All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/10] ARM: tegra: Add PCIe device tree support
@ 2012-06-11 15:05 ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-11 15:05 UTC (permalink / raw)
  To: linux-tegra-u79uwXL29TY76Z2rM5mHXA
  Cc: Jesse Barnes, linux-pci-u79uwXL29TY76Z2rM5mHXA, Grant Likely,
	Rob Herring, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	Russell King, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Colin Cross, Olof Johansson, Stephen Warren

This patch series adds support for device tree based probing of the PCIe
controller found on Tegra SoCs.

Patches 1 and 2 keep the pci_fixup_irqs() and ARM-specific pci_common_init()
functions around after init. This is required to support driver probe
deferral, which may cause built-in drivers to be probed after __init data has
already been freed.

Patch 3 allows a driver's probe function to pass per-controller private data
when calling the pci_common_init() function.

Patch 4 is trivial and has already been Acked-by: Stephen Warren before.

Patch 5 rewrites PCIe support as a driver and switches the Harmony and
TrimSlice boards to add the proper platform device instead of calling the
tegra_pcie_init() function. Patch 6 adds MSI support as an IRQ domain.

Patch 7 finally implements device tree support and patches 8, 9 and 10 move
the Harmony and TrimSlice boards over to use information provided in the DTS
to probe the PCIe controller.

Thierry

Thierry Reding (10):
  PCI: Keep pci_fixup_irqs() around after init
  ARM: pci: Keep pci_common_init() around after init
  ARM: pci: Allow passing per-controller private data
  ARM: tegra: Move tegra_pcie_xclk_clamp() to PMC
  ARM: tegra: Rewrite PCIe support as a driver
  ARM: tegra: pcie: Add MSI support
  ARM: tegra: pcie: Add device tree support
  ARM: tegra: harmony: Initialize regulators from DT
  ARM: tegra: harmony: Initialize PCIe from DT
  ARM: tegra: trimslice: Initialize PCIe from DT

 .../devicetree/bindings/pci/tegra-pcie.txt         |   23 +
 arch/arm/boot/dts/tegra-harmony.dts                |   98 +++
 arch/arm/boot/dts/tegra-trimslice.dts              |   20 +
 arch/arm/boot/dts/tegra20.dtsi                     |    9 +
 arch/arm/include/asm/mach/pci.h                    |    1 +
 arch/arm/kernel/bios32.c                           |    7 +-
 arch/arm/mach-tegra/Kconfig                        |    1 +
 arch/arm/mach-tegra/board-dt-tegra20.c             |   35 +-
 arch/arm/mach-tegra/board-harmony-pcie.c           |   38 +-
 arch/arm/mach-tegra/board-harmony.c                |    1 +
 arch/arm/mach-tegra/board-harmony.h                |    1 +
 arch/arm/mach-tegra/board-trimslice.c              |   18 +-
 arch/arm/mach-tegra/board.h                        |    2 +-
 arch/arm/mach-tegra/devices.c                      |   32 +
 arch/arm/mach-tegra/devices.h                      |    1 +
 arch/arm/mach-tegra/include/mach/iomap.h           |    6 +
 arch/arm/mach-tegra/include/mach/irqs.h            |    5 +-
 arch/arm/mach-tegra/include/mach/pci-tegra.h       |   29 +
 arch/arm/mach-tegra/pcie.c                         |  926 +++++++++++++++-----
 arch/arm/mach-tegra/pmc.c                          |   16 +
 arch/arm/mach-tegra/pmc.h                          |    1 +
 drivers/pci/setup-irq.c                            |    4 +-
 22 files changed, 983 insertions(+), 291 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pci/tegra-pcie.txt
 create mode 100644 arch/arm/mach-tegra/include/mach/pci-tegra.h

-- 
1.7.10.4

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

* [PATCH v2 00/10] ARM: tegra: Add PCIe device tree support
@ 2012-06-11 15:05 ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-11 15:05 UTC (permalink / raw)
  To: linux-tegra
  Cc: Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson, Stephen Warren

This patch series adds support for device tree based probing of the PCIe
controller found on Tegra SoCs.

Patches 1 and 2 keep the pci_fixup_irqs() and ARM-specific pci_common_init()
functions around after init. This is required to support driver probe
deferral, which may cause built-in drivers to be probed after __init data has
already been freed.

Patch 3 allows a driver's probe function to pass per-controller private data
when calling the pci_common_init() function.

Patch 4 is trivial and has already been Acked-by: Stephen Warren before.

Patch 5 rewrites PCIe support as a driver and switches the Harmony and
TrimSlice boards to add the proper platform device instead of calling the
tegra_pcie_init() function. Patch 6 adds MSI support as an IRQ domain.

Patch 7 finally implements device tree support and patches 8, 9 and 10 move
the Harmony and TrimSlice boards over to use information provided in the DTS
to probe the PCIe controller.

Thierry

Thierry Reding (10):
  PCI: Keep pci_fixup_irqs() around after init
  ARM: pci: Keep pci_common_init() around after init
  ARM: pci: Allow passing per-controller private data
  ARM: tegra: Move tegra_pcie_xclk_clamp() to PMC
  ARM: tegra: Rewrite PCIe support as a driver
  ARM: tegra: pcie: Add MSI support
  ARM: tegra: pcie: Add device tree support
  ARM: tegra: harmony: Initialize regulators from DT
  ARM: tegra: harmony: Initialize PCIe from DT
  ARM: tegra: trimslice: Initialize PCIe from DT

 .../devicetree/bindings/pci/tegra-pcie.txt         |   23 +
 arch/arm/boot/dts/tegra-harmony.dts                |   98 +++
 arch/arm/boot/dts/tegra-trimslice.dts              |   20 +
 arch/arm/boot/dts/tegra20.dtsi                     |    9 +
 arch/arm/include/asm/mach/pci.h                    |    1 +
 arch/arm/kernel/bios32.c                           |    7 +-
 arch/arm/mach-tegra/Kconfig                        |    1 +
 arch/arm/mach-tegra/board-dt-tegra20.c             |   35 +-
 arch/arm/mach-tegra/board-harmony-pcie.c           |   38 +-
 arch/arm/mach-tegra/board-harmony.c                |    1 +
 arch/arm/mach-tegra/board-harmony.h                |    1 +
 arch/arm/mach-tegra/board-trimslice.c              |   18 +-
 arch/arm/mach-tegra/board.h                        |    2 +-
 arch/arm/mach-tegra/devices.c                      |   32 +
 arch/arm/mach-tegra/devices.h                      |    1 +
 arch/arm/mach-tegra/include/mach/iomap.h           |    6 +
 arch/arm/mach-tegra/include/mach/irqs.h            |    5 +-
 arch/arm/mach-tegra/include/mach/pci-tegra.h       |   29 +
 arch/arm/mach-tegra/pcie.c                         |  926 +++++++++++++++-----
 arch/arm/mach-tegra/pmc.c                          |   16 +
 arch/arm/mach-tegra/pmc.h                          |    1 +
 drivers/pci/setup-irq.c                            |    4 +-
 22 files changed, 983 insertions(+), 291 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pci/tegra-pcie.txt
 create mode 100644 arch/arm/mach-tegra/include/mach/pci-tegra.h

-- 
1.7.10.4


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

* [PATCH v2 00/10] ARM: tegra: Add PCIe device tree support
@ 2012-06-11 15:05 ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-11 15:05 UTC (permalink / raw)
  To: linux-arm-kernel

This patch series adds support for device tree based probing of the PCIe
controller found on Tegra SoCs.

Patches 1 and 2 keep the pci_fixup_irqs() and ARM-specific pci_common_init()
functions around after init. This is required to support driver probe
deferral, which may cause built-in drivers to be probed after __init data has
already been freed.

Patch 3 allows a driver's probe function to pass per-controller private data
when calling the pci_common_init() function.

Patch 4 is trivial and has already been Acked-by: Stephen Warren before.

Patch 5 rewrites PCIe support as a driver and switches the Harmony and
TrimSlice boards to add the proper platform device instead of calling the
tegra_pcie_init() function. Patch 6 adds MSI support as an IRQ domain.

Patch 7 finally implements device tree support and patches 8, 9 and 10 move
the Harmony and TrimSlice boards over to use information provided in the DTS
to probe the PCIe controller.

Thierry

Thierry Reding (10):
  PCI: Keep pci_fixup_irqs() around after init
  ARM: pci: Keep pci_common_init() around after init
  ARM: pci: Allow passing per-controller private data
  ARM: tegra: Move tegra_pcie_xclk_clamp() to PMC
  ARM: tegra: Rewrite PCIe support as a driver
  ARM: tegra: pcie: Add MSI support
  ARM: tegra: pcie: Add device tree support
  ARM: tegra: harmony: Initialize regulators from DT
  ARM: tegra: harmony: Initialize PCIe from DT
  ARM: tegra: trimslice: Initialize PCIe from DT

 .../devicetree/bindings/pci/tegra-pcie.txt         |   23 +
 arch/arm/boot/dts/tegra-harmony.dts                |   98 +++
 arch/arm/boot/dts/tegra-trimslice.dts              |   20 +
 arch/arm/boot/dts/tegra20.dtsi                     |    9 +
 arch/arm/include/asm/mach/pci.h                    |    1 +
 arch/arm/kernel/bios32.c                           |    7 +-
 arch/arm/mach-tegra/Kconfig                        |    1 +
 arch/arm/mach-tegra/board-dt-tegra20.c             |   35 +-
 arch/arm/mach-tegra/board-harmony-pcie.c           |   38 +-
 arch/arm/mach-tegra/board-harmony.c                |    1 +
 arch/arm/mach-tegra/board-harmony.h                |    1 +
 arch/arm/mach-tegra/board-trimslice.c              |   18 +-
 arch/arm/mach-tegra/board.h                        |    2 +-
 arch/arm/mach-tegra/devices.c                      |   32 +
 arch/arm/mach-tegra/devices.h                      |    1 +
 arch/arm/mach-tegra/include/mach/iomap.h           |    6 +
 arch/arm/mach-tegra/include/mach/irqs.h            |    5 +-
 arch/arm/mach-tegra/include/mach/pci-tegra.h       |   29 +
 arch/arm/mach-tegra/pcie.c                         |  926 +++++++++++++++-----
 arch/arm/mach-tegra/pmc.c                          |   16 +
 arch/arm/mach-tegra/pmc.h                          |    1 +
 drivers/pci/setup-irq.c                            |    4 +-
 22 files changed, 983 insertions(+), 291 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pci/tegra-pcie.txt
 create mode 100644 arch/arm/mach-tegra/include/mach/pci-tegra.h

-- 
1.7.10.4

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

* [PATCH v2 01/10] PCI: Keep pci_fixup_irqs() around after init
  2012-06-11 15:05 ` Thierry Reding
  (?)
@ 2012-06-11 15:05     ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-11 15:05 UTC (permalink / raw)
  To: linux-tegra-u79uwXL29TY76Z2rM5mHXA
  Cc: Russell King, linux-pci-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Jesse Barnes, Colin Cross,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

Signed-off-by: Thierry Reding <thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
---
Changes in v2:
- use __devinit annotations

 drivers/pci/setup-irq.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/setup-irq.c b/drivers/pci/setup-irq.c
index eb219a1..f0bcd56 100644
--- a/drivers/pci/setup-irq.c
+++ b/drivers/pci/setup-irq.c
@@ -18,7 +18,7 @@
 #include <linux/cache.h>
 
 
-static void __init
+static void __devinit
 pdev_fixup_irq(struct pci_dev *dev,
 	       u8 (*swizzle)(struct pci_dev *, u8 *),
 	       int (*map_irq)(const struct pci_dev *, u8, u8))
@@ -54,7 +54,7 @@ pdev_fixup_irq(struct pci_dev *dev,
 	pcibios_update_irq(dev, irq);
 }
 
-void __init
+void __devinit
 pci_fixup_irqs(u8 (*swizzle)(struct pci_dev *, u8 *),
 	       int (*map_irq)(const struct pci_dev *, u8, u8))
 {
-- 
1.7.10.4

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

* [PATCH v2 01/10] PCI: Keep pci_fixup_irqs() around after init
@ 2012-06-11 15:05     ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-11 15:05 UTC (permalink / raw)
  To: linux-tegra
  Cc: Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson, Stephen Warren

Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
---
Changes in v2:
- use __devinit annotations

 drivers/pci/setup-irq.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/setup-irq.c b/drivers/pci/setup-irq.c
index eb219a1..f0bcd56 100644
--- a/drivers/pci/setup-irq.c
+++ b/drivers/pci/setup-irq.c
@@ -18,7 +18,7 @@
 #include <linux/cache.h>
 
 
-static void __init
+static void __devinit
 pdev_fixup_irq(struct pci_dev *dev,
 	       u8 (*swizzle)(struct pci_dev *, u8 *),
 	       int (*map_irq)(const struct pci_dev *, u8, u8))
@@ -54,7 +54,7 @@ pdev_fixup_irq(struct pci_dev *dev,
 	pcibios_update_irq(dev, irq);
 }
 
-void __init
+void __devinit
 pci_fixup_irqs(u8 (*swizzle)(struct pci_dev *, u8 *),
 	       int (*map_irq)(const struct pci_dev *, u8, u8))
 {
-- 
1.7.10.4


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

* [PATCH v2 01/10] PCI: Keep pci_fixup_irqs() around after init
@ 2012-06-11 15:05     ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-11 15:05 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
---
Changes in v2:
- use __devinit annotations

 drivers/pci/setup-irq.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/setup-irq.c b/drivers/pci/setup-irq.c
index eb219a1..f0bcd56 100644
--- a/drivers/pci/setup-irq.c
+++ b/drivers/pci/setup-irq.c
@@ -18,7 +18,7 @@
 #include <linux/cache.h>
 
 
-static void __init
+static void __devinit
 pdev_fixup_irq(struct pci_dev *dev,
 	       u8 (*swizzle)(struct pci_dev *, u8 *),
 	       int (*map_irq)(const struct pci_dev *, u8, u8))
@@ -54,7 +54,7 @@ pdev_fixup_irq(struct pci_dev *dev,
 	pcibios_update_irq(dev, irq);
 }
 
-void __init
+void __devinit
 pci_fixup_irqs(u8 (*swizzle)(struct pci_dev *, u8 *),
 	       int (*map_irq)(const struct pci_dev *, u8, u8))
 {
-- 
1.7.10.4

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

* [PATCH v2 02/10] ARM: pci: Keep pci_common_init() around after init
  2012-06-11 15:05 ` Thierry Reding
  (?)
@ 2012-06-11 15:05     ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-11 15:05 UTC (permalink / raw)
  To: linux-tegra-u79uwXL29TY76Z2rM5mHXA
  Cc: Jesse Barnes, linux-pci-u79uwXL29TY76Z2rM5mHXA, Grant Likely,
	Rob Herring, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	Russell King, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Colin Cross, Olof Johansson, Stephen Warren

Signed-off-by: Thierry Reding <thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>

---
Changes in v2:
- use __devinit annotations
---
 arch/arm/kernel/bios32.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index 2555250..c9d28dd 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -423,7 +423,7 @@ static int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 	return irq;
 }
 
-static void __init pcibios_init_hw(struct hw_pci *hw, struct list_head *head)
+static void __devinit pcibios_init_hw(struct hw_pci *hw, struct list_head *head)
 {
 	struct pci_sys_data *sys = NULL;
 	int ret;
@@ -472,7 +472,7 @@ static void __init pcibios_init_hw(struct hw_pci *hw, struct list_head *head)
 	}
 }
 
-void __init pci_common_init(struct hw_pci *hw)
+void __devinit pci_common_init(struct hw_pci *hw)
 {
 	struct pci_sys_data *sys;
 	LIST_HEAD(head);
-- 
1.7.10.4

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

* [PATCH v2 02/10] ARM: pci: Keep pci_common_init() around after init
@ 2012-06-11 15:05     ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-11 15:05 UTC (permalink / raw)
  To: linux-tegra
  Cc: Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson, Stephen Warren

Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>

---
Changes in v2:
- use __devinit annotations
---
 arch/arm/kernel/bios32.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index 2555250..c9d28dd 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -423,7 +423,7 @@ static int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 	return irq;
 }
 
-static void __init pcibios_init_hw(struct hw_pci *hw, struct list_head *head)
+static void __devinit pcibios_init_hw(struct hw_pci *hw, struct list_head *head)
 {
 	struct pci_sys_data *sys = NULL;
 	int ret;
@@ -472,7 +472,7 @@ static void __init pcibios_init_hw(struct hw_pci *hw, struct list_head *head)
 	}
 }
 
-void __init pci_common_init(struct hw_pci *hw)
+void __devinit pci_common_init(struct hw_pci *hw)
 {
 	struct pci_sys_data *sys;
 	LIST_HEAD(head);
-- 
1.7.10.4


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

* [PATCH v2 02/10] ARM: pci: Keep pci_common_init() around after init
@ 2012-06-11 15:05     ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-11 15:05 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>

---
Changes in v2:
- use __devinit annotations
---
 arch/arm/kernel/bios32.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index 2555250..c9d28dd 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -423,7 +423,7 @@ static int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 	return irq;
 }
 
-static void __init pcibios_init_hw(struct hw_pci *hw, struct list_head *head)
+static void __devinit pcibios_init_hw(struct hw_pci *hw, struct list_head *head)
 {
 	struct pci_sys_data *sys = NULL;
 	int ret;
@@ -472,7 +472,7 @@ static void __init pcibios_init_hw(struct hw_pci *hw, struct list_head *head)
 	}
 }
 
-void __init pci_common_init(struct hw_pci *hw)
+void __devinit pci_common_init(struct hw_pci *hw)
 {
 	struct pci_sys_data *sys;
 	LIST_HEAD(head);
-- 
1.7.10.4

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

* [PATCH v2 03/10] ARM: pci: Allow passing per-controller private data
  2012-06-11 15:05 ` Thierry Reding
  (?)
@ 2012-06-11 15:05     ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-11 15:05 UTC (permalink / raw)
  To: linux-tegra-u79uwXL29TY76Z2rM5mHXA
  Cc: Jesse Barnes, linux-pci-u79uwXL29TY76Z2rM5mHXA, Grant Likely,
	Rob Herring, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	Russell King, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Colin Cross, Olof Johansson, Stephen Warren

In order to allow drivers to specify private data for each controller,
this commit adds a private_data field to the struct hw_pci. This field
is an array of nr_controllers pointers that will be used to initialize
the private_data field of the corresponding controller's pci_sys_data
structure.

Signed-off-by: Thierry Reding <thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>

---
Changes in v2:
- new patch
---
 arch/arm/include/asm/mach/pci.h |    1 +
 arch/arm/kernel/bios32.c        |    3 +++
 2 files changed, 4 insertions(+)

diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h
index 26c511f..736cb8d 100644
--- a/arch/arm/include/asm/mach/pci.h
+++ b/arch/arm/include/asm/mach/pci.h
@@ -21,6 +21,7 @@ struct hw_pci {
 #endif
 	struct pci_ops	*ops;
 	int		nr_controllers;
+	void		**private_data;
 	int		(*setup)(int nr, struct pci_sys_data *);
 	struct pci_bus *(*scan)(int nr, struct pci_sys_data *);
 	void		(*preinit)(void);
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index c9d28dd..04858c6 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -442,6 +442,9 @@ static void __devinit pcibios_init_hw(struct hw_pci *hw, struct list_head *head)
 		sys->map_irq = hw->map_irq;
 		INIT_LIST_HEAD(&sys->resources);
 
+		if (hw->private_data)
+			sys->private_data = hw->private_data[nr];
+
 		ret = hw->setup(nr, sys);
 
 		if (ret > 0) {
-- 
1.7.10.4

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

* [PATCH v2 03/10] ARM: pci: Allow passing per-controller private data
@ 2012-06-11 15:05     ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-11 15:05 UTC (permalink / raw)
  To: linux-tegra
  Cc: Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson, Stephen Warren

In order to allow drivers to specify private data for each controller,
this commit adds a private_data field to the struct hw_pci. This field
is an array of nr_controllers pointers that will be used to initialize
the private_data field of the corresponding controller's pci_sys_data
structure.

Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>

---
Changes in v2:
- new patch
---
 arch/arm/include/asm/mach/pci.h |    1 +
 arch/arm/kernel/bios32.c        |    3 +++
 2 files changed, 4 insertions(+)

diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h
index 26c511f..736cb8d 100644
--- a/arch/arm/include/asm/mach/pci.h
+++ b/arch/arm/include/asm/mach/pci.h
@@ -21,6 +21,7 @@ struct hw_pci {
 #endif
 	struct pci_ops	*ops;
 	int		nr_controllers;
+	void		**private_data;
 	int		(*setup)(int nr, struct pci_sys_data *);
 	struct pci_bus *(*scan)(int nr, struct pci_sys_data *);
 	void		(*preinit)(void);
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index c9d28dd..04858c6 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -442,6 +442,9 @@ static void __devinit pcibios_init_hw(struct hw_pci *hw, struct list_head *head)
 		sys->map_irq = hw->map_irq;
 		INIT_LIST_HEAD(&sys->resources);
 
+		if (hw->private_data)
+			sys->private_data = hw->private_data[nr];
+
 		ret = hw->setup(nr, sys);
 
 		if (ret > 0) {
-- 
1.7.10.4


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

* [PATCH v2 03/10] ARM: pci: Allow passing per-controller private data
@ 2012-06-11 15:05     ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-11 15:05 UTC (permalink / raw)
  To: linux-arm-kernel

In order to allow drivers to specify private data for each controller,
this commit adds a private_data field to the struct hw_pci. This field
is an array of nr_controllers pointers that will be used to initialize
the private_data field of the corresponding controller's pci_sys_data
structure.

Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>

---
Changes in v2:
- new patch
---
 arch/arm/include/asm/mach/pci.h |    1 +
 arch/arm/kernel/bios32.c        |    3 +++
 2 files changed, 4 insertions(+)

diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h
index 26c511f..736cb8d 100644
--- a/arch/arm/include/asm/mach/pci.h
+++ b/arch/arm/include/asm/mach/pci.h
@@ -21,6 +21,7 @@ struct hw_pci {
 #endif
 	struct pci_ops	*ops;
 	int		nr_controllers;
+	void		**private_data;
 	int		(*setup)(int nr, struct pci_sys_data *);
 	struct pci_bus *(*scan)(int nr, struct pci_sys_data *);
 	void		(*preinit)(void);
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index c9d28dd..04858c6 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -442,6 +442,9 @@ static void __devinit pcibios_init_hw(struct hw_pci *hw, struct list_head *head)
 		sys->map_irq = hw->map_irq;
 		INIT_LIST_HEAD(&sys->resources);
 
+		if (hw->private_data)
+			sys->private_data = hw->private_data[nr];
+
 		ret = hw->setup(nr, sys);
 
 		if (ret > 0) {
-- 
1.7.10.4

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

* [PATCH v2 04/10] ARM: tegra: Move tegra_pcie_xclk_clamp() to PMC
  2012-06-11 15:05 ` Thierry Reding
  (?)
@ 2012-06-11 15:05     ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-11 15:05 UTC (permalink / raw)
  To: linux-tegra-u79uwXL29TY76Z2rM5mHXA
  Cc: Jesse Barnes, linux-pci-u79uwXL29TY76Z2rM5mHXA, Grant Likely,
	Rob Herring, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	Russell King, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Colin Cross, Olof Johansson, Stephen Warren

The PMC code already accesses to PMC registers so it makes sense to
move this function there as well. While at it, rename the function to
tegra_pmc_pcie_xclk_clamp() for consistency.

Signed-off-by: Thierry Reding <thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
Acked-by: Stephen Warren <swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>

---
Changes in v2:
- none
---
 arch/arm/mach-tegra/pcie.c |   30 ++++--------------------------
 arch/arm/mach-tegra/pmc.c  |   16 ++++++++++++++++
 arch/arm/mach-tegra/pmc.h  |    1 +
 3 files changed, 21 insertions(+), 26 deletions(-)

diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c
index 0e09137..fcdf8bc 100644
--- a/arch/arm/mach-tegra/pcie.c
+++ b/arch/arm/mach-tegra/pcie.c
@@ -42,6 +42,7 @@
 #include <mach/powergate.h>
 
 #include "board.h"
+#include "pmc.h"
 
 /* register definitions */
 #define AFI_OFFSET	0x3800
@@ -145,17 +146,6 @@
 #define  PADS_PLL_CTL_TXCLKREF_DIV10		(0 << 20)
 #define  PADS_PLL_CTL_TXCLKREF_DIV5		(1 << 20)
 
-/* PMC access is required for PCIE xclk (un)clamping */
-#define PMC_SCRATCH42		0x144
-#define PMC_SCRATCH42_PCX_CLAMP	(1 << 0)
-
-static void __iomem *reg_pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
-
-#define pmc_writel(value, reg) \
-	__raw_writel(value, reg_pmc_base + (reg))
-#define pmc_readl(reg) \
-	__raw_readl(reg_pmc_base + (reg))
-
 /*
  * Tegra2 defines 1GB in the AXI address map for PCIe.
  *
@@ -679,18 +669,6 @@ static int tegra_pcie_enable_controller(void)
 	return 0;
 }
 
-static void tegra_pcie_xclk_clamp(bool clamp)
-{
-	u32 reg;
-
-	reg = pmc_readl(PMC_SCRATCH42) & ~PMC_SCRATCH42_PCX_CLAMP;
-
-	if (clamp)
-		reg |= PMC_SCRATCH42_PCX_CLAMP;
-
-	pmc_writel(reg, PMC_SCRATCH42);
-}
-
 static void tegra_pcie_power_off(void)
 {
 	tegra_periph_reset_assert(tegra_pcie.pcie_xclk);
@@ -698,7 +676,7 @@ static void tegra_pcie_power_off(void)
 	tegra_periph_reset_assert(tegra_pcie.pex_clk);
 
 	tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
-	tegra_pcie_xclk_clamp(true);
+	tegra_pmc_pcie_xclk_clamp(true);
 }
 
 static int tegra_pcie_power_regate(void)
@@ -707,7 +685,7 @@ static int tegra_pcie_power_regate(void)
 
 	tegra_pcie_power_off();
 
-	tegra_pcie_xclk_clamp(true);
+	tegra_pmc_pcie_xclk_clamp(true);
 
 	tegra_periph_reset_assert(tegra_pcie.pcie_xclk);
 	tegra_periph_reset_assert(tegra_pcie.afi_clk);
@@ -721,7 +699,7 @@ static int tegra_pcie_power_regate(void)
 
 	tegra_periph_reset_deassert(tegra_pcie.afi_clk);
 
-	tegra_pcie_xclk_clamp(false);
+	tegra_pmc_pcie_xclk_clamp(false);
 
 	clk_enable(tegra_pcie.afi_clk);
 	clk_enable(tegra_pcie.pex_clk);
diff --git a/arch/arm/mach-tegra/pmc.c b/arch/arm/mach-tegra/pmc.c
index 7af6a54..399dc3a 100644
--- a/arch/arm/mach-tegra/pmc.c
+++ b/arch/arm/mach-tegra/pmc.c
@@ -24,6 +24,10 @@
 #define PMC_CTRL		0x0
 #define PMC_CTRL_INTR_LOW	(1 << 17)
 
+/* PMC access is required for PCIE xclk (un)clamping */
+#define PMC_SCRATCH42		0x144
+#define PMC_SCRATCH42_PCX_CLAMP	(1 << 0)
+
 static inline u32 tegra_pmc_readl(u32 reg)
 {
 	return readl(IO_ADDRESS(TEGRA_PMC_BASE + reg));
@@ -74,3 +78,15 @@ void __init tegra_pmc_init(void)
 		val &= ~PMC_CTRL_INTR_LOW;
 	tegra_pmc_writel(val, PMC_CTRL);
 }
+
+void tegra_pmc_pcie_xclk_clamp(bool clamp)
+{
+	u32 reg;
+
+	reg = tegra_pmc_readl(PMC_SCRATCH42) & ~PMC_SCRATCH42_PCX_CLAMP;
+
+	if (clamp)
+		reg |= PMC_SCRATCH42_PCX_CLAMP;
+
+	tegra_pmc_writel(reg, PMC_SCRATCH42);
+}
diff --git a/arch/arm/mach-tegra/pmc.h b/arch/arm/mach-tegra/pmc.h
index 8995ee4..2631c9a 100644
--- a/arch/arm/mach-tegra/pmc.h
+++ b/arch/arm/mach-tegra/pmc.h
@@ -19,5 +19,6 @@
 #define __MACH_TEGRA_PMC_H
 
 void tegra_pmc_init(void);
+void tegra_pmc_pcie_xclk_clamp(bool clamp);
 
 #endif
-- 
1.7.10.4

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

* [PATCH v2 04/10] ARM: tegra: Move tegra_pcie_xclk_clamp() to PMC
@ 2012-06-11 15:05     ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-11 15:05 UTC (permalink / raw)
  To: linux-tegra
  Cc: Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson, Stephen Warren

The PMC code already accesses to PMC registers so it makes sense to
move this function there as well. While at it, rename the function to
tegra_pmc_pcie_xclk_clamp() for consistency.

Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
Acked-by: Stephen Warren <swarren@wwwdotorg.org>

---
Changes in v2:
- none
---
 arch/arm/mach-tegra/pcie.c |   30 ++++--------------------------
 arch/arm/mach-tegra/pmc.c  |   16 ++++++++++++++++
 arch/arm/mach-tegra/pmc.h  |    1 +
 3 files changed, 21 insertions(+), 26 deletions(-)

diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c
index 0e09137..fcdf8bc 100644
--- a/arch/arm/mach-tegra/pcie.c
+++ b/arch/arm/mach-tegra/pcie.c
@@ -42,6 +42,7 @@
 #include <mach/powergate.h>
 
 #include "board.h"
+#include "pmc.h"
 
 /* register definitions */
 #define AFI_OFFSET	0x3800
@@ -145,17 +146,6 @@
 #define  PADS_PLL_CTL_TXCLKREF_DIV10		(0 << 20)
 #define  PADS_PLL_CTL_TXCLKREF_DIV5		(1 << 20)
 
-/* PMC access is required for PCIE xclk (un)clamping */
-#define PMC_SCRATCH42		0x144
-#define PMC_SCRATCH42_PCX_CLAMP	(1 << 0)
-
-static void __iomem *reg_pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
-
-#define pmc_writel(value, reg) \
-	__raw_writel(value, reg_pmc_base + (reg))
-#define pmc_readl(reg) \
-	__raw_readl(reg_pmc_base + (reg))
-
 /*
  * Tegra2 defines 1GB in the AXI address map for PCIe.
  *
@@ -679,18 +669,6 @@ static int tegra_pcie_enable_controller(void)
 	return 0;
 }
 
-static void tegra_pcie_xclk_clamp(bool clamp)
-{
-	u32 reg;
-
-	reg = pmc_readl(PMC_SCRATCH42) & ~PMC_SCRATCH42_PCX_CLAMP;
-
-	if (clamp)
-		reg |= PMC_SCRATCH42_PCX_CLAMP;
-
-	pmc_writel(reg, PMC_SCRATCH42);
-}
-
 static void tegra_pcie_power_off(void)
 {
 	tegra_periph_reset_assert(tegra_pcie.pcie_xclk);
@@ -698,7 +676,7 @@ static void tegra_pcie_power_off(void)
 	tegra_periph_reset_assert(tegra_pcie.pex_clk);
 
 	tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
-	tegra_pcie_xclk_clamp(true);
+	tegra_pmc_pcie_xclk_clamp(true);
 }
 
 static int tegra_pcie_power_regate(void)
@@ -707,7 +685,7 @@ static int tegra_pcie_power_regate(void)
 
 	tegra_pcie_power_off();
 
-	tegra_pcie_xclk_clamp(true);
+	tegra_pmc_pcie_xclk_clamp(true);
 
 	tegra_periph_reset_assert(tegra_pcie.pcie_xclk);
 	tegra_periph_reset_assert(tegra_pcie.afi_clk);
@@ -721,7 +699,7 @@ static int tegra_pcie_power_regate(void)
 
 	tegra_periph_reset_deassert(tegra_pcie.afi_clk);
 
-	tegra_pcie_xclk_clamp(false);
+	tegra_pmc_pcie_xclk_clamp(false);
 
 	clk_enable(tegra_pcie.afi_clk);
 	clk_enable(tegra_pcie.pex_clk);
diff --git a/arch/arm/mach-tegra/pmc.c b/arch/arm/mach-tegra/pmc.c
index 7af6a54..399dc3a 100644
--- a/arch/arm/mach-tegra/pmc.c
+++ b/arch/arm/mach-tegra/pmc.c
@@ -24,6 +24,10 @@
 #define PMC_CTRL		0x0
 #define PMC_CTRL_INTR_LOW	(1 << 17)
 
+/* PMC access is required for PCIE xclk (un)clamping */
+#define PMC_SCRATCH42		0x144
+#define PMC_SCRATCH42_PCX_CLAMP	(1 << 0)
+
 static inline u32 tegra_pmc_readl(u32 reg)
 {
 	return readl(IO_ADDRESS(TEGRA_PMC_BASE + reg));
@@ -74,3 +78,15 @@ void __init tegra_pmc_init(void)
 		val &= ~PMC_CTRL_INTR_LOW;
 	tegra_pmc_writel(val, PMC_CTRL);
 }
+
+void tegra_pmc_pcie_xclk_clamp(bool clamp)
+{
+	u32 reg;
+
+	reg = tegra_pmc_readl(PMC_SCRATCH42) & ~PMC_SCRATCH42_PCX_CLAMP;
+
+	if (clamp)
+		reg |= PMC_SCRATCH42_PCX_CLAMP;
+
+	tegra_pmc_writel(reg, PMC_SCRATCH42);
+}
diff --git a/arch/arm/mach-tegra/pmc.h b/arch/arm/mach-tegra/pmc.h
index 8995ee4..2631c9a 100644
--- a/arch/arm/mach-tegra/pmc.h
+++ b/arch/arm/mach-tegra/pmc.h
@@ -19,5 +19,6 @@
 #define __MACH_TEGRA_PMC_H
 
 void tegra_pmc_init(void);
+void tegra_pmc_pcie_xclk_clamp(bool clamp);
 
 #endif
-- 
1.7.10.4


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

* [PATCH v2 04/10] ARM: tegra: Move tegra_pcie_xclk_clamp() to PMC
@ 2012-06-11 15:05     ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-11 15:05 UTC (permalink / raw)
  To: linux-arm-kernel

The PMC code already accesses to PMC registers so it makes sense to
move this function there as well. While at it, rename the function to
tegra_pmc_pcie_xclk_clamp() for consistency.

Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
Acked-by: Stephen Warren <swarren@wwwdotorg.org>

---
Changes in v2:
- none
---
 arch/arm/mach-tegra/pcie.c |   30 ++++--------------------------
 arch/arm/mach-tegra/pmc.c  |   16 ++++++++++++++++
 arch/arm/mach-tegra/pmc.h  |    1 +
 3 files changed, 21 insertions(+), 26 deletions(-)

diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c
index 0e09137..fcdf8bc 100644
--- a/arch/arm/mach-tegra/pcie.c
+++ b/arch/arm/mach-tegra/pcie.c
@@ -42,6 +42,7 @@
 #include <mach/powergate.h>
 
 #include "board.h"
+#include "pmc.h"
 
 /* register definitions */
 #define AFI_OFFSET	0x3800
@@ -145,17 +146,6 @@
 #define  PADS_PLL_CTL_TXCLKREF_DIV10		(0 << 20)
 #define  PADS_PLL_CTL_TXCLKREF_DIV5		(1 << 20)
 
-/* PMC access is required for PCIE xclk (un)clamping */
-#define PMC_SCRATCH42		0x144
-#define PMC_SCRATCH42_PCX_CLAMP	(1 << 0)
-
-static void __iomem *reg_pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
-
-#define pmc_writel(value, reg) \
-	__raw_writel(value, reg_pmc_base + (reg))
-#define pmc_readl(reg) \
-	__raw_readl(reg_pmc_base + (reg))
-
 /*
  * Tegra2 defines 1GB in the AXI address map for PCIe.
  *
@@ -679,18 +669,6 @@ static int tegra_pcie_enable_controller(void)
 	return 0;
 }
 
-static void tegra_pcie_xclk_clamp(bool clamp)
-{
-	u32 reg;
-
-	reg = pmc_readl(PMC_SCRATCH42) & ~PMC_SCRATCH42_PCX_CLAMP;
-
-	if (clamp)
-		reg |= PMC_SCRATCH42_PCX_CLAMP;
-
-	pmc_writel(reg, PMC_SCRATCH42);
-}
-
 static void tegra_pcie_power_off(void)
 {
 	tegra_periph_reset_assert(tegra_pcie.pcie_xclk);
@@ -698,7 +676,7 @@ static void tegra_pcie_power_off(void)
 	tegra_periph_reset_assert(tegra_pcie.pex_clk);
 
 	tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
-	tegra_pcie_xclk_clamp(true);
+	tegra_pmc_pcie_xclk_clamp(true);
 }
 
 static int tegra_pcie_power_regate(void)
@@ -707,7 +685,7 @@ static int tegra_pcie_power_regate(void)
 
 	tegra_pcie_power_off();
 
-	tegra_pcie_xclk_clamp(true);
+	tegra_pmc_pcie_xclk_clamp(true);
 
 	tegra_periph_reset_assert(tegra_pcie.pcie_xclk);
 	tegra_periph_reset_assert(tegra_pcie.afi_clk);
@@ -721,7 +699,7 @@ static int tegra_pcie_power_regate(void)
 
 	tegra_periph_reset_deassert(tegra_pcie.afi_clk);
 
-	tegra_pcie_xclk_clamp(false);
+	tegra_pmc_pcie_xclk_clamp(false);
 
 	clk_enable(tegra_pcie.afi_clk);
 	clk_enable(tegra_pcie.pex_clk);
diff --git a/arch/arm/mach-tegra/pmc.c b/arch/arm/mach-tegra/pmc.c
index 7af6a54..399dc3a 100644
--- a/arch/arm/mach-tegra/pmc.c
+++ b/arch/arm/mach-tegra/pmc.c
@@ -24,6 +24,10 @@
 #define PMC_CTRL		0x0
 #define PMC_CTRL_INTR_LOW	(1 << 17)
 
+/* PMC access is required for PCIE xclk (un)clamping */
+#define PMC_SCRATCH42		0x144
+#define PMC_SCRATCH42_PCX_CLAMP	(1 << 0)
+
 static inline u32 tegra_pmc_readl(u32 reg)
 {
 	return readl(IO_ADDRESS(TEGRA_PMC_BASE + reg));
@@ -74,3 +78,15 @@ void __init tegra_pmc_init(void)
 		val &= ~PMC_CTRL_INTR_LOW;
 	tegra_pmc_writel(val, PMC_CTRL);
 }
+
+void tegra_pmc_pcie_xclk_clamp(bool clamp)
+{
+	u32 reg;
+
+	reg = tegra_pmc_readl(PMC_SCRATCH42) & ~PMC_SCRATCH42_PCX_CLAMP;
+
+	if (clamp)
+		reg |= PMC_SCRATCH42_PCX_CLAMP;
+
+	tegra_pmc_writel(reg, PMC_SCRATCH42);
+}
diff --git a/arch/arm/mach-tegra/pmc.h b/arch/arm/mach-tegra/pmc.h
index 8995ee4..2631c9a 100644
--- a/arch/arm/mach-tegra/pmc.h
+++ b/arch/arm/mach-tegra/pmc.h
@@ -19,5 +19,6 @@
 #define __MACH_TEGRA_PMC_H
 
 void tegra_pmc_init(void);
+void tegra_pmc_pcie_xclk_clamp(bool clamp);
 
 #endif
-- 
1.7.10.4

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

* [PATCH v2 05/10] ARM: tegra: Rewrite PCIe support as a driver
  2012-06-11 15:05 ` Thierry Reding
@ 2012-06-11 15:05   ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-11 15:05 UTC (permalink / raw)
  To: linux-tegra
  Cc: Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson, Stephen Warren

This commit adds a platform device driver for the PCIe controller on
Tegra SOCs. Current users of the old code (TrimSlice and Harmony) are
converted and now initialize and register a corresponding platform
device.

Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>

---
Changes in v2:
- use struct hw_pci's new private_data field
- fix DT initialization for TrimSlice
---
 arch/arm/mach-tegra/board-dt-tegra20.c       |   15 +-
 arch/arm/mach-tegra/board-harmony-pcie.c     |   38 +-
 arch/arm/mach-tegra/board-harmony.c          |    1 +
 arch/arm/mach-tegra/board-harmony.h          |    1 +
 arch/arm/mach-tegra/board-trimslice.c        |   18 +-
 arch/arm/mach-tegra/board.h                  |    2 +-
 arch/arm/mach-tegra/devices.c                |   25 ++
 arch/arm/mach-tegra/devices.h                |    1 +
 arch/arm/mach-tegra/include/mach/iomap.h     |    6 +
 arch/arm/mach-tegra/include/mach/pci-tegra.h |   29 ++
 arch/arm/mach-tegra/pcie.c                   |  514 ++++++++++++++++----------
 11 files changed, 419 insertions(+), 231 deletions(-)
 create mode 100644 arch/arm/mach-tegra/include/mach/pci-tegra.h

diff --git a/arch/arm/mach-tegra/board-dt-tegra20.c b/arch/arm/mach-tegra/board-dt-tegra20.c
index 9c444a0..0f29c05 100644
--- a/arch/arm/mach-tegra/board-dt-tegra20.c
+++ b/arch/arm/mach-tegra/board-dt-tegra20.c
@@ -40,6 +40,7 @@
 
 #include <mach/iomap.h>
 #include <mach/irqs.h>
+#include <mach/pci-tegra.h>
 
 #include "board.h"
 #include "board-harmony.h"
@@ -116,13 +117,17 @@ static void __init tegra_dt_init(void)
 }
 
 #ifdef CONFIG_MACH_TRIMSLICE
+static struct tegra_pcie_pdata trimslice_pcie_pdata = {
+	.enable_ports = {
+		[0] = true,
+		[1] = true,
+	},
+};
+
 static void __init trimslice_init(void)
 {
-	int ret;
-
-	ret = tegra_pcie_init(true, true);
-	if (ret)
-		pr_err("tegra_pci_init() failed: %d\n", ret);
+	tegra_pcie_device.dev.platform_data = &trimslice_pcie_pdata;
+	platform_device_register(&tegra_pcie_device);
 }
 #endif
 
diff --git a/arch/arm/mach-tegra/board-harmony-pcie.c b/arch/arm/mach-tegra/board-harmony-pcie.c
index e8c3fda..8373271 100644
--- a/arch/arm/mach-tegra/board-harmony-pcie.c
+++ b/arch/arm/mach-tegra/board-harmony-pcie.c
@@ -22,12 +22,14 @@
 
 #include <asm/mach-types.h>
 
+#include <mach/pci-tegra.h>
+
 #include "board.h"
+#include "devices.h"
 #include "board-harmony.h"
 
 #ifdef CONFIG_TEGRA_PCI
-
-int __init harmony_pcie_init(void)
+static int harmony_pcie_board_init(struct platform_device *pdev)
 {
 	struct regulator *regulator = NULL;
 	int err;
@@ -44,30 +46,32 @@ int __init harmony_pcie_init(void)
 
 	regulator_enable(regulator);
 
-	err = tegra_pcie_init(true, true);
-	if (err)
-		goto err_pcie;
-
 	return 0;
 
-err_pcie:
-	regulator_disable(regulator);
-	regulator_put(regulator);
 err_reg:
 	gpio_free(TEGRA_GPIO_EN_VDD_1V05_GPIO);
 
 	return err;
 }
 
-static int __init harmony_pcie_initcall(void)
+static struct tegra_pcie_pdata harmony_pcie_pdata = {
+	.init = harmony_pcie_board_init,
+	.enable_ports = {
+		[0] = true,
+		[1] = true,
+	},
+};
+
+int __init harmony_pcie_init(void)
 {
-	if (!machine_is_harmony())
-		return 0;
+	tegra_pcie_device.dev.platform_data = &harmony_pcie_pdata;
+	platform_device_register(&tegra_pcie_device);
 
-	return harmony_pcie_init();
+	return 0;
+}
+#else
+int __init harmony_pcie_init(void)
+{
+	return 0;
 }
-
-/* PCI should be initialized after I2C, mfd and regulators */
-subsys_initcall_sync(harmony_pcie_initcall);
-
 #endif
diff --git a/arch/arm/mach-tegra/board-harmony.c b/arch/arm/mach-tegra/board-harmony.c
index e5f3352..063c7d5 100644
--- a/arch/arm/mach-tegra/board-harmony.c
+++ b/arch/arm/mach-tegra/board-harmony.c
@@ -204,6 +204,7 @@ static void __init tegra_harmony_init(void)
 	pwm_add_table(harmony_pwm_lookup, ARRAY_SIZE(harmony_pwm_lookup));
 	harmony_i2c_init();
 	harmony_regulator_init();
+	harmony_pcie_init();
 }
 
 MACHINE_START(HARMONY, "harmony")
diff --git a/arch/arm/mach-tegra/board-harmony.h b/arch/arm/mach-tegra/board-harmony.h
index 139d96c..afa68e2 100644
--- a/arch/arm/mach-tegra/board-harmony.h
+++ b/arch/arm/mach-tegra/board-harmony.h
@@ -37,5 +37,6 @@
 
 void harmony_pinmux_init(void);
 int harmony_regulator_init(void);
+int harmony_pcie_init(void);
 
 #endif
diff --git a/arch/arm/mach-tegra/board-trimslice.c b/arch/arm/mach-tegra/board-trimslice.c
index 776aa95..30246d2 100644
--- a/arch/arm/mach-tegra/board-trimslice.c
+++ b/arch/arm/mach-tegra/board-trimslice.c
@@ -34,6 +34,7 @@
 #include <asm/setup.h>
 
 #include <mach/iomap.h>
+#include <mach/pci-tegra.h>
 #include <mach/sdhci.h>
 
 #include "board.h"
@@ -145,14 +146,20 @@ static __initdata struct tegra_clk_init_table trimslice_clk_init_table[] = {
 	{ NULL,		NULL,		0,		0},
 };
 
-static int __init tegra_trimslice_pci_init(void)
+static struct tegra_pcie_pdata trimslice_pcie_pdata = {
+	.enable_ports = {
+		[0] = true,
+		[1] = true,
+	},
+};
+
+static int __init trimslice_pci_init(void)
 {
-	if (!machine_is_trimslice())
-		return 0;
+	tegra_pcie_device.dev.platform_data = &trimslice_pcie_pdata;
+	platform_device_register(&tegra_pcie_device);
 
-	return tegra_pcie_init(true, true);
+	return 0;
 }
-subsys_initcall(tegra_trimslice_pci_init);
 
 static void __init tegra_trimslice_init(void)
 {
@@ -167,6 +174,7 @@ static void __init tegra_trimslice_init(void)
 
 	trimslice_i2c_init();
 	trimslice_usb_init();
+	trimslice_pci_init();
 }
 
 MACHINE_START(TRIMSLICE, "trimslice")
diff --git a/arch/arm/mach-tegra/board.h b/arch/arm/mach-tegra/board.h
index f88e514..3a2a7e9 100644
--- a/arch/arm/mach-tegra/board.h
+++ b/arch/arm/mach-tegra/board.h
@@ -30,7 +30,6 @@ void __init tegra30_init_early(void);
 void __init tegra_map_common_io(void);
 void __init tegra_init_irq(void);
 void __init tegra_dt_init_irq(void);
-int __init tegra_pcie_init(bool init_port0, bool init_port1);
 
 void tegra_init_late(void);
 
@@ -56,4 +55,5 @@ static inline int harmony_pcie_init(void) { return 0; }
 void __init tegra_paz00_wifikill_init(void);
 
 extern struct sys_timer tegra_timer;
+
 #endif
diff --git a/arch/arm/mach-tegra/devices.c b/arch/arm/mach-tegra/devices.c
index 4529561..de4aef9 100644
--- a/arch/arm/mach-tegra/devices.c
+++ b/arch/arm/mach-tegra/devices.c
@@ -735,3 +735,28 @@ struct platform_device tegra_nand_device = {
 	.num_resources = ARRAY_SIZE(tegra_nand_resources),
 	.resource = tegra_nand_resources,
 };
+
+static struct resource tegra_pcie_resources[] = {
+	[0] = {
+		.start = TEGRA_PCIE_BASE,
+		.end = TEGRA_PCIE_BASE + TEGRA_PCIE_SIZE - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = TEGRA_PCIE_MMIO_BASE,
+		.end = TEGRA_PCIE_MMIO_BASE + TEGRA_PCIE_MMIO_SIZE - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[2] = {
+		.start = INT_PCIE_INTR,
+		.end = INT_PCIE_INTR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device tegra_pcie_device = {
+	.name = "tegra-pcie",
+	.id = -1,
+	.resource = tegra_pcie_resources,
+	.num_resources = ARRAY_SIZE(tegra_pcie_resources),
+};
diff --git a/arch/arm/mach-tegra/devices.h b/arch/arm/mach-tegra/devices.h
index f054d10..b2caed4 100644
--- a/arch/arm/mach-tegra/devices.h
+++ b/arch/arm/mach-tegra/devices.h
@@ -57,5 +57,6 @@ extern struct platform_device tegra_i2s_device1;
 extern struct platform_device tegra_i2s_device2;
 extern struct platform_device tegra_das_device;
 extern struct platform_device tegra_pwm_device;
+extern struct platform_device tegra_pcie_device;
 
 #endif
diff --git a/arch/arm/mach-tegra/include/mach/iomap.h b/arch/arm/mach-tegra/include/mach/iomap.h
index 3e80f3f..aee9d27 100644
--- a/arch/arm/mach-tegra/include/mach/iomap.h
+++ b/arch/arm/mach-tegra/include/mach/iomap.h
@@ -248,6 +248,12 @@
 #define TEGRA_CSITE_BASE		0x70040000
 #define TEGRA_CSITE_SIZE		SZ_256K
 
+#define TEGRA_PCIE_BASE			0x80000000
+#define TEGRA_PCIE_SIZE			SZ_4M
+
+#define TEGRA_PCIE_MMIO_BASE		0x80400000
+#define TEGRA_PCIE_MMIO_SIZE		SZ_64K
+
 #define TEGRA_USB_BASE			0xC5000000
 #define TEGRA_USB_SIZE			SZ_16K
 
diff --git a/arch/arm/mach-tegra/include/mach/pci-tegra.h b/arch/arm/mach-tegra/include/mach/pci-tegra.h
new file mode 100644
index 0000000..348a68a
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/pci-tegra.h
@@ -0,0 +1,29 @@
+/*
+ * arch/arm/mach-tegra/include/mach/tegra-pcie.h
+ *
+ * Copyright (C) 2012 Avionic Design GmbH
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MACH_TEGRA_PCIE_H
+#define __MACH_TEGRA_PCIE_H
+
+#include <linux/platform_device.h>
+
+#define TEGRA_PCIE_MAX_PORTS 2
+
+struct tegra_pcie_pdata {
+	int (*init)(struct platform_device *pdev);
+	int (*exit)(struct platform_device *pdev);
+	bool enable_ports[TEGRA_PCIE_MAX_PORTS];
+};
+
+#endif
diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c
index fcdf8bc..291d55d 100644
--- a/arch/arm/mach-tegra/pcie.c
+++ b/arch/arm/mach-tegra/pcie.c
@@ -27,7 +27,9 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
+#include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/clk.h>
@@ -40,8 +42,8 @@
 #include <mach/iomap.h>
 #include <mach/clk.h>
 #include <mach/powergate.h>
+#include <mach/pci-tegra.h>
 
-#include "board.h"
 #include "pmc.h"
 
 /* register definitions */
@@ -161,17 +163,12 @@
  * 0x90000000 - 0x9fffffff - non-prefetchable memory
  * 0xa0000000 - 0xbfffffff - prefetchable memory
  */
-#define TEGRA_PCIE_BASE		0x80000000
-
 #define PCIE_REGS_SZ		SZ_16K
 #define PCIE_CFG_OFF		PCIE_REGS_SZ
 #define PCIE_CFG_SZ		SZ_1M
 #define PCIE_EXT_CFG_OFF	(PCIE_CFG_SZ + PCIE_CFG_OFF)
 #define PCIE_EXT_CFG_SZ		SZ_1M
-#define PCIE_IOMAP_SZ		(PCIE_REGS_SZ + PCIE_CFG_SZ + PCIE_EXT_CFG_SZ)
 
-#define MMIO_BASE		(TEGRA_PCIE_BASE + SZ_4M)
-#define MMIO_SIZE		SZ_64K
 #define MEM_BASE_0		(TEGRA_PCIE_BASE + SZ_256M)
 #define MEM_SIZE_0		SZ_128M
 #define MEM_BASE_1		(MEM_BASE_0 + MEM_SIZE_0)
@@ -201,11 +198,14 @@ struct tegra_pcie_port {
 };
 
 struct tegra_pcie_info {
-	struct tegra_pcie_port	port[2];
+	struct device		*dev;
+
+	struct tegra_pcie_port	port[TEGRA_PCIE_MAX_PORTS];
 	int			num_ports;
 
 	void __iomem		*regs;
-	struct resource		res_mmio;
+	void __iomem		*mmio;
+	int			irq;
 
 	struct clk		*pex_clk;
 	struct clk		*afi_clk;
@@ -213,55 +213,53 @@ struct tegra_pcie_info {
 	struct clk		*pll_e;
 };
 
-static struct tegra_pcie_info tegra_pcie = {
-	.res_mmio = {
-		.name = "PCI IO",
-		.start = MMIO_BASE,
-		.end = MMIO_BASE + MMIO_SIZE - 1,
-		.flags = IORESOURCE_MEM,
-	},
-};
+static inline struct tegra_pcie_info *sys_to_pcie(struct pci_sys_data *sys)
+{
+	return sys->private_data;
+}
 
 void __iomem *tegra_pcie_io_base;
 EXPORT_SYMBOL(tegra_pcie_io_base);
 
-static inline void afi_writel(u32 value, unsigned long offset)
+static inline void afi_writel(struct tegra_pcie_info *pcie, u32 value, unsigned long offset)
 {
-	writel(value, offset + AFI_OFFSET + tegra_pcie.regs);
+	writel(value, offset + AFI_OFFSET + pcie->regs);
 }
 
-static inline u32 afi_readl(unsigned long offset)
+static inline u32 afi_readl(struct tegra_pcie_info *pcie, unsigned long offset)
 {
-	return readl(offset + AFI_OFFSET + tegra_pcie.regs);
+	return readl(offset + AFI_OFFSET + pcie->regs);
 }
 
-static inline void pads_writel(u32 value, unsigned long offset)
+static inline void pads_writel(struct tegra_pcie_info *pcie, u32 value, unsigned long offset)
 {
-	writel(value, offset + PADS_OFFSET + tegra_pcie.regs);
+	writel(value, offset + PADS_OFFSET + pcie->regs);
 }
 
-static inline u32 pads_readl(unsigned long offset)
+static inline u32 pads_readl(struct tegra_pcie_info *pcie, unsigned long offset)
 {
-	return readl(offset + PADS_OFFSET + tegra_pcie.regs);
+	return readl(offset + PADS_OFFSET + pcie->regs);
 }
 
-static struct tegra_pcie_port *bus_to_port(int bus)
+static struct tegra_pcie_port *bus_to_port(struct pci_bus *bus)
 {
+	struct tegra_pcie_info *pcie = sys_to_pcie(bus->sysdata);
 	int i;
 
-	for (i = tegra_pcie.num_ports - 1; i >= 0; i--) {
-		int rbus = tegra_pcie.port[i].root_bus_nr;
-		if (rbus != -1 && rbus == bus)
+	for (i = pcie->num_ports - 1; i >= 0; i--) {
+		int rbus = pcie->port[i].root_bus_nr;
+		if (rbus != -1 && rbus == bus->number)
 			break;
 	}
 
-	return i >= 0 ? tegra_pcie.port + i : NULL;
+	return i >= 0 ? pcie->port + i : NULL;
 }
 
 static int tegra_pcie_read_conf(struct pci_bus *bus, unsigned int devfn,
 				int where, int size, u32 *val)
 {
-	struct tegra_pcie_port *pp = bus_to_port(bus->number);
+	struct tegra_pcie_info *pcie = sys_to_pcie(bus->sysdata);
+	struct tegra_pcie_port *pp = bus_to_port(bus);
 	void __iomem *addr;
 
 	if (pp) {
@@ -272,10 +270,10 @@ static int tegra_pcie_read_conf(struct pci_bus *bus, unsigned int devfn,
 
 		addr = pp->base + (where & ~0x3);
 	} else {
-		addr = tegra_pcie.regs + (PCIE_CONF_BUS(bus->number) +
-					  PCIE_CONF_DEV(PCI_SLOT(devfn)) +
-					  PCIE_CONF_FUNC(PCI_FUNC(devfn)) +
-					  PCIE_CONF_REG(where));
+		addr = pcie->regs + (PCIE_CONF_BUS(bus->number) +
+				     PCIE_CONF_DEV(PCI_SLOT(devfn)) +
+				     PCIE_CONF_FUNC(PCI_FUNC(devfn)) +
+				     PCIE_CONF_REG(where));
 	}
 
 	*val = readl(addr);
@@ -291,7 +289,8 @@ static int tegra_pcie_read_conf(struct pci_bus *bus, unsigned int devfn,
 static int tegra_pcie_write_conf(struct pci_bus *bus, unsigned int devfn,
 				 int where, int size, u32 val)
 {
-	struct tegra_pcie_port *pp = bus_to_port(bus->number);
+	struct tegra_pcie_info *pcie = sys_to_pcie(bus->sysdata);
+	struct tegra_pcie_port *pp = bus_to_port(bus);
 	void __iomem *addr;
 
 	u32 mask;
@@ -303,10 +302,10 @@ static int tegra_pcie_write_conf(struct pci_bus *bus, unsigned int devfn,
 
 		addr = pp->base + (where & ~0x3);
 	} else {
-		addr = tegra_pcie.regs + (PCIE_CONF_BUS(bus->number) +
-					  PCIE_CONF_DEV(PCI_SLOT(devfn)) +
-					  PCIE_CONF_FUNC(PCI_FUNC(devfn)) +
-					  PCIE_CONF_REG(where));
+		addr = pcie->regs + (PCIE_CONF_BUS(bus->number) +
+				     PCIE_CONF_DEV(PCI_SLOT(devfn)) +
+				     PCIE_CONF_FUNC(PCI_FUNC(devfn)) +
+				     PCIE_CONF_REG(where));
 	}
 
 	if (size == 4) {
@@ -373,12 +372,13 @@ DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_relax_enable);
 
 static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
 {
+	struct tegra_pcie_info *pcie = sys_to_pcie(sys);
 	struct tegra_pcie_port *pp;
 
-	if (nr >= tegra_pcie.num_ports)
+	if (nr >= pcie->num_ports)
 		return 0;
 
-	pp = tegra_pcie.port + nr;
+	pp = pcie->port + nr;
 	pp->root_bus_nr = sys->busnr;
 
 	/*
@@ -441,34 +441,29 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
 	return 1;
 }
 
-static int tegra_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+static int tegra_pcie_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
 {
-	return INT_PCIE_INTR;
+	struct tegra_pcie_info *pcie = sys_to_pcie(pdev->bus->sysdata);
+
+	return pcie->irq;
 }
 
-static struct pci_bus __init *tegra_pcie_scan_bus(int nr,
-						  struct pci_sys_data *sys)
+static struct pci_bus __devinit *tegra_pcie_scan_bus(int nr,
+						     struct pci_sys_data *sys)
 {
+	struct tegra_pcie_info *pcie = sys_to_pcie(sys);
 	struct tegra_pcie_port *pp;
 
-	if (nr >= tegra_pcie.num_ports)
+	if (nr >= pcie->num_ports)
 		return NULL;
 
-	pp = tegra_pcie.port + nr;
+	pp = pcie->port + nr;
 	pp->root_bus_nr = sys->busnr;
 
 	return pci_scan_root_bus(NULL, sys->busnr, &tegra_pcie_ops, sys,
 				 &sys->resources);
 }
 
-static struct hw_pci tegra_pcie_hw __initdata = {
-	.nr_controllers	= 2,
-	.setup		= tegra_pcie_setup,
-	.scan		= tegra_pcie_scan_bus,
-	.map_irq	= tegra_pcie_map_irq,
-};
-
-
 static irqreturn_t tegra_pcie_isr(int irq, void *arg)
 {
 	const char *err_msg[] = {
@@ -482,12 +477,12 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg)
 		"AXI response decoding error",
 		"Transcation timeout",
 	};
-
+	struct tegra_pcie_info *pcie = arg;
 	u32 code, signature;
 
-	code = afi_readl(AFI_INTR_CODE) & AFI_INTR_CODE_MASK;
-	signature = afi_readl(AFI_INTR_SIGNATURE);
-	afi_writel(0, AFI_INTR_CODE);
+	code = afi_readl(pcie, AFI_INTR_CODE) & AFI_INTR_CODE_MASK;
+	signature = afi_readl(pcie, AFI_INTR_SIGNATURE);
+	afi_writel(pcie, 0, AFI_INTR_CODE);
 
 	if (code == AFI_INTR_LEGACY)
 		return IRQ_NONE;
@@ -500,14 +495,16 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg)
 	 * happen a lot during enumeration
 	 */
 	if (code == AFI_INTR_MASTER_ABORT)
-		pr_debug("PCIE: %s, signature: %08x\n", err_msg[code], signature);
+		dev_dbg(pcie->dev, "%s, signature: %08x\n", err_msg[code],
+			signature);
 	else
-		pr_err("PCIE: %s, signature: %08x\n", err_msg[code], signature);
+		dev_err(pcie->dev, "%s, signature: %08x\n", err_msg[code],
+			signature);
 
 	return IRQ_HANDLED;
 }
 
-static void tegra_pcie_setup_translations(void)
+static void tegra_pcie_setup_translations(struct tegra_pcie_info *pcie)
 {
 	u32 fpci_bar;
 	u32 size;
@@ -517,120 +514,120 @@ static void tegra_pcie_setup_translations(void)
 	fpci_bar = ((u32)0xfdff << 16);
 	size = PCIE_CFG_SZ;
 	axi_address = TEGRA_PCIE_BASE + PCIE_CFG_OFF;
-	afi_writel(axi_address, AFI_AXI_BAR0_START);
-	afi_writel(size >> 12, AFI_AXI_BAR0_SZ);
-	afi_writel(fpci_bar, AFI_FPCI_BAR0);
+	afi_writel(pcie, axi_address, AFI_AXI_BAR0_START);
+	afi_writel(pcie, size >> 12, AFI_AXI_BAR0_SZ);
+	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR0);
 
 	/* Bar 1: extended config Bar */
 	fpci_bar = ((u32)0xfe1 << 20);
 	size = PCIE_EXT_CFG_SZ;
 	axi_address = TEGRA_PCIE_BASE + PCIE_EXT_CFG_OFF;
-	afi_writel(axi_address, AFI_AXI_BAR1_START);
-	afi_writel(size >> 12, AFI_AXI_BAR1_SZ);
-	afi_writel(fpci_bar, AFI_FPCI_BAR1);
+	afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
+	afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
+	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
 
 	/* Bar 2: downstream IO bar */
 	fpci_bar = ((__u32)0xfdfc << 16);
-	size = MMIO_SIZE;
-	axi_address = MMIO_BASE;
-	afi_writel(axi_address, AFI_AXI_BAR2_START);
-	afi_writel(size >> 12, AFI_AXI_BAR2_SZ);
-	afi_writel(fpci_bar, AFI_FPCI_BAR2);
+	size = TEGRA_PCIE_MMIO_SIZE;
+	axi_address = TEGRA_PCIE_MMIO_BASE;
+	afi_writel(pcie, axi_address, AFI_AXI_BAR2_START);
+	afi_writel(pcie, size >> 12, AFI_AXI_BAR2_SZ);
+	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR2);
 
 	/* Bar 3: prefetchable memory BAR */
 	fpci_bar = (((PREFETCH_MEM_BASE_0 >> 12) & 0x0fffffff) << 4) | 0x1;
 	size =  PREFETCH_MEM_SIZE_0 +  PREFETCH_MEM_SIZE_1;
 	axi_address = PREFETCH_MEM_BASE_0;
-	afi_writel(axi_address, AFI_AXI_BAR3_START);
-	afi_writel(size >> 12, AFI_AXI_BAR3_SZ);
-	afi_writel(fpci_bar, AFI_FPCI_BAR3);
+	afi_writel(pcie, axi_address, AFI_AXI_BAR3_START);
+	afi_writel(pcie, size >> 12, AFI_AXI_BAR3_SZ);
+	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR3);
 
 	/* Bar 4: non prefetchable memory BAR */
 	fpci_bar = (((MEM_BASE_0 >> 12)	& 0x0FFFFFFF) << 4) | 0x1;
 	size = MEM_SIZE_0 + MEM_SIZE_1;
 	axi_address = MEM_BASE_0;
-	afi_writel(axi_address, AFI_AXI_BAR4_START);
-	afi_writel(size >> 12, AFI_AXI_BAR4_SZ);
-	afi_writel(fpci_bar, AFI_FPCI_BAR4);
+	afi_writel(pcie, axi_address, AFI_AXI_BAR4_START);
+	afi_writel(pcie, size >> 12, AFI_AXI_BAR4_SZ);
+	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR4);
 
 	/* Bar 5: NULL out the remaining BAR as it is not used */
 	fpci_bar = 0;
 	size = 0;
 	axi_address = 0;
-	afi_writel(axi_address, AFI_AXI_BAR5_START);
-	afi_writel(size >> 12, AFI_AXI_BAR5_SZ);
-	afi_writel(fpci_bar, AFI_FPCI_BAR5);
+	afi_writel(pcie, axi_address, AFI_AXI_BAR5_START);
+	afi_writel(pcie, size >> 12, AFI_AXI_BAR5_SZ);
+	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR5);
 
 	/* map all upstream transactions as uncached */
-	afi_writel(PHYS_OFFSET, AFI_CACHE_BAR0_ST);
-	afi_writel(0, AFI_CACHE_BAR0_SZ);
-	afi_writel(0, AFI_CACHE_BAR1_ST);
-	afi_writel(0, AFI_CACHE_BAR1_SZ);
+	afi_writel(pcie, PHYS_OFFSET, AFI_CACHE_BAR0_ST);
+	afi_writel(pcie, 0, AFI_CACHE_BAR0_SZ);
+	afi_writel(pcie, 0, AFI_CACHE_BAR1_ST);
+	afi_writel(pcie, 0, AFI_CACHE_BAR1_SZ);
 
 	/* No MSI */
-	afi_writel(0, AFI_MSI_FPCI_BAR_ST);
-	afi_writel(0, AFI_MSI_BAR_SZ);
-	afi_writel(0, AFI_MSI_AXI_BAR_ST);
-	afi_writel(0, AFI_MSI_BAR_SZ);
+	afi_writel(pcie, 0, AFI_MSI_FPCI_BAR_ST);
+	afi_writel(pcie, 0, AFI_MSI_BAR_SZ);
+	afi_writel(pcie, 0, AFI_MSI_AXI_BAR_ST);
+	afi_writel(pcie, 0, AFI_MSI_BAR_SZ);
 }
 
-static int tegra_pcie_enable_controller(void)
+static int tegra_pcie_enable_controller(struct tegra_pcie_info *pcie)
 {
 	u32 val, reg;
 	int i, timeout;
 
 	/* Enable slot clock and pulse the reset signals */
 	for (i = 0, reg = AFI_PEX0_CTRL; i < 2; i++, reg += 0x8) {
-		val = afi_readl(reg) |  AFI_PEX_CTRL_REFCLK_EN;
-		afi_writel(val, reg);
+		val = afi_readl(pcie, reg) |  AFI_PEX_CTRL_REFCLK_EN;
+		afi_writel(pcie, val, reg);
 		val &= ~AFI_PEX_CTRL_RST;
-		afi_writel(val, reg);
+		afi_writel(pcie, val, reg);
 
-		val = afi_readl(reg) | AFI_PEX_CTRL_RST;
-		afi_writel(val, reg);
+		val = afi_readl(pcie, reg) | AFI_PEX_CTRL_RST;
+		afi_writel(pcie, val, reg);
 	}
 
 	/* Enable dual controller and both ports */
-	val = afi_readl(AFI_PCIE_CONFIG);
+	val = afi_readl(pcie, AFI_PCIE_CONFIG);
 	val &= ~(AFI_PCIE_CONFIG_PCIEC0_DISABLE_DEVICE |
 		 AFI_PCIE_CONFIG_PCIEC1_DISABLE_DEVICE |
 		 AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_MASK);
 	val |= AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_DUAL;
-	afi_writel(val, AFI_PCIE_CONFIG);
+	afi_writel(pcie, val, AFI_PCIE_CONFIG);
 
-	val = afi_readl(AFI_FUSE) & ~AFI_FUSE_PCIE_T0_GEN2_DIS;
-	afi_writel(val, AFI_FUSE);
+	val = afi_readl(pcie, AFI_FUSE) & ~AFI_FUSE_PCIE_T0_GEN2_DIS;
+	afi_writel(pcie, val, AFI_FUSE);
 
 	/* Initialze internal PHY, enable up to 16 PCIE lanes */
-	pads_writel(0x0, PADS_CTL_SEL);
+	pads_writel(pcie, 0x0, PADS_CTL_SEL);
 
 	/* override IDDQ to 1 on all 4 lanes */
-	val = pads_readl(PADS_CTL) | PADS_CTL_IDDQ_1L;
-	pads_writel(val, PADS_CTL);
+	val = pads_readl(pcie, PADS_CTL) | PADS_CTL_IDDQ_1L;
+	pads_writel(pcie, val, PADS_CTL);
 
 	/*
 	 * set up PHY PLL inputs select PLLE output as refclock,
 	 * set TX ref sel to div10 (not div5)
 	 */
-	val = pads_readl(PADS_PLL_CTL);
+	val = pads_readl(pcie, PADS_PLL_CTL);
 	val &= ~(PADS_PLL_CTL_REFCLK_MASK | PADS_PLL_CTL_TXCLKREF_MASK);
 	val |= (PADS_PLL_CTL_REFCLK_INTERNAL_CML | PADS_PLL_CTL_TXCLKREF_DIV10);
-	pads_writel(val, PADS_PLL_CTL);
+	pads_writel(pcie, val, PADS_PLL_CTL);
 
 	/* take PLL out of reset  */
-	val = pads_readl(PADS_PLL_CTL) | PADS_PLL_CTL_RST_B4SM;
-	pads_writel(val, PADS_PLL_CTL);
+	val = pads_readl(pcie, PADS_PLL_CTL) | PADS_PLL_CTL_RST_B4SM;
+	pads_writel(pcie, val, PADS_PLL_CTL);
 
 	/*
 	 * Hack, set the clock voltage to the DEFAULT provided by hw folks.
 	 * This doesn't exist in the documentation
 	 */
-	pads_writel(0xfa5cfa5c, 0xc8);
+	pads_writel(pcie, 0xfa5cfa5c, 0xc8);
 
 	/* Wait for the PLL to lock */
 	timeout = 300;
 	do {
-		val = pads_readl(PADS_PLL_CTL);
+		val = pads_readl(pcie, PADS_PLL_CTL);
 		usleep_range(1000, 1000);
 		if (--timeout == 0) {
 			pr_err("Tegra PCIe error: timeout waiting for PLL\n");
@@ -639,188 +636,237 @@ static int tegra_pcie_enable_controller(void)
 	} while (!(val & PADS_PLL_CTL_LOCKDET));
 
 	/* turn off IDDQ override */
-	val = pads_readl(PADS_CTL) & ~PADS_CTL_IDDQ_1L;
-	pads_writel(val, PADS_CTL);
+	val = pads_readl(pcie, PADS_CTL) & ~PADS_CTL_IDDQ_1L;
+	pads_writel(pcie, val, PADS_CTL);
 
 	/* enable TX/RX data */
-	val = pads_readl(PADS_CTL);
+	val = pads_readl(pcie, PADS_CTL);
 	val |= (PADS_CTL_TX_DATA_EN_1L | PADS_CTL_RX_DATA_EN_1L);
-	pads_writel(val, PADS_CTL);
+	pads_writel(pcie, val, PADS_CTL);
 
 	/* Take the PCIe interface module out of reset */
-	tegra_periph_reset_deassert(tegra_pcie.pcie_xclk);
+	tegra_periph_reset_deassert(pcie->pcie_xclk);
 
 	/* Finally enable PCIe */
-	val = afi_readl(AFI_CONFIGURATION) | AFI_CONFIGURATION_EN_FPCI;
-	afi_writel(val, AFI_CONFIGURATION);
+	val = afi_readl(pcie, AFI_CONFIGURATION) | AFI_CONFIGURATION_EN_FPCI;
+	afi_writel(pcie, val, AFI_CONFIGURATION);
 
 	val = (AFI_INTR_EN_INI_SLVERR | AFI_INTR_EN_INI_DECERR |
 	       AFI_INTR_EN_TGT_SLVERR | AFI_INTR_EN_TGT_DECERR |
 	       AFI_INTR_EN_TGT_WRERR | AFI_INTR_EN_DFPCI_DECERR);
-	afi_writel(val, AFI_AFI_INTR_ENABLE);
-	afi_writel(0xffffffff, AFI_SM_INTR_ENABLE);
+	afi_writel(pcie, val, AFI_AFI_INTR_ENABLE);
+	afi_writel(pcie, 0xffffffff, AFI_SM_INTR_ENABLE);
 
 	/* FIXME: No MSI for now, only INT */
-	afi_writel(AFI_INTR_MASK_INT_MASK, AFI_INTR_MASK);
+	afi_writel(pcie, AFI_INTR_MASK_INT_MASK, AFI_INTR_MASK);
 
 	/* Disable all execptions */
-	afi_writel(0, AFI_FPCI_ERROR_MASKS);
+	afi_writel(pcie, 0, AFI_FPCI_ERROR_MASKS);
 
 	return 0;
 }
 
-static void tegra_pcie_power_off(void)
+static void tegra_pcie_power_off(struct tegra_pcie_info *pcie)
 {
-	tegra_periph_reset_assert(tegra_pcie.pcie_xclk);
-	tegra_periph_reset_assert(tegra_pcie.afi_clk);
-	tegra_periph_reset_assert(tegra_pcie.pex_clk);
+	tegra_periph_reset_assert(pcie->pcie_xclk);
+	tegra_periph_reset_assert(pcie->afi_clk);
+	tegra_periph_reset_assert(pcie->pex_clk);
 
 	tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
 	tegra_pmc_pcie_xclk_clamp(true);
 }
 
-static int tegra_pcie_power_regate(void)
+static int tegra_pcie_power_regate(struct tegra_pcie_info *pcie)
 {
 	int err;
 
-	tegra_pcie_power_off();
+	tegra_pcie_power_off(pcie);
 
 	tegra_pmc_pcie_xclk_clamp(true);
 
-	tegra_periph_reset_assert(tegra_pcie.pcie_xclk);
-	tegra_periph_reset_assert(tegra_pcie.afi_clk);
+	tegra_periph_reset_assert(pcie->pcie_xclk);
+	tegra_periph_reset_assert(pcie->afi_clk);
 
 	err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_PCIE,
-						tegra_pcie.pex_clk);
+						pcie->pex_clk);
 	if (err) {
-		pr_err("PCIE: powerup sequence failed: %d\n", err);
+		dev_err(pcie->dev, "powerup sequence failed: %d\n", err);
 		return err;
 	}
 
-	tegra_periph_reset_deassert(tegra_pcie.afi_clk);
+	tegra_periph_reset_deassert(pcie->afi_clk);
 
 	tegra_pmc_pcie_xclk_clamp(false);
 
-	clk_enable(tegra_pcie.afi_clk);
-	clk_enable(tegra_pcie.pex_clk);
-	return clk_enable(tegra_pcie.pll_e);
+	clk_enable(pcie->afi_clk);
+	clk_enable(pcie->pex_clk);
+	return clk_enable(pcie->pll_e);
 }
 
-static int tegra_pcie_clocks_get(void)
+static int tegra_pcie_clocks_get(struct tegra_pcie_info *pcie)
 {
 	int err;
 
-	tegra_pcie.pex_clk = clk_get(NULL, "pex");
-	if (IS_ERR(tegra_pcie.pex_clk))
-		return PTR_ERR(tegra_pcie.pex_clk);
+	pcie->pex_clk = clk_get(NULL, "pex");
+	if (IS_ERR(pcie->pex_clk))
+		return PTR_ERR(pcie->pex_clk);
 
-	tegra_pcie.afi_clk = clk_get(NULL, "afi");
-	if (IS_ERR(tegra_pcie.afi_clk)) {
-		err = PTR_ERR(tegra_pcie.afi_clk);
+	pcie->afi_clk = clk_get(NULL, "afi");
+	if (IS_ERR(pcie->afi_clk)) {
+		err = PTR_ERR(pcie->afi_clk);
 		goto err_afi_clk;
 	}
 
-	tegra_pcie.pcie_xclk = clk_get(NULL, "pcie_xclk");
-	if (IS_ERR(tegra_pcie.pcie_xclk)) {
-		err =  PTR_ERR(tegra_pcie.pcie_xclk);
+	pcie->pcie_xclk = clk_get(NULL, "pcie_xclk");
+	if (IS_ERR(pcie->pcie_xclk)) {
+		err = PTR_ERR(pcie->pcie_xclk);
 		goto err_pcie_xclk;
 	}
 
-	tegra_pcie.pll_e = clk_get_sys(NULL, "pll_e");
-	if (IS_ERR(tegra_pcie.pll_e)) {
-		err = PTR_ERR(tegra_pcie.pll_e);
+	pcie->pll_e = clk_get_sys(NULL, "pll_e");
+	if (IS_ERR(pcie->pll_e)) {
+		err = PTR_ERR(pcie->pll_e);
 		goto err_pll_e;
 	}
 
 	return 0;
 
 err_pll_e:
-	clk_put(tegra_pcie.pcie_xclk);
+	clk_put(pcie->pcie_xclk);
 err_pcie_xclk:
-	clk_put(tegra_pcie.afi_clk);
+	clk_put(pcie->afi_clk);
 err_afi_clk:
-	clk_put(tegra_pcie.pex_clk);
+	clk_put(pcie->pex_clk);
 
 	return err;
 }
 
-static void tegra_pcie_clocks_put(void)
+static void tegra_pcie_clocks_put(struct tegra_pcie_info *pcie)
 {
-	clk_put(tegra_pcie.pll_e);
-	clk_put(tegra_pcie.pcie_xclk);
-	clk_put(tegra_pcie.afi_clk);
-	clk_put(tegra_pcie.pex_clk);
+	clk_put(pcie->pll_e);
+	clk_put(pcie->pcie_xclk);
+	clk_put(pcie->afi_clk);
+	clk_put(pcie->pex_clk);
 }
 
-static int __init tegra_pcie_get_resources(void)
+static int __devinit tegra_pcie_get_resources(struct platform_device *pdev)
 {
-	struct resource *res_mmio = &tegra_pcie.res_mmio;
+	struct tegra_pcie_info *pcie = platform_get_drvdata(pdev);
+	struct resource *regs;
+	struct resource *mmio;
 	int err;
 
-	err = tegra_pcie_clocks_get();
+	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	mmio = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+
+	if (!regs || !mmio) {
+		dev_err(&pdev->dev, "failed to get I/O resources\n");
+		return -ENXIO;
+	}
+
+	err = tegra_pcie_clocks_get(pcie);
 	if (err) {
-		pr_err("PCIE: failed to get clocks: %d\n", err);
+		dev_err(&pdev->dev, "failed to get clocks: %d\n", err);
 		return err;
 	}
 
-	err = tegra_pcie_power_regate();
+	err = tegra_pcie_power_regate(pcie);
 	if (err) {
-		pr_err("PCIE: failed to power up: %d\n", err);
+		dev_err(&pdev->dev, "failed to power up: %d\n", err);
 		goto err_pwr_on;
 	}
 
-	tegra_pcie.regs = ioremap_nocache(TEGRA_PCIE_BASE, PCIE_IOMAP_SZ);
-	if (tegra_pcie.regs == NULL) {
-		pr_err("PCIE: Failed to map PCI/AFI registers\n");
+	regs = request_mem_region(regs->start, resource_size(regs), "PCI/AFI");
+	if (regs == NULL) {
+		dev_err(&pdev->dev, "failed to request PCI/AFI region: %d\n", err);
+		goto err_req_reg;
+	}
+
+	pcie->regs = ioremap_nocache(regs->start, resource_size(regs));
+	if (pcie->regs == NULL) {
+		dev_err(&pdev->dev, "failed to map PCI/AFI registers\n");
 		err = -ENOMEM;
 		goto err_map_reg;
 	}
 
-	err = request_resource(&iomem_resource, res_mmio);
-	if (err) {
-		pr_err("PCIE: Failed to request resources: %d\n", err);
+	mmio = request_mem_region(mmio->start, resource_size(mmio), "PCI I/O");
+	if (mmio == NULL) {
+		dev_err(&pdev->dev, "failed to request PCI I/O region: %d\n", err);
 		goto err_req_io;
 	}
 
-	tegra_pcie_io_base = ioremap_nocache(res_mmio->start,
-					     resource_size(res_mmio));
-	if (tegra_pcie_io_base == NULL) {
-		pr_err("PCIE: Failed to map IO\n");
+	pcie->mmio = ioremap_nocache(mmio->start, resource_size(mmio));
+	if (pcie->mmio == NULL) {
+		dev_err(&pdev->dev, "failed to map PCI I/O region\n");
 		err = -ENOMEM;
 		goto err_map_io;
 	}
 
-	err = request_irq(INT_PCIE_INTR, tegra_pcie_isr,
-			  IRQF_SHARED, "PCIE", &tegra_pcie);
+	tegra_pcie_io_base = pcie->mmio;
+
+	err = platform_get_irq(pdev, 0);
+	if (err < 0) {
+		dev_err(&pdev->dev, "failed to get IRQ: %d\n", err);
+		goto err_irq;
+	}
+
+	pcie->irq = err;
+
+	err = request_irq(pcie->irq, tegra_pcie_isr, IRQF_SHARED, "PCIE",
+			  pcie);
 	if (err) {
-		pr_err("PCIE: Failed to register IRQ: %d\n", err);
+		dev_err(&pdev->dev, "failed to register IRQ: %d\n", err);
 		goto err_irq;
 	}
-	set_irq_flags(INT_PCIE_INTR, IRQF_VALID);
 
 	return 0;
 
 err_irq:
-	iounmap(tegra_pcie_io_base);
+	iounmap(pcie->mmio);
 err_map_io:
-	release_resource(&tegra_pcie.res_mmio);
+	release_resource(mmio);
 err_req_io:
-	iounmap(tegra_pcie.regs);
+	iounmap(pcie->regs);
 err_map_reg:
-	tegra_pcie_power_off();
+	release_resource(regs);
+err_req_reg:
+	tegra_pcie_power_off(pcie);
 err_pwr_on:
-	tegra_pcie_clocks_put();
+	tegra_pcie_clocks_put(pcie);
 
 	return err;
 }
 
+static int tegra_pcie_put_resources(struct platform_device *pdev)
+{
+	struct tegra_pcie_info *pcie = platform_get_drvdata(pdev);
+	struct resource *regs;
+	struct resource *mmio;
+
+	free_irq(pcie->irq, pcie);
+
+	iounmap(pcie->mmio);
+	mmio = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	release_resource(mmio);
+
+	iounmap(pcie->regs);
+	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	release_resource(regs);
+
+	tegra_pcie_power_off(pcie);
+	tegra_pcie_clocks_put(pcie);
+
+	return 0;
+}
+
 /*
  * FIXME: If there are no PCIe cards attached, then calling this function
  * can result in the increase of the bootup time as there are big timeout
  * loops.
  */
 #define TEGRA_PCIE_LINKUP_TIMEOUT	200	/* up to 1.2 seconds */
-static bool tegra_pcie_check_link(struct tegra_pcie_port *pp, int idx,
+static bool tegra_pcie_check_link(struct tegra_pcie_info *pcie,
+				  struct tegra_pcie_port *pp, int idx,
 				  u32 reset_reg)
 {
 	u32 reg;
@@ -840,7 +886,7 @@ static bool tegra_pcie_check_link(struct tegra_pcie_port *pp, int idx,
 		}
 
 		if (!timeout)  {
-			pr_err("PCIE: port %d: link down, retrying\n", idx);
+			dev_err(pcie->dev, "port %d: link down, retrying\n", idx);
 			goto retry;
 		}
 
@@ -857,11 +903,11 @@ static bool tegra_pcie_check_link(struct tegra_pcie_port *pp, int idx,
 
 retry:
 		/* Pulse the PEX reset */
-		reg = afi_readl(reset_reg) | AFI_PEX_CTRL_RST;
-		afi_writel(reg, reset_reg);
+		reg = afi_readl(pcie, reset_reg) | AFI_PEX_CTRL_RST;
+		afi_writel(pcie, reg, reset_reg);
 		mdelay(1);
-		reg = afi_readl(reset_reg) & ~AFI_PEX_CTRL_RST;
-		afi_writel(reg, reset_reg);
+		reg = afi_readl(pcie, reset_reg) & ~AFI_PEX_CTRL_RST;
+		afi_writel(pcie, reg, reset_reg);
 
 		retries--;
 	} while (retries);
@@ -869,55 +915,117 @@ retry:
 	return false;
 }
 
-static void __init tegra_pcie_add_port(int index, u32 offset, u32 reset_reg)
+static void __devinit tegra_pcie_add_port(struct tegra_pcie_info *pcie,
+					  int index, u32 offset,
+					  u32 reset_reg)
 {
 	struct tegra_pcie_port *pp;
 
-	pp = tegra_pcie.port + tegra_pcie.num_ports;
+	pp = pcie->port + pcie->num_ports;
 
 	pp->index = -1;
-	pp->base = tegra_pcie.regs + offset;
-	pp->link_up = tegra_pcie_check_link(pp, index, reset_reg);
+	pp->base = pcie->regs + offset;
+	pp->link_up = tegra_pcie_check_link(pcie, pp, index, reset_reg);
 
 	if (!pp->link_up) {
 		pp->base = NULL;
-		printk(KERN_INFO "PCIE: port %d: link down, ignoring\n", index);
+		dev_info(pcie->dev, "port %d: link down, ignoring\n", index);
 		return;
 	}
 
-	tegra_pcie.num_ports++;
+	pcie->num_ports++;
 	pp->index = index;
 	pp->root_bus_nr = -1;
 	memset(pp->res, 0, sizeof(pp->res));
 }
 
-int __init tegra_pcie_init(bool init_port0, bool init_port1)
+static int __devinit tegra_pcie_probe(struct platform_device *pdev)
 {
+	struct tegra_pcie_pdata *pdata = pdev->dev.platform_data;
+	void *private_data[TEGRA_PCIE_MAX_PORTS];
+	struct tegra_pcie_info *pcie;
+	struct hw_pci hw;
 	int err;
 
-	if (!(init_port0 || init_port1))
+	if (!pdata->enable_ports[0] && !pdata->enable_ports[1])
 		return -ENODEV;
 
+	pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL);
+	if (!pcie)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, pcie);
+	pcie->dev = &pdev->dev;
+
 	pcibios_min_mem = 0;
 
-	err = tegra_pcie_get_resources();
-	if (err)
+	err = tegra_pcie_get_resources(pdev);
+	if (err < 0) {
+		dev_err(&pdev->dev, "failed to request resources: %d\n", err);
 		return err;
+	}
+
+	if (pdata->init) {
+		err = pdata->init(pdev);
+		if (err < 0) {
+			tegra_pcie_put_resources(pdev);
+			return err;
+		}
+	}
 
-	err = tegra_pcie_enable_controller();
+	err = tegra_pcie_enable_controller(pcie);
 	if (err)
 		return err;
 
 	/* setup the AFI address translations */
-	tegra_pcie_setup_translations();
+	tegra_pcie_setup_translations(pcie);
 
-	if (init_port0)
-		tegra_pcie_add_port(0, RP0_OFFSET, AFI_PEX0_CTRL);
+	if (pdata->enable_ports[0]) {
+		tegra_pcie_add_port(pcie, 0, RP0_OFFSET, AFI_PEX0_CTRL);
+		private_data[0] = pcie;
+	}
+
+	if (pdata->enable_ports[1]) {
+		tegra_pcie_add_port(pcie, 1, RP1_OFFSET, AFI_PEX1_CTRL);
+		private_data[1] = pcie;
+	}
 
-	if (init_port1)
-		tegra_pcie_add_port(1, RP1_OFFSET, AFI_PEX1_CTRL);
+	memset(&hw, 0, sizeof(hw));
+	hw.nr_controllers = 2;
+	hw.private_data = private_data;
+	hw.setup = tegra_pcie_setup;
+	hw.scan = tegra_pcie_scan_bus;
+	hw.map_irq = tegra_pcie_map_irq;
 
-	pci_common_init(&tegra_pcie_hw);
+	pci_common_init(&hw);
 
 	return 0;
 }
+
+static int __devexit tegra_pcie_remove(struct platform_device *pdev)
+{
+	struct tegra_pcie_pdata *pdata = pdev->dev.platform_data;
+	int err;
+
+	err = tegra_pcie_put_resources(pdev);
+	if (err < 0)
+		return err;
+
+	if (pdata->exit) {
+		err = pdata->exit(pdev);
+		if (err < 0)
+			return err;
+	}
+
+	return 0;
+}
+
+static struct platform_driver tegra_pcie_driver = {
+	.driver = {
+		.name = "tegra-pcie",
+		.owner = THIS_MODULE,
+	},
+	.probe = tegra_pcie_probe,
+	.remove = __devexit_p(tegra_pcie_remove),
+};
+module_platform_driver(tegra_pcie_driver);
-- 
1.7.10.4

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

* [PATCH v2 05/10] ARM: tegra: Rewrite PCIe support as a driver
@ 2012-06-11 15:05   ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-11 15:05 UTC (permalink / raw)
  To: linux-arm-kernel

This commit adds a platform device driver for the PCIe controller on
Tegra SOCs. Current users of the old code (TrimSlice and Harmony) are
converted and now initialize and register a corresponding platform
device.

Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>

---
Changes in v2:
- use struct hw_pci's new private_data field
- fix DT initialization for TrimSlice
---
 arch/arm/mach-tegra/board-dt-tegra20.c       |   15 +-
 arch/arm/mach-tegra/board-harmony-pcie.c     |   38 +-
 arch/arm/mach-tegra/board-harmony.c          |    1 +
 arch/arm/mach-tegra/board-harmony.h          |    1 +
 arch/arm/mach-tegra/board-trimslice.c        |   18 +-
 arch/arm/mach-tegra/board.h                  |    2 +-
 arch/arm/mach-tegra/devices.c                |   25 ++
 arch/arm/mach-tegra/devices.h                |    1 +
 arch/arm/mach-tegra/include/mach/iomap.h     |    6 +
 arch/arm/mach-tegra/include/mach/pci-tegra.h |   29 ++
 arch/arm/mach-tegra/pcie.c                   |  514 ++++++++++++++++----------
 11 files changed, 419 insertions(+), 231 deletions(-)
 create mode 100644 arch/arm/mach-tegra/include/mach/pci-tegra.h

diff --git a/arch/arm/mach-tegra/board-dt-tegra20.c b/arch/arm/mach-tegra/board-dt-tegra20.c
index 9c444a0..0f29c05 100644
--- a/arch/arm/mach-tegra/board-dt-tegra20.c
+++ b/arch/arm/mach-tegra/board-dt-tegra20.c
@@ -40,6 +40,7 @@
 
 #include <mach/iomap.h>
 #include <mach/irqs.h>
+#include <mach/pci-tegra.h>
 
 #include "board.h"
 #include "board-harmony.h"
@@ -116,13 +117,17 @@ static void __init tegra_dt_init(void)
 }
 
 #ifdef CONFIG_MACH_TRIMSLICE
+static struct tegra_pcie_pdata trimslice_pcie_pdata = {
+	.enable_ports = {
+		[0] = true,
+		[1] = true,
+	},
+};
+
 static void __init trimslice_init(void)
 {
-	int ret;
-
-	ret = tegra_pcie_init(true, true);
-	if (ret)
-		pr_err("tegra_pci_init() failed: %d\n", ret);
+	tegra_pcie_device.dev.platform_data = &trimslice_pcie_pdata;
+	platform_device_register(&tegra_pcie_device);
 }
 #endif
 
diff --git a/arch/arm/mach-tegra/board-harmony-pcie.c b/arch/arm/mach-tegra/board-harmony-pcie.c
index e8c3fda..8373271 100644
--- a/arch/arm/mach-tegra/board-harmony-pcie.c
+++ b/arch/arm/mach-tegra/board-harmony-pcie.c
@@ -22,12 +22,14 @@
 
 #include <asm/mach-types.h>
 
+#include <mach/pci-tegra.h>
+
 #include "board.h"
+#include "devices.h"
 #include "board-harmony.h"
 
 #ifdef CONFIG_TEGRA_PCI
-
-int __init harmony_pcie_init(void)
+static int harmony_pcie_board_init(struct platform_device *pdev)
 {
 	struct regulator *regulator = NULL;
 	int err;
@@ -44,30 +46,32 @@ int __init harmony_pcie_init(void)
 
 	regulator_enable(regulator);
 
-	err = tegra_pcie_init(true, true);
-	if (err)
-		goto err_pcie;
-
 	return 0;
 
-err_pcie:
-	regulator_disable(regulator);
-	regulator_put(regulator);
 err_reg:
 	gpio_free(TEGRA_GPIO_EN_VDD_1V05_GPIO);
 
 	return err;
 }
 
-static int __init harmony_pcie_initcall(void)
+static struct tegra_pcie_pdata harmony_pcie_pdata = {
+	.init = harmony_pcie_board_init,
+	.enable_ports = {
+		[0] = true,
+		[1] = true,
+	},
+};
+
+int __init harmony_pcie_init(void)
 {
-	if (!machine_is_harmony())
-		return 0;
+	tegra_pcie_device.dev.platform_data = &harmony_pcie_pdata;
+	platform_device_register(&tegra_pcie_device);
 
-	return harmony_pcie_init();
+	return 0;
+}
+#else
+int __init harmony_pcie_init(void)
+{
+	return 0;
 }
-
-/* PCI should be initialized after I2C, mfd and regulators */
-subsys_initcall_sync(harmony_pcie_initcall);
-
 #endif
diff --git a/arch/arm/mach-tegra/board-harmony.c b/arch/arm/mach-tegra/board-harmony.c
index e5f3352..063c7d5 100644
--- a/arch/arm/mach-tegra/board-harmony.c
+++ b/arch/arm/mach-tegra/board-harmony.c
@@ -204,6 +204,7 @@ static void __init tegra_harmony_init(void)
 	pwm_add_table(harmony_pwm_lookup, ARRAY_SIZE(harmony_pwm_lookup));
 	harmony_i2c_init();
 	harmony_regulator_init();
+	harmony_pcie_init();
 }
 
 MACHINE_START(HARMONY, "harmony")
diff --git a/arch/arm/mach-tegra/board-harmony.h b/arch/arm/mach-tegra/board-harmony.h
index 139d96c..afa68e2 100644
--- a/arch/arm/mach-tegra/board-harmony.h
+++ b/arch/arm/mach-tegra/board-harmony.h
@@ -37,5 +37,6 @@
 
 void harmony_pinmux_init(void);
 int harmony_regulator_init(void);
+int harmony_pcie_init(void);
 
 #endif
diff --git a/arch/arm/mach-tegra/board-trimslice.c b/arch/arm/mach-tegra/board-trimslice.c
index 776aa95..30246d2 100644
--- a/arch/arm/mach-tegra/board-trimslice.c
+++ b/arch/arm/mach-tegra/board-trimslice.c
@@ -34,6 +34,7 @@
 #include <asm/setup.h>
 
 #include <mach/iomap.h>
+#include <mach/pci-tegra.h>
 #include <mach/sdhci.h>
 
 #include "board.h"
@@ -145,14 +146,20 @@ static __initdata struct tegra_clk_init_table trimslice_clk_init_table[] = {
 	{ NULL,		NULL,		0,		0},
 };
 
-static int __init tegra_trimslice_pci_init(void)
+static struct tegra_pcie_pdata trimslice_pcie_pdata = {
+	.enable_ports = {
+		[0] = true,
+		[1] = true,
+	},
+};
+
+static int __init trimslice_pci_init(void)
 {
-	if (!machine_is_trimslice())
-		return 0;
+	tegra_pcie_device.dev.platform_data = &trimslice_pcie_pdata;
+	platform_device_register(&tegra_pcie_device);
 
-	return tegra_pcie_init(true, true);
+	return 0;
 }
-subsys_initcall(tegra_trimslice_pci_init);
 
 static void __init tegra_trimslice_init(void)
 {
@@ -167,6 +174,7 @@ static void __init tegra_trimslice_init(void)
 
 	trimslice_i2c_init();
 	trimslice_usb_init();
+	trimslice_pci_init();
 }
 
 MACHINE_START(TRIMSLICE, "trimslice")
diff --git a/arch/arm/mach-tegra/board.h b/arch/arm/mach-tegra/board.h
index f88e514..3a2a7e9 100644
--- a/arch/arm/mach-tegra/board.h
+++ b/arch/arm/mach-tegra/board.h
@@ -30,7 +30,6 @@ void __init tegra30_init_early(void);
 void __init tegra_map_common_io(void);
 void __init tegra_init_irq(void);
 void __init tegra_dt_init_irq(void);
-int __init tegra_pcie_init(bool init_port0, bool init_port1);
 
 void tegra_init_late(void);
 
@@ -56,4 +55,5 @@ static inline int harmony_pcie_init(void) { return 0; }
 void __init tegra_paz00_wifikill_init(void);
 
 extern struct sys_timer tegra_timer;
+
 #endif
diff --git a/arch/arm/mach-tegra/devices.c b/arch/arm/mach-tegra/devices.c
index 4529561..de4aef9 100644
--- a/arch/arm/mach-tegra/devices.c
+++ b/arch/arm/mach-tegra/devices.c
@@ -735,3 +735,28 @@ struct platform_device tegra_nand_device = {
 	.num_resources = ARRAY_SIZE(tegra_nand_resources),
 	.resource = tegra_nand_resources,
 };
+
+static struct resource tegra_pcie_resources[] = {
+	[0] = {
+		.start = TEGRA_PCIE_BASE,
+		.end = TEGRA_PCIE_BASE + TEGRA_PCIE_SIZE - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = TEGRA_PCIE_MMIO_BASE,
+		.end = TEGRA_PCIE_MMIO_BASE + TEGRA_PCIE_MMIO_SIZE - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[2] = {
+		.start = INT_PCIE_INTR,
+		.end = INT_PCIE_INTR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device tegra_pcie_device = {
+	.name = "tegra-pcie",
+	.id = -1,
+	.resource = tegra_pcie_resources,
+	.num_resources = ARRAY_SIZE(tegra_pcie_resources),
+};
diff --git a/arch/arm/mach-tegra/devices.h b/arch/arm/mach-tegra/devices.h
index f054d10..b2caed4 100644
--- a/arch/arm/mach-tegra/devices.h
+++ b/arch/arm/mach-tegra/devices.h
@@ -57,5 +57,6 @@ extern struct platform_device tegra_i2s_device1;
 extern struct platform_device tegra_i2s_device2;
 extern struct platform_device tegra_das_device;
 extern struct platform_device tegra_pwm_device;
+extern struct platform_device tegra_pcie_device;
 
 #endif
diff --git a/arch/arm/mach-tegra/include/mach/iomap.h b/arch/arm/mach-tegra/include/mach/iomap.h
index 3e80f3f..aee9d27 100644
--- a/arch/arm/mach-tegra/include/mach/iomap.h
+++ b/arch/arm/mach-tegra/include/mach/iomap.h
@@ -248,6 +248,12 @@
 #define TEGRA_CSITE_BASE		0x70040000
 #define TEGRA_CSITE_SIZE		SZ_256K
 
+#define TEGRA_PCIE_BASE			0x80000000
+#define TEGRA_PCIE_SIZE			SZ_4M
+
+#define TEGRA_PCIE_MMIO_BASE		0x80400000
+#define TEGRA_PCIE_MMIO_SIZE		SZ_64K
+
 #define TEGRA_USB_BASE			0xC5000000
 #define TEGRA_USB_SIZE			SZ_16K
 
diff --git a/arch/arm/mach-tegra/include/mach/pci-tegra.h b/arch/arm/mach-tegra/include/mach/pci-tegra.h
new file mode 100644
index 0000000..348a68a
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/pci-tegra.h
@@ -0,0 +1,29 @@
+/*
+ * arch/arm/mach-tegra/include/mach/tegra-pcie.h
+ *
+ * Copyright (C) 2012 Avionic Design GmbH
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MACH_TEGRA_PCIE_H
+#define __MACH_TEGRA_PCIE_H
+
+#include <linux/platform_device.h>
+
+#define TEGRA_PCIE_MAX_PORTS 2
+
+struct tegra_pcie_pdata {
+	int (*init)(struct platform_device *pdev);
+	int (*exit)(struct platform_device *pdev);
+	bool enable_ports[TEGRA_PCIE_MAX_PORTS];
+};
+
+#endif
diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c
index fcdf8bc..291d55d 100644
--- a/arch/arm/mach-tegra/pcie.c
+++ b/arch/arm/mach-tegra/pcie.c
@@ -27,7 +27,9 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
+#include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/clk.h>
@@ -40,8 +42,8 @@
 #include <mach/iomap.h>
 #include <mach/clk.h>
 #include <mach/powergate.h>
+#include <mach/pci-tegra.h>
 
-#include "board.h"
 #include "pmc.h"
 
 /* register definitions */
@@ -161,17 +163,12 @@
  * 0x90000000 - 0x9fffffff - non-prefetchable memory
  * 0xa0000000 - 0xbfffffff - prefetchable memory
  */
-#define TEGRA_PCIE_BASE		0x80000000
-
 #define PCIE_REGS_SZ		SZ_16K
 #define PCIE_CFG_OFF		PCIE_REGS_SZ
 #define PCIE_CFG_SZ		SZ_1M
 #define PCIE_EXT_CFG_OFF	(PCIE_CFG_SZ + PCIE_CFG_OFF)
 #define PCIE_EXT_CFG_SZ		SZ_1M
-#define PCIE_IOMAP_SZ		(PCIE_REGS_SZ + PCIE_CFG_SZ + PCIE_EXT_CFG_SZ)
 
-#define MMIO_BASE		(TEGRA_PCIE_BASE + SZ_4M)
-#define MMIO_SIZE		SZ_64K
 #define MEM_BASE_0		(TEGRA_PCIE_BASE + SZ_256M)
 #define MEM_SIZE_0		SZ_128M
 #define MEM_BASE_1		(MEM_BASE_0 + MEM_SIZE_0)
@@ -201,11 +198,14 @@ struct tegra_pcie_port {
 };
 
 struct tegra_pcie_info {
-	struct tegra_pcie_port	port[2];
+	struct device		*dev;
+
+	struct tegra_pcie_port	port[TEGRA_PCIE_MAX_PORTS];
 	int			num_ports;
 
 	void __iomem		*regs;
-	struct resource		res_mmio;
+	void __iomem		*mmio;
+	int			irq;
 
 	struct clk		*pex_clk;
 	struct clk		*afi_clk;
@@ -213,55 +213,53 @@ struct tegra_pcie_info {
 	struct clk		*pll_e;
 };
 
-static struct tegra_pcie_info tegra_pcie = {
-	.res_mmio = {
-		.name = "PCI IO",
-		.start = MMIO_BASE,
-		.end = MMIO_BASE + MMIO_SIZE - 1,
-		.flags = IORESOURCE_MEM,
-	},
-};
+static inline struct tegra_pcie_info *sys_to_pcie(struct pci_sys_data *sys)
+{
+	return sys->private_data;
+}
 
 void __iomem *tegra_pcie_io_base;
 EXPORT_SYMBOL(tegra_pcie_io_base);
 
-static inline void afi_writel(u32 value, unsigned long offset)
+static inline void afi_writel(struct tegra_pcie_info *pcie, u32 value, unsigned long offset)
 {
-	writel(value, offset + AFI_OFFSET + tegra_pcie.regs);
+	writel(value, offset + AFI_OFFSET + pcie->regs);
 }
 
-static inline u32 afi_readl(unsigned long offset)
+static inline u32 afi_readl(struct tegra_pcie_info *pcie, unsigned long offset)
 {
-	return readl(offset + AFI_OFFSET + tegra_pcie.regs);
+	return readl(offset + AFI_OFFSET + pcie->regs);
 }
 
-static inline void pads_writel(u32 value, unsigned long offset)
+static inline void pads_writel(struct tegra_pcie_info *pcie, u32 value, unsigned long offset)
 {
-	writel(value, offset + PADS_OFFSET + tegra_pcie.regs);
+	writel(value, offset + PADS_OFFSET + pcie->regs);
 }
 
-static inline u32 pads_readl(unsigned long offset)
+static inline u32 pads_readl(struct tegra_pcie_info *pcie, unsigned long offset)
 {
-	return readl(offset + PADS_OFFSET + tegra_pcie.regs);
+	return readl(offset + PADS_OFFSET + pcie->regs);
 }
 
-static struct tegra_pcie_port *bus_to_port(int bus)
+static struct tegra_pcie_port *bus_to_port(struct pci_bus *bus)
 {
+	struct tegra_pcie_info *pcie = sys_to_pcie(bus->sysdata);
 	int i;
 
-	for (i = tegra_pcie.num_ports - 1; i >= 0; i--) {
-		int rbus = tegra_pcie.port[i].root_bus_nr;
-		if (rbus != -1 && rbus == bus)
+	for (i = pcie->num_ports - 1; i >= 0; i--) {
+		int rbus = pcie->port[i].root_bus_nr;
+		if (rbus != -1 && rbus == bus->number)
 			break;
 	}
 
-	return i >= 0 ? tegra_pcie.port + i : NULL;
+	return i >= 0 ? pcie->port + i : NULL;
 }
 
 static int tegra_pcie_read_conf(struct pci_bus *bus, unsigned int devfn,
 				int where, int size, u32 *val)
 {
-	struct tegra_pcie_port *pp = bus_to_port(bus->number);
+	struct tegra_pcie_info *pcie = sys_to_pcie(bus->sysdata);
+	struct tegra_pcie_port *pp = bus_to_port(bus);
 	void __iomem *addr;
 
 	if (pp) {
@@ -272,10 +270,10 @@ static int tegra_pcie_read_conf(struct pci_bus *bus, unsigned int devfn,
 
 		addr = pp->base + (where & ~0x3);
 	} else {
-		addr = tegra_pcie.regs + (PCIE_CONF_BUS(bus->number) +
-					  PCIE_CONF_DEV(PCI_SLOT(devfn)) +
-					  PCIE_CONF_FUNC(PCI_FUNC(devfn)) +
-					  PCIE_CONF_REG(where));
+		addr = pcie->regs + (PCIE_CONF_BUS(bus->number) +
+				     PCIE_CONF_DEV(PCI_SLOT(devfn)) +
+				     PCIE_CONF_FUNC(PCI_FUNC(devfn)) +
+				     PCIE_CONF_REG(where));
 	}
 
 	*val = readl(addr);
@@ -291,7 +289,8 @@ static int tegra_pcie_read_conf(struct pci_bus *bus, unsigned int devfn,
 static int tegra_pcie_write_conf(struct pci_bus *bus, unsigned int devfn,
 				 int where, int size, u32 val)
 {
-	struct tegra_pcie_port *pp = bus_to_port(bus->number);
+	struct tegra_pcie_info *pcie = sys_to_pcie(bus->sysdata);
+	struct tegra_pcie_port *pp = bus_to_port(bus);
 	void __iomem *addr;
 
 	u32 mask;
@@ -303,10 +302,10 @@ static int tegra_pcie_write_conf(struct pci_bus *bus, unsigned int devfn,
 
 		addr = pp->base + (where & ~0x3);
 	} else {
-		addr = tegra_pcie.regs + (PCIE_CONF_BUS(bus->number) +
-					  PCIE_CONF_DEV(PCI_SLOT(devfn)) +
-					  PCIE_CONF_FUNC(PCI_FUNC(devfn)) +
-					  PCIE_CONF_REG(where));
+		addr = pcie->regs + (PCIE_CONF_BUS(bus->number) +
+				     PCIE_CONF_DEV(PCI_SLOT(devfn)) +
+				     PCIE_CONF_FUNC(PCI_FUNC(devfn)) +
+				     PCIE_CONF_REG(where));
 	}
 
 	if (size == 4) {
@@ -373,12 +372,13 @@ DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_relax_enable);
 
 static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
 {
+	struct tegra_pcie_info *pcie = sys_to_pcie(sys);
 	struct tegra_pcie_port *pp;
 
-	if (nr >= tegra_pcie.num_ports)
+	if (nr >= pcie->num_ports)
 		return 0;
 
-	pp = tegra_pcie.port + nr;
+	pp = pcie->port + nr;
 	pp->root_bus_nr = sys->busnr;
 
 	/*
@@ -441,34 +441,29 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
 	return 1;
 }
 
-static int tegra_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+static int tegra_pcie_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
 {
-	return INT_PCIE_INTR;
+	struct tegra_pcie_info *pcie = sys_to_pcie(pdev->bus->sysdata);
+
+	return pcie->irq;
 }
 
-static struct pci_bus __init *tegra_pcie_scan_bus(int nr,
-						  struct pci_sys_data *sys)
+static struct pci_bus __devinit *tegra_pcie_scan_bus(int nr,
+						     struct pci_sys_data *sys)
 {
+	struct tegra_pcie_info *pcie = sys_to_pcie(sys);
 	struct tegra_pcie_port *pp;
 
-	if (nr >= tegra_pcie.num_ports)
+	if (nr >= pcie->num_ports)
 		return NULL;
 
-	pp = tegra_pcie.port + nr;
+	pp = pcie->port + nr;
 	pp->root_bus_nr = sys->busnr;
 
 	return pci_scan_root_bus(NULL, sys->busnr, &tegra_pcie_ops, sys,
 				 &sys->resources);
 }
 
-static struct hw_pci tegra_pcie_hw __initdata = {
-	.nr_controllers	= 2,
-	.setup		= tegra_pcie_setup,
-	.scan		= tegra_pcie_scan_bus,
-	.map_irq	= tegra_pcie_map_irq,
-};
-
-
 static irqreturn_t tegra_pcie_isr(int irq, void *arg)
 {
 	const char *err_msg[] = {
@@ -482,12 +477,12 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg)
 		"AXI response decoding error",
 		"Transcation timeout",
 	};
-
+	struct tegra_pcie_info *pcie = arg;
 	u32 code, signature;
 
-	code = afi_readl(AFI_INTR_CODE) & AFI_INTR_CODE_MASK;
-	signature = afi_readl(AFI_INTR_SIGNATURE);
-	afi_writel(0, AFI_INTR_CODE);
+	code = afi_readl(pcie, AFI_INTR_CODE) & AFI_INTR_CODE_MASK;
+	signature = afi_readl(pcie, AFI_INTR_SIGNATURE);
+	afi_writel(pcie, 0, AFI_INTR_CODE);
 
 	if (code == AFI_INTR_LEGACY)
 		return IRQ_NONE;
@@ -500,14 +495,16 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg)
 	 * happen a lot during enumeration
 	 */
 	if (code == AFI_INTR_MASTER_ABORT)
-		pr_debug("PCIE: %s, signature: %08x\n", err_msg[code], signature);
+		dev_dbg(pcie->dev, "%s, signature: %08x\n", err_msg[code],
+			signature);
 	else
-		pr_err("PCIE: %s, signature: %08x\n", err_msg[code], signature);
+		dev_err(pcie->dev, "%s, signature: %08x\n", err_msg[code],
+			signature);
 
 	return IRQ_HANDLED;
 }
 
-static void tegra_pcie_setup_translations(void)
+static void tegra_pcie_setup_translations(struct tegra_pcie_info *pcie)
 {
 	u32 fpci_bar;
 	u32 size;
@@ -517,120 +514,120 @@ static void tegra_pcie_setup_translations(void)
 	fpci_bar = ((u32)0xfdff << 16);
 	size = PCIE_CFG_SZ;
 	axi_address = TEGRA_PCIE_BASE + PCIE_CFG_OFF;
-	afi_writel(axi_address, AFI_AXI_BAR0_START);
-	afi_writel(size >> 12, AFI_AXI_BAR0_SZ);
-	afi_writel(fpci_bar, AFI_FPCI_BAR0);
+	afi_writel(pcie, axi_address, AFI_AXI_BAR0_START);
+	afi_writel(pcie, size >> 12, AFI_AXI_BAR0_SZ);
+	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR0);
 
 	/* Bar 1: extended config Bar */
 	fpci_bar = ((u32)0xfe1 << 20);
 	size = PCIE_EXT_CFG_SZ;
 	axi_address = TEGRA_PCIE_BASE + PCIE_EXT_CFG_OFF;
-	afi_writel(axi_address, AFI_AXI_BAR1_START);
-	afi_writel(size >> 12, AFI_AXI_BAR1_SZ);
-	afi_writel(fpci_bar, AFI_FPCI_BAR1);
+	afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
+	afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
+	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
 
 	/* Bar 2: downstream IO bar */
 	fpci_bar = ((__u32)0xfdfc << 16);
-	size = MMIO_SIZE;
-	axi_address = MMIO_BASE;
-	afi_writel(axi_address, AFI_AXI_BAR2_START);
-	afi_writel(size >> 12, AFI_AXI_BAR2_SZ);
-	afi_writel(fpci_bar, AFI_FPCI_BAR2);
+	size = TEGRA_PCIE_MMIO_SIZE;
+	axi_address = TEGRA_PCIE_MMIO_BASE;
+	afi_writel(pcie, axi_address, AFI_AXI_BAR2_START);
+	afi_writel(pcie, size >> 12, AFI_AXI_BAR2_SZ);
+	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR2);
 
 	/* Bar 3: prefetchable memory BAR */
 	fpci_bar = (((PREFETCH_MEM_BASE_0 >> 12) & 0x0fffffff) << 4) | 0x1;
 	size =  PREFETCH_MEM_SIZE_0 +  PREFETCH_MEM_SIZE_1;
 	axi_address = PREFETCH_MEM_BASE_0;
-	afi_writel(axi_address, AFI_AXI_BAR3_START);
-	afi_writel(size >> 12, AFI_AXI_BAR3_SZ);
-	afi_writel(fpci_bar, AFI_FPCI_BAR3);
+	afi_writel(pcie, axi_address, AFI_AXI_BAR3_START);
+	afi_writel(pcie, size >> 12, AFI_AXI_BAR3_SZ);
+	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR3);
 
 	/* Bar 4: non prefetchable memory BAR */
 	fpci_bar = (((MEM_BASE_0 >> 12)	& 0x0FFFFFFF) << 4) | 0x1;
 	size = MEM_SIZE_0 + MEM_SIZE_1;
 	axi_address = MEM_BASE_0;
-	afi_writel(axi_address, AFI_AXI_BAR4_START);
-	afi_writel(size >> 12, AFI_AXI_BAR4_SZ);
-	afi_writel(fpci_bar, AFI_FPCI_BAR4);
+	afi_writel(pcie, axi_address, AFI_AXI_BAR4_START);
+	afi_writel(pcie, size >> 12, AFI_AXI_BAR4_SZ);
+	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR4);
 
 	/* Bar 5: NULL out the remaining BAR as it is not used */
 	fpci_bar = 0;
 	size = 0;
 	axi_address = 0;
-	afi_writel(axi_address, AFI_AXI_BAR5_START);
-	afi_writel(size >> 12, AFI_AXI_BAR5_SZ);
-	afi_writel(fpci_bar, AFI_FPCI_BAR5);
+	afi_writel(pcie, axi_address, AFI_AXI_BAR5_START);
+	afi_writel(pcie, size >> 12, AFI_AXI_BAR5_SZ);
+	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR5);
 
 	/* map all upstream transactions as uncached */
-	afi_writel(PHYS_OFFSET, AFI_CACHE_BAR0_ST);
-	afi_writel(0, AFI_CACHE_BAR0_SZ);
-	afi_writel(0, AFI_CACHE_BAR1_ST);
-	afi_writel(0, AFI_CACHE_BAR1_SZ);
+	afi_writel(pcie, PHYS_OFFSET, AFI_CACHE_BAR0_ST);
+	afi_writel(pcie, 0, AFI_CACHE_BAR0_SZ);
+	afi_writel(pcie, 0, AFI_CACHE_BAR1_ST);
+	afi_writel(pcie, 0, AFI_CACHE_BAR1_SZ);
 
 	/* No MSI */
-	afi_writel(0, AFI_MSI_FPCI_BAR_ST);
-	afi_writel(0, AFI_MSI_BAR_SZ);
-	afi_writel(0, AFI_MSI_AXI_BAR_ST);
-	afi_writel(0, AFI_MSI_BAR_SZ);
+	afi_writel(pcie, 0, AFI_MSI_FPCI_BAR_ST);
+	afi_writel(pcie, 0, AFI_MSI_BAR_SZ);
+	afi_writel(pcie, 0, AFI_MSI_AXI_BAR_ST);
+	afi_writel(pcie, 0, AFI_MSI_BAR_SZ);
 }
 
-static int tegra_pcie_enable_controller(void)
+static int tegra_pcie_enable_controller(struct tegra_pcie_info *pcie)
 {
 	u32 val, reg;
 	int i, timeout;
 
 	/* Enable slot clock and pulse the reset signals */
 	for (i = 0, reg = AFI_PEX0_CTRL; i < 2; i++, reg += 0x8) {
-		val = afi_readl(reg) |  AFI_PEX_CTRL_REFCLK_EN;
-		afi_writel(val, reg);
+		val = afi_readl(pcie, reg) |  AFI_PEX_CTRL_REFCLK_EN;
+		afi_writel(pcie, val, reg);
 		val &= ~AFI_PEX_CTRL_RST;
-		afi_writel(val, reg);
+		afi_writel(pcie, val, reg);
 
-		val = afi_readl(reg) | AFI_PEX_CTRL_RST;
-		afi_writel(val, reg);
+		val = afi_readl(pcie, reg) | AFI_PEX_CTRL_RST;
+		afi_writel(pcie, val, reg);
 	}
 
 	/* Enable dual controller and both ports */
-	val = afi_readl(AFI_PCIE_CONFIG);
+	val = afi_readl(pcie, AFI_PCIE_CONFIG);
 	val &= ~(AFI_PCIE_CONFIG_PCIEC0_DISABLE_DEVICE |
 		 AFI_PCIE_CONFIG_PCIEC1_DISABLE_DEVICE |
 		 AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_MASK);
 	val |= AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_DUAL;
-	afi_writel(val, AFI_PCIE_CONFIG);
+	afi_writel(pcie, val, AFI_PCIE_CONFIG);
 
-	val = afi_readl(AFI_FUSE) & ~AFI_FUSE_PCIE_T0_GEN2_DIS;
-	afi_writel(val, AFI_FUSE);
+	val = afi_readl(pcie, AFI_FUSE) & ~AFI_FUSE_PCIE_T0_GEN2_DIS;
+	afi_writel(pcie, val, AFI_FUSE);
 
 	/* Initialze internal PHY, enable up to 16 PCIE lanes */
-	pads_writel(0x0, PADS_CTL_SEL);
+	pads_writel(pcie, 0x0, PADS_CTL_SEL);
 
 	/* override IDDQ to 1 on all 4 lanes */
-	val = pads_readl(PADS_CTL) | PADS_CTL_IDDQ_1L;
-	pads_writel(val, PADS_CTL);
+	val = pads_readl(pcie, PADS_CTL) | PADS_CTL_IDDQ_1L;
+	pads_writel(pcie, val, PADS_CTL);
 
 	/*
 	 * set up PHY PLL inputs select PLLE output as refclock,
 	 * set TX ref sel to div10 (not div5)
 	 */
-	val = pads_readl(PADS_PLL_CTL);
+	val = pads_readl(pcie, PADS_PLL_CTL);
 	val &= ~(PADS_PLL_CTL_REFCLK_MASK | PADS_PLL_CTL_TXCLKREF_MASK);
 	val |= (PADS_PLL_CTL_REFCLK_INTERNAL_CML | PADS_PLL_CTL_TXCLKREF_DIV10);
-	pads_writel(val, PADS_PLL_CTL);
+	pads_writel(pcie, val, PADS_PLL_CTL);
 
 	/* take PLL out of reset  */
-	val = pads_readl(PADS_PLL_CTL) | PADS_PLL_CTL_RST_B4SM;
-	pads_writel(val, PADS_PLL_CTL);
+	val = pads_readl(pcie, PADS_PLL_CTL) | PADS_PLL_CTL_RST_B4SM;
+	pads_writel(pcie, val, PADS_PLL_CTL);
 
 	/*
 	 * Hack, set the clock voltage to the DEFAULT provided by hw folks.
 	 * This doesn't exist in the documentation
 	 */
-	pads_writel(0xfa5cfa5c, 0xc8);
+	pads_writel(pcie, 0xfa5cfa5c, 0xc8);
 
 	/* Wait for the PLL to lock */
 	timeout = 300;
 	do {
-		val = pads_readl(PADS_PLL_CTL);
+		val = pads_readl(pcie, PADS_PLL_CTL);
 		usleep_range(1000, 1000);
 		if (--timeout == 0) {
 			pr_err("Tegra PCIe error: timeout waiting for PLL\n");
@@ -639,188 +636,237 @@ static int tegra_pcie_enable_controller(void)
 	} while (!(val & PADS_PLL_CTL_LOCKDET));
 
 	/* turn off IDDQ override */
-	val = pads_readl(PADS_CTL) & ~PADS_CTL_IDDQ_1L;
-	pads_writel(val, PADS_CTL);
+	val = pads_readl(pcie, PADS_CTL) & ~PADS_CTL_IDDQ_1L;
+	pads_writel(pcie, val, PADS_CTL);
 
 	/* enable TX/RX data */
-	val = pads_readl(PADS_CTL);
+	val = pads_readl(pcie, PADS_CTL);
 	val |= (PADS_CTL_TX_DATA_EN_1L | PADS_CTL_RX_DATA_EN_1L);
-	pads_writel(val, PADS_CTL);
+	pads_writel(pcie, val, PADS_CTL);
 
 	/* Take the PCIe interface module out of reset */
-	tegra_periph_reset_deassert(tegra_pcie.pcie_xclk);
+	tegra_periph_reset_deassert(pcie->pcie_xclk);
 
 	/* Finally enable PCIe */
-	val = afi_readl(AFI_CONFIGURATION) | AFI_CONFIGURATION_EN_FPCI;
-	afi_writel(val, AFI_CONFIGURATION);
+	val = afi_readl(pcie, AFI_CONFIGURATION) | AFI_CONFIGURATION_EN_FPCI;
+	afi_writel(pcie, val, AFI_CONFIGURATION);
 
 	val = (AFI_INTR_EN_INI_SLVERR | AFI_INTR_EN_INI_DECERR |
 	       AFI_INTR_EN_TGT_SLVERR | AFI_INTR_EN_TGT_DECERR |
 	       AFI_INTR_EN_TGT_WRERR | AFI_INTR_EN_DFPCI_DECERR);
-	afi_writel(val, AFI_AFI_INTR_ENABLE);
-	afi_writel(0xffffffff, AFI_SM_INTR_ENABLE);
+	afi_writel(pcie, val, AFI_AFI_INTR_ENABLE);
+	afi_writel(pcie, 0xffffffff, AFI_SM_INTR_ENABLE);
 
 	/* FIXME: No MSI for now, only INT */
-	afi_writel(AFI_INTR_MASK_INT_MASK, AFI_INTR_MASK);
+	afi_writel(pcie, AFI_INTR_MASK_INT_MASK, AFI_INTR_MASK);
 
 	/* Disable all execptions */
-	afi_writel(0, AFI_FPCI_ERROR_MASKS);
+	afi_writel(pcie, 0, AFI_FPCI_ERROR_MASKS);
 
 	return 0;
 }
 
-static void tegra_pcie_power_off(void)
+static void tegra_pcie_power_off(struct tegra_pcie_info *pcie)
 {
-	tegra_periph_reset_assert(tegra_pcie.pcie_xclk);
-	tegra_periph_reset_assert(tegra_pcie.afi_clk);
-	tegra_periph_reset_assert(tegra_pcie.pex_clk);
+	tegra_periph_reset_assert(pcie->pcie_xclk);
+	tegra_periph_reset_assert(pcie->afi_clk);
+	tegra_periph_reset_assert(pcie->pex_clk);
 
 	tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
 	tegra_pmc_pcie_xclk_clamp(true);
 }
 
-static int tegra_pcie_power_regate(void)
+static int tegra_pcie_power_regate(struct tegra_pcie_info *pcie)
 {
 	int err;
 
-	tegra_pcie_power_off();
+	tegra_pcie_power_off(pcie);
 
 	tegra_pmc_pcie_xclk_clamp(true);
 
-	tegra_periph_reset_assert(tegra_pcie.pcie_xclk);
-	tegra_periph_reset_assert(tegra_pcie.afi_clk);
+	tegra_periph_reset_assert(pcie->pcie_xclk);
+	tegra_periph_reset_assert(pcie->afi_clk);
 
 	err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_PCIE,
-						tegra_pcie.pex_clk);
+						pcie->pex_clk);
 	if (err) {
-		pr_err("PCIE: powerup sequence failed: %d\n", err);
+		dev_err(pcie->dev, "powerup sequence failed: %d\n", err);
 		return err;
 	}
 
-	tegra_periph_reset_deassert(tegra_pcie.afi_clk);
+	tegra_periph_reset_deassert(pcie->afi_clk);
 
 	tegra_pmc_pcie_xclk_clamp(false);
 
-	clk_enable(tegra_pcie.afi_clk);
-	clk_enable(tegra_pcie.pex_clk);
-	return clk_enable(tegra_pcie.pll_e);
+	clk_enable(pcie->afi_clk);
+	clk_enable(pcie->pex_clk);
+	return clk_enable(pcie->pll_e);
 }
 
-static int tegra_pcie_clocks_get(void)
+static int tegra_pcie_clocks_get(struct tegra_pcie_info *pcie)
 {
 	int err;
 
-	tegra_pcie.pex_clk = clk_get(NULL, "pex");
-	if (IS_ERR(tegra_pcie.pex_clk))
-		return PTR_ERR(tegra_pcie.pex_clk);
+	pcie->pex_clk = clk_get(NULL, "pex");
+	if (IS_ERR(pcie->pex_clk))
+		return PTR_ERR(pcie->pex_clk);
 
-	tegra_pcie.afi_clk = clk_get(NULL, "afi");
-	if (IS_ERR(tegra_pcie.afi_clk)) {
-		err = PTR_ERR(tegra_pcie.afi_clk);
+	pcie->afi_clk = clk_get(NULL, "afi");
+	if (IS_ERR(pcie->afi_clk)) {
+		err = PTR_ERR(pcie->afi_clk);
 		goto err_afi_clk;
 	}
 
-	tegra_pcie.pcie_xclk = clk_get(NULL, "pcie_xclk");
-	if (IS_ERR(tegra_pcie.pcie_xclk)) {
-		err =  PTR_ERR(tegra_pcie.pcie_xclk);
+	pcie->pcie_xclk = clk_get(NULL, "pcie_xclk");
+	if (IS_ERR(pcie->pcie_xclk)) {
+		err = PTR_ERR(pcie->pcie_xclk);
 		goto err_pcie_xclk;
 	}
 
-	tegra_pcie.pll_e = clk_get_sys(NULL, "pll_e");
-	if (IS_ERR(tegra_pcie.pll_e)) {
-		err = PTR_ERR(tegra_pcie.pll_e);
+	pcie->pll_e = clk_get_sys(NULL, "pll_e");
+	if (IS_ERR(pcie->pll_e)) {
+		err = PTR_ERR(pcie->pll_e);
 		goto err_pll_e;
 	}
 
 	return 0;
 
 err_pll_e:
-	clk_put(tegra_pcie.pcie_xclk);
+	clk_put(pcie->pcie_xclk);
 err_pcie_xclk:
-	clk_put(tegra_pcie.afi_clk);
+	clk_put(pcie->afi_clk);
 err_afi_clk:
-	clk_put(tegra_pcie.pex_clk);
+	clk_put(pcie->pex_clk);
 
 	return err;
 }
 
-static void tegra_pcie_clocks_put(void)
+static void tegra_pcie_clocks_put(struct tegra_pcie_info *pcie)
 {
-	clk_put(tegra_pcie.pll_e);
-	clk_put(tegra_pcie.pcie_xclk);
-	clk_put(tegra_pcie.afi_clk);
-	clk_put(tegra_pcie.pex_clk);
+	clk_put(pcie->pll_e);
+	clk_put(pcie->pcie_xclk);
+	clk_put(pcie->afi_clk);
+	clk_put(pcie->pex_clk);
 }
 
-static int __init tegra_pcie_get_resources(void)
+static int __devinit tegra_pcie_get_resources(struct platform_device *pdev)
 {
-	struct resource *res_mmio = &tegra_pcie.res_mmio;
+	struct tegra_pcie_info *pcie = platform_get_drvdata(pdev);
+	struct resource *regs;
+	struct resource *mmio;
 	int err;
 
-	err = tegra_pcie_clocks_get();
+	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	mmio = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+
+	if (!regs || !mmio) {
+		dev_err(&pdev->dev, "failed to get I/O resources\n");
+		return -ENXIO;
+	}
+
+	err = tegra_pcie_clocks_get(pcie);
 	if (err) {
-		pr_err("PCIE: failed to get clocks: %d\n", err);
+		dev_err(&pdev->dev, "failed to get clocks: %d\n", err);
 		return err;
 	}
 
-	err = tegra_pcie_power_regate();
+	err = tegra_pcie_power_regate(pcie);
 	if (err) {
-		pr_err("PCIE: failed to power up: %d\n", err);
+		dev_err(&pdev->dev, "failed to power up: %d\n", err);
 		goto err_pwr_on;
 	}
 
-	tegra_pcie.regs = ioremap_nocache(TEGRA_PCIE_BASE, PCIE_IOMAP_SZ);
-	if (tegra_pcie.regs == NULL) {
-		pr_err("PCIE: Failed to map PCI/AFI registers\n");
+	regs = request_mem_region(regs->start, resource_size(regs), "PCI/AFI");
+	if (regs == NULL) {
+		dev_err(&pdev->dev, "failed to request PCI/AFI region: %d\n", err);
+		goto err_req_reg;
+	}
+
+	pcie->regs = ioremap_nocache(regs->start, resource_size(regs));
+	if (pcie->regs == NULL) {
+		dev_err(&pdev->dev, "failed to map PCI/AFI registers\n");
 		err = -ENOMEM;
 		goto err_map_reg;
 	}
 
-	err = request_resource(&iomem_resource, res_mmio);
-	if (err) {
-		pr_err("PCIE: Failed to request resources: %d\n", err);
+	mmio = request_mem_region(mmio->start, resource_size(mmio), "PCI I/O");
+	if (mmio == NULL) {
+		dev_err(&pdev->dev, "failed to request PCI I/O region: %d\n", err);
 		goto err_req_io;
 	}
 
-	tegra_pcie_io_base = ioremap_nocache(res_mmio->start,
-					     resource_size(res_mmio));
-	if (tegra_pcie_io_base == NULL) {
-		pr_err("PCIE: Failed to map IO\n");
+	pcie->mmio = ioremap_nocache(mmio->start, resource_size(mmio));
+	if (pcie->mmio == NULL) {
+		dev_err(&pdev->dev, "failed to map PCI I/O region\n");
 		err = -ENOMEM;
 		goto err_map_io;
 	}
 
-	err = request_irq(INT_PCIE_INTR, tegra_pcie_isr,
-			  IRQF_SHARED, "PCIE", &tegra_pcie);
+	tegra_pcie_io_base = pcie->mmio;
+
+	err = platform_get_irq(pdev, 0);
+	if (err < 0) {
+		dev_err(&pdev->dev, "failed to get IRQ: %d\n", err);
+		goto err_irq;
+	}
+
+	pcie->irq = err;
+
+	err = request_irq(pcie->irq, tegra_pcie_isr, IRQF_SHARED, "PCIE",
+			  pcie);
 	if (err) {
-		pr_err("PCIE: Failed to register IRQ: %d\n", err);
+		dev_err(&pdev->dev, "failed to register IRQ: %d\n", err);
 		goto err_irq;
 	}
-	set_irq_flags(INT_PCIE_INTR, IRQF_VALID);
 
 	return 0;
 
 err_irq:
-	iounmap(tegra_pcie_io_base);
+	iounmap(pcie->mmio);
 err_map_io:
-	release_resource(&tegra_pcie.res_mmio);
+	release_resource(mmio);
 err_req_io:
-	iounmap(tegra_pcie.regs);
+	iounmap(pcie->regs);
 err_map_reg:
-	tegra_pcie_power_off();
+	release_resource(regs);
+err_req_reg:
+	tegra_pcie_power_off(pcie);
 err_pwr_on:
-	tegra_pcie_clocks_put();
+	tegra_pcie_clocks_put(pcie);
 
 	return err;
 }
 
+static int tegra_pcie_put_resources(struct platform_device *pdev)
+{
+	struct tegra_pcie_info *pcie = platform_get_drvdata(pdev);
+	struct resource *regs;
+	struct resource *mmio;
+
+	free_irq(pcie->irq, pcie);
+
+	iounmap(pcie->mmio);
+	mmio = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	release_resource(mmio);
+
+	iounmap(pcie->regs);
+	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	release_resource(regs);
+
+	tegra_pcie_power_off(pcie);
+	tegra_pcie_clocks_put(pcie);
+
+	return 0;
+}
+
 /*
  * FIXME: If there are no PCIe cards attached, then calling this function
  * can result in the increase of the bootup time as there are big timeout
  * loops.
  */
 #define TEGRA_PCIE_LINKUP_TIMEOUT	200	/* up to 1.2 seconds */
-static bool tegra_pcie_check_link(struct tegra_pcie_port *pp, int idx,
+static bool tegra_pcie_check_link(struct tegra_pcie_info *pcie,
+				  struct tegra_pcie_port *pp, int idx,
 				  u32 reset_reg)
 {
 	u32 reg;
@@ -840,7 +886,7 @@ static bool tegra_pcie_check_link(struct tegra_pcie_port *pp, int idx,
 		}
 
 		if (!timeout)  {
-			pr_err("PCIE: port %d: link down, retrying\n", idx);
+			dev_err(pcie->dev, "port %d: link down, retrying\n", idx);
 			goto retry;
 		}
 
@@ -857,11 +903,11 @@ static bool tegra_pcie_check_link(struct tegra_pcie_port *pp, int idx,
 
 retry:
 		/* Pulse the PEX reset */
-		reg = afi_readl(reset_reg) | AFI_PEX_CTRL_RST;
-		afi_writel(reg, reset_reg);
+		reg = afi_readl(pcie, reset_reg) | AFI_PEX_CTRL_RST;
+		afi_writel(pcie, reg, reset_reg);
 		mdelay(1);
-		reg = afi_readl(reset_reg) & ~AFI_PEX_CTRL_RST;
-		afi_writel(reg, reset_reg);
+		reg = afi_readl(pcie, reset_reg) & ~AFI_PEX_CTRL_RST;
+		afi_writel(pcie, reg, reset_reg);
 
 		retries--;
 	} while (retries);
@@ -869,55 +915,117 @@ retry:
 	return false;
 }
 
-static void __init tegra_pcie_add_port(int index, u32 offset, u32 reset_reg)
+static void __devinit tegra_pcie_add_port(struct tegra_pcie_info *pcie,
+					  int index, u32 offset,
+					  u32 reset_reg)
 {
 	struct tegra_pcie_port *pp;
 
-	pp = tegra_pcie.port + tegra_pcie.num_ports;
+	pp = pcie->port + pcie->num_ports;
 
 	pp->index = -1;
-	pp->base = tegra_pcie.regs + offset;
-	pp->link_up = tegra_pcie_check_link(pp, index, reset_reg);
+	pp->base = pcie->regs + offset;
+	pp->link_up = tegra_pcie_check_link(pcie, pp, index, reset_reg);
 
 	if (!pp->link_up) {
 		pp->base = NULL;
-		printk(KERN_INFO "PCIE: port %d: link down, ignoring\n", index);
+		dev_info(pcie->dev, "port %d: link down, ignoring\n", index);
 		return;
 	}
 
-	tegra_pcie.num_ports++;
+	pcie->num_ports++;
 	pp->index = index;
 	pp->root_bus_nr = -1;
 	memset(pp->res, 0, sizeof(pp->res));
 }
 
-int __init tegra_pcie_init(bool init_port0, bool init_port1)
+static int __devinit tegra_pcie_probe(struct platform_device *pdev)
 {
+	struct tegra_pcie_pdata *pdata = pdev->dev.platform_data;
+	void *private_data[TEGRA_PCIE_MAX_PORTS];
+	struct tegra_pcie_info *pcie;
+	struct hw_pci hw;
 	int err;
 
-	if (!(init_port0 || init_port1))
+	if (!pdata->enable_ports[0] && !pdata->enable_ports[1])
 		return -ENODEV;
 
+	pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL);
+	if (!pcie)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, pcie);
+	pcie->dev = &pdev->dev;
+
 	pcibios_min_mem = 0;
 
-	err = tegra_pcie_get_resources();
-	if (err)
+	err = tegra_pcie_get_resources(pdev);
+	if (err < 0) {
+		dev_err(&pdev->dev, "failed to request resources: %d\n", err);
 		return err;
+	}
+
+	if (pdata->init) {
+		err = pdata->init(pdev);
+		if (err < 0) {
+			tegra_pcie_put_resources(pdev);
+			return err;
+		}
+	}
 
-	err = tegra_pcie_enable_controller();
+	err = tegra_pcie_enable_controller(pcie);
 	if (err)
 		return err;
 
 	/* setup the AFI address translations */
-	tegra_pcie_setup_translations();
+	tegra_pcie_setup_translations(pcie);
 
-	if (init_port0)
-		tegra_pcie_add_port(0, RP0_OFFSET, AFI_PEX0_CTRL);
+	if (pdata->enable_ports[0]) {
+		tegra_pcie_add_port(pcie, 0, RP0_OFFSET, AFI_PEX0_CTRL);
+		private_data[0] = pcie;
+	}
+
+	if (pdata->enable_ports[1]) {
+		tegra_pcie_add_port(pcie, 1, RP1_OFFSET, AFI_PEX1_CTRL);
+		private_data[1] = pcie;
+	}
 
-	if (init_port1)
-		tegra_pcie_add_port(1, RP1_OFFSET, AFI_PEX1_CTRL);
+	memset(&hw, 0, sizeof(hw));
+	hw.nr_controllers = 2;
+	hw.private_data = private_data;
+	hw.setup = tegra_pcie_setup;
+	hw.scan = tegra_pcie_scan_bus;
+	hw.map_irq = tegra_pcie_map_irq;
 
-	pci_common_init(&tegra_pcie_hw);
+	pci_common_init(&hw);
 
 	return 0;
 }
+
+static int __devexit tegra_pcie_remove(struct platform_device *pdev)
+{
+	struct tegra_pcie_pdata *pdata = pdev->dev.platform_data;
+	int err;
+
+	err = tegra_pcie_put_resources(pdev);
+	if (err < 0)
+		return err;
+
+	if (pdata->exit) {
+		err = pdata->exit(pdev);
+		if (err < 0)
+			return err;
+	}
+
+	return 0;
+}
+
+static struct platform_driver tegra_pcie_driver = {
+	.driver = {
+		.name = "tegra-pcie",
+		.owner = THIS_MODULE,
+	},
+	.probe = tegra_pcie_probe,
+	.remove = __devexit_p(tegra_pcie_remove),
+};
+module_platform_driver(tegra_pcie_driver);
-- 
1.7.10.4

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

* [PATCH v2 06/10] ARM: tegra: pcie: Add MSI support
  2012-06-11 15:05 ` Thierry Reding
@ 2012-06-11 15:05   ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-11 15:05 UTC (permalink / raw)
  To: linux-tegra
  Cc: Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson, Stephen Warren

This commit adds support for message signaled interrupts to the Tegra
PCIe controller. Based on code by Krishna Kishore <kthota@nvidia.com>.

Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>

---
Changes in v2:
- improve compile coverage by using the IS_ENABLED() macro
- move MSI-related fields to a separate structure
- free pages used for the AFI/FPCI region
- properly remove IRQ domain on module removal
- disable MSI interrupt on module removal
- use linear IRQ domain
---
 arch/arm/mach-tegra/Kconfig             |    1 +
 arch/arm/mach-tegra/devices.c           |    7 +
 arch/arm/mach-tegra/include/mach/irqs.h |    5 +-
 arch/arm/mach-tegra/pcie.c              |  268 +++++++++++++++++++++++++++++++
 4 files changed, 280 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index cf129d6..4dd6945 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -48,6 +48,7 @@ config ARCH_TEGRA_3x_SOC
 config TEGRA_PCI
 	bool "PCI Express support"
 	depends on ARCH_TEGRA_2x_SOC
+	select ARCH_SUPPORTS_MSI
 	select PCI
 
 config TEGRA_AHB
diff --git a/arch/arm/mach-tegra/devices.c b/arch/arm/mach-tegra/devices.c
index de4aef9..03da0f7 100644
--- a/arch/arm/mach-tegra/devices.c
+++ b/arch/arm/mach-tegra/devices.c
@@ -752,6 +752,13 @@ static struct resource tegra_pcie_resources[] = {
 		.end = INT_PCIE_INTR,
 		.flags = IORESOURCE_IRQ,
 	},
+#ifdef CONFIG_PCI_MSI
+	[3] = {
+		.start = INT_PCIE_MSI,
+		.end = INT_PCIE_MSI,
+		.flags = IORESOURCE_IRQ,
+	},
+#endif
 };
 
 struct platform_device tegra_pcie_device = {
diff --git a/arch/arm/mach-tegra/include/mach/irqs.h b/arch/arm/mach-tegra/include/mach/irqs.h
index 0a0dcac..a282524 100644
--- a/arch/arm/mach-tegra/include/mach/irqs.h
+++ b/arch/arm/mach-tegra/include/mach/irqs.h
@@ -172,7 +172,10 @@
 /* Tegra30 has 8 banks of 32 GPIOs */
 #define INT_GPIO_NR			(32 * 8)
 
-#define TEGRA_NR_IRQS			(INT_GPIO_BASE + INT_GPIO_NR)
+#define INT_PCI_MSI_BASE		(INT_GPIO_BASE + INT_GPIO_NR)
+#define INT_PCI_MSI_NR			(32 * 8)
+
+#define TEGRA_NR_IRQS			(INT_PCI_MSI_BASE + INT_PCI_MSI_NR)
 
 #define INT_BOARD_BASE			TEGRA_NR_IRQS
 #define NR_BOARD_IRQS			128
diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c
index 291d55d..3c8c953 100644
--- a/arch/arm/mach-tegra/pcie.c
+++ b/arch/arm/mach-tegra/pcie.c
@@ -32,11 +32,14 @@
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/irqdomain.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/export.h>
+#include <linux/msi.h>
 
 #include <asm/sizes.h>
+#include <asm/mach/irq.h>
 #include <asm/mach/pci.h>
 
 #include <mach/iomap.h>
@@ -82,6 +85,24 @@
 #define AFI_MSI_FPCI_BAR_ST	0x64
 #define AFI_MSI_AXI_BAR_ST	0x68
 
+#define AFI_MSI_VEC0		0x6c
+#define AFI_MSI_VEC1		0x70
+#define AFI_MSI_VEC2		0x74
+#define AFI_MSI_VEC3		0x78
+#define AFI_MSI_VEC4		0x7c
+#define AFI_MSI_VEC5		0x80
+#define AFI_MSI_VEC6		0x84
+#define AFI_MSI_VEC7		0x88
+
+#define AFI_MSI_EN_VEC0		0x8c
+#define AFI_MSI_EN_VEC1		0x90
+#define AFI_MSI_EN_VEC2		0x94
+#define AFI_MSI_EN_VEC3		0x98
+#define AFI_MSI_EN_VEC4		0x9c
+#define AFI_MSI_EN_VEC5		0xa0
+#define AFI_MSI_EN_VEC6		0xa4
+#define AFI_MSI_EN_VEC7		0xa8
+
 #define AFI_CONFIGURATION		0xac
 #define  AFI_CONFIGURATION_EN_FPCI	(1 << 0)
 
@@ -197,6 +218,14 @@ struct tegra_pcie_port {
 	struct resource		res[3];
 };
 
+struct tegra_pcie_msi {
+	DECLARE_BITMAP(used, INT_PCI_MSI_NR);
+	struct irq_domain *domain;
+	unsigned long pages;
+	struct mutex lock;
+	int irq;
+};
+
 struct tegra_pcie_info {
 	struct device		*dev;
 
@@ -211,6 +240,8 @@ struct tegra_pcie_info {
 	struct clk		*afi_clk;
 	struct clk		*pcie_xclk;
 	struct clk		*pll_e;
+
+	struct tegra_pcie_msi	*msi;
 };
 
 static inline struct tegra_pcie_info *sys_to_pcie(struct pci_sys_data *sys)
@@ -939,6 +970,230 @@ static void __devinit tegra_pcie_add_port(struct tegra_pcie_info *pcie,
 	memset(pp->res, 0, sizeof(pp->res));
 }
 
+static int tegra_pcie_msi_alloc(struct tegra_pcie_info *pcie)
+{
+	int msi;
+
+	mutex_lock(&pcie->msi->lock);
+
+	msi = find_first_zero_bit(pcie->msi->used, INT_PCI_MSI_NR);
+	if (msi < INT_PCI_MSI_NR)
+		set_bit(msi, pcie->msi->used);
+	else
+		msi = -ENOSPC;
+
+	mutex_unlock(&pcie->msi->lock);
+
+	return msi;
+}
+
+static void tegra_pcie_msi_free(struct tegra_pcie_info *pcie, unsigned long irq)
+{
+	mutex_lock(&pcie->msi->lock);
+
+	if (!test_bit(irq, pcie->msi->used))
+		dev_err(pcie->dev, "trying to free unused MSI#%lu\n", irq);
+	else
+		clear_bit(irq, pcie->msi->used);
+
+	mutex_unlock(&pcie->msi->lock);
+}
+
+static irqreturn_t tegra_pcie_msi_irq(int irq, void *data)
+{
+	struct tegra_pcie_info *pcie = data;
+	unsigned int i;
+
+	for (i = 0; i < 8; i++) {
+		unsigned long reg = afi_readl(pcie, AFI_MSI_VEC0 + i * 4);
+
+		while (reg) {
+			unsigned int offset = find_first_bit(&reg, 32);
+			unsigned int index = i * 32 + offset;
+			unsigned int irq;
+
+			irq = irq_find_mapping(pcie->msi->domain, index);
+			if (irq) {
+				if (test_bit(index, pcie->msi->used))
+					generic_handle_irq(irq);
+				else
+					dev_info(pcie->dev, "unhandled MSI\n");
+			} else {
+				/*
+				 * that's weird who triggered this?
+				 * just clear it
+				 */
+				dev_info(pcie->dev, "unexpected MSI\n");
+			}
+
+			/* clear the interrupt */
+			afi_writel(pcie, 1 << offset, AFI_MSI_VEC0 + i * 4);
+			/* see if there's any more pending in this vector */
+			reg = afi_readl(pcie, AFI_MSI_VEC0 + i * 4);
+		}
+	}
+
+	return IRQ_HANDLED;
+}
+
+/* called by arch_setup_msi_irqs in drivers/pci/msi.c */
+int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
+{
+	struct tegra_pcie_info *pcie = sys_to_pcie(pdev->bus->sysdata);
+	struct msi_msg msg;
+	unsigned int irq;
+	int hwirq;
+
+	hwirq = tegra_pcie_msi_alloc(pcie);
+	if (hwirq < 0)
+		return hwirq;
+
+	irq = irq_create_mapping(pcie->msi->domain, hwirq);
+	if (!irq)
+		return -EINVAL;
+
+	irq_set_msi_desc(irq, desc);
+
+	msg.address_lo = afi_readl(pcie, AFI_MSI_AXI_BAR_ST);
+	/* 32 bit address only */
+	msg.address_hi = 0;
+	msg.data = hwirq;
+
+	write_msi_msg(irq, &msg);
+
+	return 0;
+}
+
+void arch_teardown_msi_irq(unsigned int irq)
+{
+	struct tegra_pcie_info *pcie = irq_get_chip_data(irq);
+	struct irq_data *d = irq_get_irq_data(irq);
+
+	tegra_pcie_msi_free(pcie, d->hwirq);
+}
+
+static struct irq_chip tegra_pcie_msi_irq_chip = {
+	.name = "Tegra PCIe MSI",
+	.irq_enable = unmask_msi_irq,
+	.irq_disable = mask_msi_irq,
+	.irq_mask = mask_msi_irq,
+	.irq_unmask = unmask_msi_irq,
+};
+
+static int tegra_pcie_msi_map(struct irq_domain *domain, unsigned int irq,
+			      irq_hw_number_t hwirq)
+{
+	irq_set_chip_and_handler(irq, &tegra_pcie_msi_irq_chip,
+				 handle_simple_irq);
+	irq_set_chip_data(irq, domain->host_data);
+	set_irq_flags(irq, IRQF_VALID);
+
+	return 0;
+}
+
+static const struct irq_domain_ops msi_domain_ops = {
+	.map = tegra_pcie_msi_map,
+};
+
+static int tegra_pcie_enable_msi(struct platform_device *pdev)
+{
+	struct tegra_pcie_info *pcie = platform_get_drvdata(pdev);
+	unsigned long base;
+	int err;
+	u32 reg;
+
+	pcie->msi = devm_kzalloc(&pdev->dev, sizeof(*pcie->msi), GFP_KERNEL);
+	if (!pcie->msi)
+		return -ENOMEM;
+
+	mutex_init(&pcie->msi->lock);
+
+	pcie->msi->domain = irq_domain_add_linear(pcie->dev->of_node,
+						  INT_PCI_MSI_NR,
+						  &msi_domain_ops, pcie);
+	if (!pcie->msi->domain) {
+		dev_err(&pdev->dev, "failed to create IRQ domain\n");
+		return -ENOMEM;
+	}
+
+	err = platform_get_irq(pdev, 1);
+	if (err < 0) {
+		dev_err(&pdev->dev, "failed to get IRQ: %d\n", err);
+		goto err;
+	}
+
+	pcie->msi->irq = err;
+
+	err = devm_request_irq(&pdev->dev, pcie->msi->irq, tegra_pcie_msi_irq,
+			       0, tegra_pcie_msi_irq_chip.name, pcie);
+	if (err < 0) {
+		dev_err(&pdev->dev, "failed to request IRQ: %d\n", err);
+		goto err;
+	}
+
+	/* setup AFI/FPCI range */
+	pcie->msi->pages = __get_free_pages(GFP_KERNEL, 3);
+	base = virt_to_phys((void *)pcie->msi->pages);
+
+	afi_writel(pcie, base, AFI_MSI_FPCI_BAR_ST);
+	afi_writel(pcie, base, AFI_MSI_AXI_BAR_ST);
+	/* this register is in 4K increments */
+	afi_writel(pcie, 1, AFI_MSI_BAR_SZ);
+
+	/* enable all MSI vectors */
+	afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC0);
+	afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC1);
+	afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC2);
+	afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC3);
+	afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC4);
+	afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC5);
+	afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC6);
+	afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC7);
+
+	/* and unmask the MSI interrupt */
+	reg = afi_readl(pcie, AFI_INTR_MASK);
+	reg |= AFI_INTR_MASK_MSI_MASK;
+	afi_writel(pcie, reg, AFI_INTR_MASK);
+
+	return 0;
+
+err:
+	irq_domain_remove(pcie->msi->domain);
+	return err;
+}
+
+static int tegra_pcie_disable_msi(struct platform_device *pdev)
+{
+	struct tegra_pcie_info *pcie = platform_get_drvdata(pdev);
+	unsigned int i, irq;
+	u32 reg;
+
+	/* mask the MSI interrupt */
+	reg = afi_readl(pcie, AFI_INTR_MASK);
+	reg &= ~AFI_INTR_MASK_MSI_MASK;
+	afi_writel(pcie, reg, AFI_INTR_MASK);
+
+	/* disable all MSI vectors */
+	afi_writel(pcie, 0, AFI_MSI_EN_VEC0);
+	afi_writel(pcie, 0, AFI_MSI_EN_VEC1);
+	afi_writel(pcie, 0, AFI_MSI_EN_VEC2);
+	afi_writel(pcie, 0, AFI_MSI_EN_VEC3);
+	afi_writel(pcie, 0, AFI_MSI_EN_VEC4);
+	afi_writel(pcie, 0, AFI_MSI_EN_VEC5);
+	afi_writel(pcie, 0, AFI_MSI_EN_VEC6);
+	afi_writel(pcie, 0, AFI_MSI_EN_VEC7);
+
+	for (i = 0; i < INT_PCI_MSI_NR; i++) {
+		irq = irq_find_mapping(pcie->msi->domain, i);
+		if (irq > 0)
+			irq_dispose_mapping(irq);
+	}
+
+	irq_domain_remove(pcie->msi->domain);
+
+	return 0;
+}
+
 static int __devinit tegra_pcie_probe(struct platform_device *pdev)
 {
 	struct tegra_pcie_pdata *pdata = pdev->dev.platform_data;
@@ -980,6 +1235,13 @@ static int __devinit tegra_pcie_probe(struct platform_device *pdev)
 	/* setup the AFI address translations */
 	tegra_pcie_setup_translations(pcie);
 
+	if (IS_ENABLED(CONFIG_PCI_MSI)) {
+		err = tegra_pcie_enable_msi(pdev);
+		if (err < 0)
+			dev_err(&pdev->dev, "failed to enable MSI support: %d\n",
+				err);
+	}
+
 	if (pdata->enable_ports[0]) {
 		tegra_pcie_add_port(pcie, 0, RP0_OFFSET, AFI_PEX0_CTRL);
 		private_data[0] = pcie;
@@ -1007,6 +1269,12 @@ static int __devexit tegra_pcie_remove(struct platform_device *pdev)
 	struct tegra_pcie_pdata *pdata = pdev->dev.platform_data;
 	int err;
 
+	if (IS_ENABLED(CONFIG_PCI_MSI)) {
+		err = tegra_pcie_disable_msi(pdev);
+		if (err < 0)
+			return err;
+	}
+
 	err = tegra_pcie_put_resources(pdev);
 	if (err < 0)
 		return err;
-- 
1.7.10.4

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

* [PATCH v2 06/10] ARM: tegra: pcie: Add MSI support
@ 2012-06-11 15:05   ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-11 15:05 UTC (permalink / raw)
  To: linux-arm-kernel

This commit adds support for message signaled interrupts to the Tegra
PCIe controller. Based on code by Krishna Kishore <kthota@nvidia.com>.

Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>

---
Changes in v2:
- improve compile coverage by using the IS_ENABLED() macro
- move MSI-related fields to a separate structure
- free pages used for the AFI/FPCI region
- properly remove IRQ domain on module removal
- disable MSI interrupt on module removal
- use linear IRQ domain
---
 arch/arm/mach-tegra/Kconfig             |    1 +
 arch/arm/mach-tegra/devices.c           |    7 +
 arch/arm/mach-tegra/include/mach/irqs.h |    5 +-
 arch/arm/mach-tegra/pcie.c              |  268 +++++++++++++++++++++++++++++++
 4 files changed, 280 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index cf129d6..4dd6945 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -48,6 +48,7 @@ config ARCH_TEGRA_3x_SOC
 config TEGRA_PCI
 	bool "PCI Express support"
 	depends on ARCH_TEGRA_2x_SOC
+	select ARCH_SUPPORTS_MSI
 	select PCI
 
 config TEGRA_AHB
diff --git a/arch/arm/mach-tegra/devices.c b/arch/arm/mach-tegra/devices.c
index de4aef9..03da0f7 100644
--- a/arch/arm/mach-tegra/devices.c
+++ b/arch/arm/mach-tegra/devices.c
@@ -752,6 +752,13 @@ static struct resource tegra_pcie_resources[] = {
 		.end = INT_PCIE_INTR,
 		.flags = IORESOURCE_IRQ,
 	},
+#ifdef CONFIG_PCI_MSI
+	[3] = {
+		.start = INT_PCIE_MSI,
+		.end = INT_PCIE_MSI,
+		.flags = IORESOURCE_IRQ,
+	},
+#endif
 };
 
 struct platform_device tegra_pcie_device = {
diff --git a/arch/arm/mach-tegra/include/mach/irqs.h b/arch/arm/mach-tegra/include/mach/irqs.h
index 0a0dcac..a282524 100644
--- a/arch/arm/mach-tegra/include/mach/irqs.h
+++ b/arch/arm/mach-tegra/include/mach/irqs.h
@@ -172,7 +172,10 @@
 /* Tegra30 has 8 banks of 32 GPIOs */
 #define INT_GPIO_NR			(32 * 8)
 
-#define TEGRA_NR_IRQS			(INT_GPIO_BASE + INT_GPIO_NR)
+#define INT_PCI_MSI_BASE		(INT_GPIO_BASE + INT_GPIO_NR)
+#define INT_PCI_MSI_NR			(32 * 8)
+
+#define TEGRA_NR_IRQS			(INT_PCI_MSI_BASE + INT_PCI_MSI_NR)
 
 #define INT_BOARD_BASE			TEGRA_NR_IRQS
 #define NR_BOARD_IRQS			128
diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c
index 291d55d..3c8c953 100644
--- a/arch/arm/mach-tegra/pcie.c
+++ b/arch/arm/mach-tegra/pcie.c
@@ -32,11 +32,14 @@
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/irqdomain.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/export.h>
+#include <linux/msi.h>
 
 #include <asm/sizes.h>
+#include <asm/mach/irq.h>
 #include <asm/mach/pci.h>
 
 #include <mach/iomap.h>
@@ -82,6 +85,24 @@
 #define AFI_MSI_FPCI_BAR_ST	0x64
 #define AFI_MSI_AXI_BAR_ST	0x68
 
+#define AFI_MSI_VEC0		0x6c
+#define AFI_MSI_VEC1		0x70
+#define AFI_MSI_VEC2		0x74
+#define AFI_MSI_VEC3		0x78
+#define AFI_MSI_VEC4		0x7c
+#define AFI_MSI_VEC5		0x80
+#define AFI_MSI_VEC6		0x84
+#define AFI_MSI_VEC7		0x88
+
+#define AFI_MSI_EN_VEC0		0x8c
+#define AFI_MSI_EN_VEC1		0x90
+#define AFI_MSI_EN_VEC2		0x94
+#define AFI_MSI_EN_VEC3		0x98
+#define AFI_MSI_EN_VEC4		0x9c
+#define AFI_MSI_EN_VEC5		0xa0
+#define AFI_MSI_EN_VEC6		0xa4
+#define AFI_MSI_EN_VEC7		0xa8
+
 #define AFI_CONFIGURATION		0xac
 #define  AFI_CONFIGURATION_EN_FPCI	(1 << 0)
 
@@ -197,6 +218,14 @@ struct tegra_pcie_port {
 	struct resource		res[3];
 };
 
+struct tegra_pcie_msi {
+	DECLARE_BITMAP(used, INT_PCI_MSI_NR);
+	struct irq_domain *domain;
+	unsigned long pages;
+	struct mutex lock;
+	int irq;
+};
+
 struct tegra_pcie_info {
 	struct device		*dev;
 
@@ -211,6 +240,8 @@ struct tegra_pcie_info {
 	struct clk		*afi_clk;
 	struct clk		*pcie_xclk;
 	struct clk		*pll_e;
+
+	struct tegra_pcie_msi	*msi;
 };
 
 static inline struct tegra_pcie_info *sys_to_pcie(struct pci_sys_data *sys)
@@ -939,6 +970,230 @@ static void __devinit tegra_pcie_add_port(struct tegra_pcie_info *pcie,
 	memset(pp->res, 0, sizeof(pp->res));
 }
 
+static int tegra_pcie_msi_alloc(struct tegra_pcie_info *pcie)
+{
+	int msi;
+
+	mutex_lock(&pcie->msi->lock);
+
+	msi = find_first_zero_bit(pcie->msi->used, INT_PCI_MSI_NR);
+	if (msi < INT_PCI_MSI_NR)
+		set_bit(msi, pcie->msi->used);
+	else
+		msi = -ENOSPC;
+
+	mutex_unlock(&pcie->msi->lock);
+
+	return msi;
+}
+
+static void tegra_pcie_msi_free(struct tegra_pcie_info *pcie, unsigned long irq)
+{
+	mutex_lock(&pcie->msi->lock);
+
+	if (!test_bit(irq, pcie->msi->used))
+		dev_err(pcie->dev, "trying to free unused MSI#%lu\n", irq);
+	else
+		clear_bit(irq, pcie->msi->used);
+
+	mutex_unlock(&pcie->msi->lock);
+}
+
+static irqreturn_t tegra_pcie_msi_irq(int irq, void *data)
+{
+	struct tegra_pcie_info *pcie = data;
+	unsigned int i;
+
+	for (i = 0; i < 8; i++) {
+		unsigned long reg = afi_readl(pcie, AFI_MSI_VEC0 + i * 4);
+
+		while (reg) {
+			unsigned int offset = find_first_bit(&reg, 32);
+			unsigned int index = i * 32 + offset;
+			unsigned int irq;
+
+			irq = irq_find_mapping(pcie->msi->domain, index);
+			if (irq) {
+				if (test_bit(index, pcie->msi->used))
+					generic_handle_irq(irq);
+				else
+					dev_info(pcie->dev, "unhandled MSI\n");
+			} else {
+				/*
+				 * that's weird who triggered this?
+				 * just clear it
+				 */
+				dev_info(pcie->dev, "unexpected MSI\n");
+			}
+
+			/* clear the interrupt */
+			afi_writel(pcie, 1 << offset, AFI_MSI_VEC0 + i * 4);
+			/* see if there's any more pending in this vector */
+			reg = afi_readl(pcie, AFI_MSI_VEC0 + i * 4);
+		}
+	}
+
+	return IRQ_HANDLED;
+}
+
+/* called by arch_setup_msi_irqs in drivers/pci/msi.c */
+int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
+{
+	struct tegra_pcie_info *pcie = sys_to_pcie(pdev->bus->sysdata);
+	struct msi_msg msg;
+	unsigned int irq;
+	int hwirq;
+
+	hwirq = tegra_pcie_msi_alloc(pcie);
+	if (hwirq < 0)
+		return hwirq;
+
+	irq = irq_create_mapping(pcie->msi->domain, hwirq);
+	if (!irq)
+		return -EINVAL;
+
+	irq_set_msi_desc(irq, desc);
+
+	msg.address_lo = afi_readl(pcie, AFI_MSI_AXI_BAR_ST);
+	/* 32 bit address only */
+	msg.address_hi = 0;
+	msg.data = hwirq;
+
+	write_msi_msg(irq, &msg);
+
+	return 0;
+}
+
+void arch_teardown_msi_irq(unsigned int irq)
+{
+	struct tegra_pcie_info *pcie = irq_get_chip_data(irq);
+	struct irq_data *d = irq_get_irq_data(irq);
+
+	tegra_pcie_msi_free(pcie, d->hwirq);
+}
+
+static struct irq_chip tegra_pcie_msi_irq_chip = {
+	.name = "Tegra PCIe MSI",
+	.irq_enable = unmask_msi_irq,
+	.irq_disable = mask_msi_irq,
+	.irq_mask = mask_msi_irq,
+	.irq_unmask = unmask_msi_irq,
+};
+
+static int tegra_pcie_msi_map(struct irq_domain *domain, unsigned int irq,
+			      irq_hw_number_t hwirq)
+{
+	irq_set_chip_and_handler(irq, &tegra_pcie_msi_irq_chip,
+				 handle_simple_irq);
+	irq_set_chip_data(irq, domain->host_data);
+	set_irq_flags(irq, IRQF_VALID);
+
+	return 0;
+}
+
+static const struct irq_domain_ops msi_domain_ops = {
+	.map = tegra_pcie_msi_map,
+};
+
+static int tegra_pcie_enable_msi(struct platform_device *pdev)
+{
+	struct tegra_pcie_info *pcie = platform_get_drvdata(pdev);
+	unsigned long base;
+	int err;
+	u32 reg;
+
+	pcie->msi = devm_kzalloc(&pdev->dev, sizeof(*pcie->msi), GFP_KERNEL);
+	if (!pcie->msi)
+		return -ENOMEM;
+
+	mutex_init(&pcie->msi->lock);
+
+	pcie->msi->domain = irq_domain_add_linear(pcie->dev->of_node,
+						  INT_PCI_MSI_NR,
+						  &msi_domain_ops, pcie);
+	if (!pcie->msi->domain) {
+		dev_err(&pdev->dev, "failed to create IRQ domain\n");
+		return -ENOMEM;
+	}
+
+	err = platform_get_irq(pdev, 1);
+	if (err < 0) {
+		dev_err(&pdev->dev, "failed to get IRQ: %d\n", err);
+		goto err;
+	}
+
+	pcie->msi->irq = err;
+
+	err = devm_request_irq(&pdev->dev, pcie->msi->irq, tegra_pcie_msi_irq,
+			       0, tegra_pcie_msi_irq_chip.name, pcie);
+	if (err < 0) {
+		dev_err(&pdev->dev, "failed to request IRQ: %d\n", err);
+		goto err;
+	}
+
+	/* setup AFI/FPCI range */
+	pcie->msi->pages = __get_free_pages(GFP_KERNEL, 3);
+	base = virt_to_phys((void *)pcie->msi->pages);
+
+	afi_writel(pcie, base, AFI_MSI_FPCI_BAR_ST);
+	afi_writel(pcie, base, AFI_MSI_AXI_BAR_ST);
+	/* this register is in 4K increments */
+	afi_writel(pcie, 1, AFI_MSI_BAR_SZ);
+
+	/* enable all MSI vectors */
+	afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC0);
+	afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC1);
+	afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC2);
+	afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC3);
+	afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC4);
+	afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC5);
+	afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC6);
+	afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC7);
+
+	/* and unmask the MSI interrupt */
+	reg = afi_readl(pcie, AFI_INTR_MASK);
+	reg |= AFI_INTR_MASK_MSI_MASK;
+	afi_writel(pcie, reg, AFI_INTR_MASK);
+
+	return 0;
+
+err:
+	irq_domain_remove(pcie->msi->domain);
+	return err;
+}
+
+static int tegra_pcie_disable_msi(struct platform_device *pdev)
+{
+	struct tegra_pcie_info *pcie = platform_get_drvdata(pdev);
+	unsigned int i, irq;
+	u32 reg;
+
+	/* mask the MSI interrupt */
+	reg = afi_readl(pcie, AFI_INTR_MASK);
+	reg &= ~AFI_INTR_MASK_MSI_MASK;
+	afi_writel(pcie, reg, AFI_INTR_MASK);
+
+	/* disable all MSI vectors */
+	afi_writel(pcie, 0, AFI_MSI_EN_VEC0);
+	afi_writel(pcie, 0, AFI_MSI_EN_VEC1);
+	afi_writel(pcie, 0, AFI_MSI_EN_VEC2);
+	afi_writel(pcie, 0, AFI_MSI_EN_VEC3);
+	afi_writel(pcie, 0, AFI_MSI_EN_VEC4);
+	afi_writel(pcie, 0, AFI_MSI_EN_VEC5);
+	afi_writel(pcie, 0, AFI_MSI_EN_VEC6);
+	afi_writel(pcie, 0, AFI_MSI_EN_VEC7);
+
+	for (i = 0; i < INT_PCI_MSI_NR; i++) {
+		irq = irq_find_mapping(pcie->msi->domain, i);
+		if (irq > 0)
+			irq_dispose_mapping(irq);
+	}
+
+	irq_domain_remove(pcie->msi->domain);
+
+	return 0;
+}
+
 static int __devinit tegra_pcie_probe(struct platform_device *pdev)
 {
 	struct tegra_pcie_pdata *pdata = pdev->dev.platform_data;
@@ -980,6 +1235,13 @@ static int __devinit tegra_pcie_probe(struct platform_device *pdev)
 	/* setup the AFI address translations */
 	tegra_pcie_setup_translations(pcie);
 
+	if (IS_ENABLED(CONFIG_PCI_MSI)) {
+		err = tegra_pcie_enable_msi(pdev);
+		if (err < 0)
+			dev_err(&pdev->dev, "failed to enable MSI support: %d\n",
+				err);
+	}
+
 	if (pdata->enable_ports[0]) {
 		tegra_pcie_add_port(pcie, 0, RP0_OFFSET, AFI_PEX0_CTRL);
 		private_data[0] = pcie;
@@ -1007,6 +1269,12 @@ static int __devexit tegra_pcie_remove(struct platform_device *pdev)
 	struct tegra_pcie_pdata *pdata = pdev->dev.platform_data;
 	int err;
 
+	if (IS_ENABLED(CONFIG_PCI_MSI)) {
+		err = tegra_pcie_disable_msi(pdev);
+		if (err < 0)
+			return err;
+	}
+
 	err = tegra_pcie_put_resources(pdev);
 	if (err < 0)
 		return err;
-- 
1.7.10.4

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-11 15:05 ` Thierry Reding
  (?)
@ 2012-06-11 15:05     ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-11 15:05 UTC (permalink / raw)
  To: linux-tegra-u79uwXL29TY76Z2rM5mHXA
  Cc: Jesse Barnes, linux-pci-u79uwXL29TY76Z2rM5mHXA, Grant Likely,
	Rob Herring, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	Russell King, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Colin Cross, Olof Johansson, Stephen Warren

This commit adds support for instantiating the Tegra PCIe controller
from a device tree.

Signed-off-by: Thierry Reding <thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>

---
Changes in v2:
- increase compile coverage by using the IS_ENABLED() macro
- disable node by default
---
 .../devicetree/bindings/pci/tegra-pcie.txt         |   23 ++++
 arch/arm/boot/dts/tegra20.dtsi                     |    9 ++
 arch/arm/mach-tegra/pcie.c                         |  120 +++++++++++++++++++-
 3 files changed, 149 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pci/tegra-pcie.txt

diff --git a/Documentation/devicetree/bindings/pci/tegra-pcie.txt b/Documentation/devicetree/bindings/pci/tegra-pcie.txt
new file mode 100644
index 0000000..10bbc40
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/tegra-pcie.txt
@@ -0,0 +1,23 @@
+NVIDIA Tegra PCIe controller
+
+Required properties:
+- compatible: "nvidia,tegra20-pcie"
+- reg: physical base address and length of the controller's registers
+- interrupts: the interrupt outputs of the controller
+
+Optional properties:
+- pex-clk-supply: supply voltage for internal reference clock
+- vdd-supply: power supply for controller (1.05V)
+
+Example:
+
+	pci@80000000 {
+		compatible = "nvidia,tegra20-pcie",
+		reg = <0x80000000 0x400000   /* PCIe AFI registers */
+		       0x80400000 0x010000>; /* PCI I/O space */
+		interrupts = < 0 98 0x04    /* controller interrupt */
+		               0 99 0x04 >; /* MSI interrupt */
+
+		pex-clk-supply = <&ldo0_reg>;
+		vdd-supply = <&pcie_reg>;
+	};
diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index fa56519..b212658 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -199,6 +199,15 @@
 		#size-cells = <0>;
 	};
 
+	pci {
+		compatible = "nvidia,tegra20-pcie";
+		reg = <0x80000000 0x400000   /* PCIe AFI registers */
+		       0x80400000 0x010000>; /* PCI I/O space */
+		interrupts = < 0 98 0x04    /* controller interrupt */
+		               0 99 0x04 >; /* MSI interrupt */
+		status = "disable";
+	};
+
 	usb@c5000000 {
 		compatible = "nvidia,tegra20-ehci", "usb-ehci";
 		reg = <0xc5000000 0x4000>;
diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c
index 3c8c953..f24923b 100644
--- a/arch/arm/mach-tegra/pcie.c
+++ b/arch/arm/mach-tegra/pcie.c
@@ -37,6 +37,8 @@
 #include <linux/delay.h>
 #include <linux/export.h>
 #include <linux/msi.h>
+#include <linux/of.h>
+#include <linux/regulator/consumer.h>
 
 #include <asm/sizes.h>
 #include <asm/mach/irq.h>
@@ -242,6 +244,9 @@ struct tegra_pcie_info {
 	struct clk		*pll_e;
 
 	struct tegra_pcie_msi	*msi;
+
+	struct regulator *pex_clk_supply;
+	struct regulator *vdd_supply;
 };
 
 static inline struct tegra_pcie_info *sys_to_pcie(struct pci_sys_data *sys)
@@ -1194,6 +1199,99 @@ static int tegra_pcie_disable_msi(struct platform_device *pdev)
 	return 0;
 }
 
+static int tegra_pcie_dt_init(struct platform_device *pdev)
+{
+	struct tegra_pcie_info *pcie = platform_get_drvdata(pdev);
+	int err;
+
+	if (!IS_ERR_OR_NULL(pcie->vdd_supply)) {
+		err = regulator_enable(pcie->vdd_supply);
+		if (err < 0) {
+			dev_err(&pdev->dev,
+				"failed to enable VDD regulator: %d\n", err);
+			return err;
+		}
+	}
+
+	if (!IS_ERR_OR_NULL(pcie->pex_clk_supply)) {
+		err = regulator_enable(pcie->pex_clk_supply);
+		if (err < 0) {
+			dev_err(&pdev->dev,
+				"failed to enable pex-clk regulator: %d\n",
+				err);
+			return err;
+		}
+	}
+
+	return 0;
+}
+
+static int tegra_pcie_dt_exit(struct platform_device *pdev)
+{
+	struct tegra_pcie_info *pcie = platform_get_drvdata(pdev);
+	int err;
+
+	if (!IS_ERR_OR_NULL(pcie->pex_clk_supply)) {
+		err = regulator_disable(pcie->pex_clk_supply);
+		if (err < 0) {
+			dev_err(&pdev->dev,
+				"failed to disable pex-clk regulator: %d\n",
+				err);
+			return err;
+		}
+	}
+
+	if (!IS_ERR_OR_NULL(pcie->vdd_supply)) {
+		err = regulator_disable(pcie->vdd_supply);
+		if (err < 0) {
+			dev_err(&pdev->dev,
+				"failed to disable VDD regulator: %d\n", err);
+			return err;
+		}
+	}
+
+	return 0;
+}
+
+static struct tegra_pcie_pdata *tegra_pcie_parse_dt(struct platform_device *pdev)
+{
+	struct tegra_pcie_info *pcie = platform_get_drvdata(pdev);
+	struct device_node *node = pdev->dev.of_node;
+	struct tegra_pcie_pdata *pdata;
+	unsigned int i;
+
+	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		return NULL;
+
+	pdata->init = tegra_pcie_dt_init;
+	pdata->exit = tegra_pcie_dt_exit;
+
+	if (of_find_property(node, "vdd-supply", NULL)) {
+		pcie->vdd_supply = regulator_get(&pdev->dev, "vdd");
+		if (IS_ERR_OR_NULL(pcie->vdd_supply))
+			return ERR_PTR(-EPROBE_DEFER);
+	}
+
+	if (of_find_property(node, "pex-clk-supply", NULL)) {
+		pcie->pex_clk_supply = regulator_get(&pdev->dev, "pex-clk");
+		if (IS_ERR_OR_NULL(pcie->pex_clk_supply))
+			return ERR_PTR(-EPROBE_DEFER);
+	}
+
+	for (i = 0; i < TEGRA_PCIE_MAX_PORTS; i++)
+		pdata->enable_ports[i] = true;
+
+	return pdata;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id tegra_pcie_of_match[] = {
+	{ .compatible = "nvidia,tegra20-pcie", },
+	{ },
+};
+#endif
+
 static int __devinit tegra_pcie_probe(struct platform_device *pdev)
 {
 	struct tegra_pcie_pdata *pdata = pdev->dev.platform_data;
@@ -1202,9 +1300,6 @@ static int __devinit tegra_pcie_probe(struct platform_device *pdev)
 	struct hw_pci hw;
 	int err;
 
-	if (!pdata->enable_ports[0] && !pdata->enable_ports[1])
-		return -ENODEV;
-
 	pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL);
 	if (!pcie)
 		return -ENOMEM;
@@ -1212,6 +1307,20 @@ static int __devinit tegra_pcie_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, pcie);
 	pcie->dev = &pdev->dev;
 
+	if (IS_ENABLED(CONFIG_OF)) {
+		if (!pdata && pdev->dev.of_node) {
+			pdata = tegra_pcie_parse_dt(pdev);
+			if (IS_ERR(pdata))
+				return PTR_ERR(pdata);
+		}
+	}
+
+	if (!pdata)
+		return -ENODEV;
+
+	if (!pdata->enable_ports[0] && !pdata->enable_ports[1])
+		return -ENODEV;
+
 	pcibios_min_mem = 0;
 
 	err = tegra_pcie_get_resources(pdev);
@@ -1266,6 +1375,7 @@ static int __devinit tegra_pcie_probe(struct platform_device *pdev)
 
 static int __devexit tegra_pcie_remove(struct platform_device *pdev)
 {
+	struct tegra_pcie_info *pcie = platform_get_drvdata(pdev);
 	struct tegra_pcie_pdata *pdata = pdev->dev.platform_data;
 	int err;
 
@@ -1285,6 +1395,9 @@ static int __devexit tegra_pcie_remove(struct platform_device *pdev)
 			return err;
 	}
 
+	regulator_put(pcie->pex_clk_supply);
+	regulator_put(pcie->vdd_supply);
+
 	return 0;
 }
 
@@ -1292,6 +1405,7 @@ static struct platform_driver tegra_pcie_driver = {
 	.driver = {
 		.name = "tegra-pcie",
 		.owner = THIS_MODULE,
+		.of_match_table = of_match_ptr(tegra_pcie_of_match),
 	},
 	.probe = tegra_pcie_probe,
 	.remove = __devexit_p(tegra_pcie_remove),
-- 
1.7.10.4

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-11 15:05     ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-11 15:05 UTC (permalink / raw)
  To: linux-tegra
  Cc: Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson, Stephen Warren

This commit adds support for instantiating the Tegra PCIe controller
from a device tree.

Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>

---
Changes in v2:
- increase compile coverage by using the IS_ENABLED() macro
- disable node by default
---
 .../devicetree/bindings/pci/tegra-pcie.txt         |   23 ++++
 arch/arm/boot/dts/tegra20.dtsi                     |    9 ++
 arch/arm/mach-tegra/pcie.c                         |  120 +++++++++++++++++++-
 3 files changed, 149 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pci/tegra-pcie.txt

diff --git a/Documentation/devicetree/bindings/pci/tegra-pcie.txt b/Documentation/devicetree/bindings/pci/tegra-pcie.txt
new file mode 100644
index 0000000..10bbc40
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/tegra-pcie.txt
@@ -0,0 +1,23 @@
+NVIDIA Tegra PCIe controller
+
+Required properties:
+- compatible: "nvidia,tegra20-pcie"
+- reg: physical base address and length of the controller's registers
+- interrupts: the interrupt outputs of the controller
+
+Optional properties:
+- pex-clk-supply: supply voltage for internal reference clock
+- vdd-supply: power supply for controller (1.05V)
+
+Example:
+
+	pci@80000000 {
+		compatible = "nvidia,tegra20-pcie",
+		reg = <0x80000000 0x400000   /* PCIe AFI registers */
+		       0x80400000 0x010000>; /* PCI I/O space */
+		interrupts = < 0 98 0x04    /* controller interrupt */
+		               0 99 0x04 >; /* MSI interrupt */
+
+		pex-clk-supply = <&ldo0_reg>;
+		vdd-supply = <&pcie_reg>;
+	};
diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index fa56519..b212658 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -199,6 +199,15 @@
 		#size-cells = <0>;
 	};
 
+	pci {
+		compatible = "nvidia,tegra20-pcie";
+		reg = <0x80000000 0x400000   /* PCIe AFI registers */
+		       0x80400000 0x010000>; /* PCI I/O space */
+		interrupts = < 0 98 0x04    /* controller interrupt */
+		               0 99 0x04 >; /* MSI interrupt */
+		status = "disable";
+	};
+
 	usb@c5000000 {
 		compatible = "nvidia,tegra20-ehci", "usb-ehci";
 		reg = <0xc5000000 0x4000>;
diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c
index 3c8c953..f24923b 100644
--- a/arch/arm/mach-tegra/pcie.c
+++ b/arch/arm/mach-tegra/pcie.c
@@ -37,6 +37,8 @@
 #include <linux/delay.h>
 #include <linux/export.h>
 #include <linux/msi.h>
+#include <linux/of.h>
+#include <linux/regulator/consumer.h>
 
 #include <asm/sizes.h>
 #include <asm/mach/irq.h>
@@ -242,6 +244,9 @@ struct tegra_pcie_info {
 	struct clk		*pll_e;
 
 	struct tegra_pcie_msi	*msi;
+
+	struct regulator *pex_clk_supply;
+	struct regulator *vdd_supply;
 };
 
 static inline struct tegra_pcie_info *sys_to_pcie(struct pci_sys_data *sys)
@@ -1194,6 +1199,99 @@ static int tegra_pcie_disable_msi(struct platform_device *pdev)
 	return 0;
 }
 
+static int tegra_pcie_dt_init(struct platform_device *pdev)
+{
+	struct tegra_pcie_info *pcie = platform_get_drvdata(pdev);
+	int err;
+
+	if (!IS_ERR_OR_NULL(pcie->vdd_supply)) {
+		err = regulator_enable(pcie->vdd_supply);
+		if (err < 0) {
+			dev_err(&pdev->dev,
+				"failed to enable VDD regulator: %d\n", err);
+			return err;
+		}
+	}
+
+	if (!IS_ERR_OR_NULL(pcie->pex_clk_supply)) {
+		err = regulator_enable(pcie->pex_clk_supply);
+		if (err < 0) {
+			dev_err(&pdev->dev,
+				"failed to enable pex-clk regulator: %d\n",
+				err);
+			return err;
+		}
+	}
+
+	return 0;
+}
+
+static int tegra_pcie_dt_exit(struct platform_device *pdev)
+{
+	struct tegra_pcie_info *pcie = platform_get_drvdata(pdev);
+	int err;
+
+	if (!IS_ERR_OR_NULL(pcie->pex_clk_supply)) {
+		err = regulator_disable(pcie->pex_clk_supply);
+		if (err < 0) {
+			dev_err(&pdev->dev,
+				"failed to disable pex-clk regulator: %d\n",
+				err);
+			return err;
+		}
+	}
+
+	if (!IS_ERR_OR_NULL(pcie->vdd_supply)) {
+		err = regulator_disable(pcie->vdd_supply);
+		if (err < 0) {
+			dev_err(&pdev->dev,
+				"failed to disable VDD regulator: %d\n", err);
+			return err;
+		}
+	}
+
+	return 0;
+}
+
+static struct tegra_pcie_pdata *tegra_pcie_parse_dt(struct platform_device *pdev)
+{
+	struct tegra_pcie_info *pcie = platform_get_drvdata(pdev);
+	struct device_node *node = pdev->dev.of_node;
+	struct tegra_pcie_pdata *pdata;
+	unsigned int i;
+
+	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		return NULL;
+
+	pdata->init = tegra_pcie_dt_init;
+	pdata->exit = tegra_pcie_dt_exit;
+
+	if (of_find_property(node, "vdd-supply", NULL)) {
+		pcie->vdd_supply = regulator_get(&pdev->dev, "vdd");
+		if (IS_ERR_OR_NULL(pcie->vdd_supply))
+			return ERR_PTR(-EPROBE_DEFER);
+	}
+
+	if (of_find_property(node, "pex-clk-supply", NULL)) {
+		pcie->pex_clk_supply = regulator_get(&pdev->dev, "pex-clk");
+		if (IS_ERR_OR_NULL(pcie->pex_clk_supply))
+			return ERR_PTR(-EPROBE_DEFER);
+	}
+
+	for (i = 0; i < TEGRA_PCIE_MAX_PORTS; i++)
+		pdata->enable_ports[i] = true;
+
+	return pdata;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id tegra_pcie_of_match[] = {
+	{ .compatible = "nvidia,tegra20-pcie", },
+	{ },
+};
+#endif
+
 static int __devinit tegra_pcie_probe(struct platform_device *pdev)
 {
 	struct tegra_pcie_pdata *pdata = pdev->dev.platform_data;
@@ -1202,9 +1300,6 @@ static int __devinit tegra_pcie_probe(struct platform_device *pdev)
 	struct hw_pci hw;
 	int err;
 
-	if (!pdata->enable_ports[0] && !pdata->enable_ports[1])
-		return -ENODEV;
-
 	pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL);
 	if (!pcie)
 		return -ENOMEM;
@@ -1212,6 +1307,20 @@ static int __devinit tegra_pcie_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, pcie);
 	pcie->dev = &pdev->dev;
 
+	if (IS_ENABLED(CONFIG_OF)) {
+		if (!pdata && pdev->dev.of_node) {
+			pdata = tegra_pcie_parse_dt(pdev);
+			if (IS_ERR(pdata))
+				return PTR_ERR(pdata);
+		}
+	}
+
+	if (!pdata)
+		return -ENODEV;
+
+	if (!pdata->enable_ports[0] && !pdata->enable_ports[1])
+		return -ENODEV;
+
 	pcibios_min_mem = 0;
 
 	err = tegra_pcie_get_resources(pdev);
@@ -1266,6 +1375,7 @@ static int __devinit tegra_pcie_probe(struct platform_device *pdev)
 
 static int __devexit tegra_pcie_remove(struct platform_device *pdev)
 {
+	struct tegra_pcie_info *pcie = platform_get_drvdata(pdev);
 	struct tegra_pcie_pdata *pdata = pdev->dev.platform_data;
 	int err;
 
@@ -1285,6 +1395,9 @@ static int __devexit tegra_pcie_remove(struct platform_device *pdev)
 			return err;
 	}
 
+	regulator_put(pcie->pex_clk_supply);
+	regulator_put(pcie->vdd_supply);
+
 	return 0;
 }
 
@@ -1292,6 +1405,7 @@ static struct platform_driver tegra_pcie_driver = {
 	.driver = {
 		.name = "tegra-pcie",
 		.owner = THIS_MODULE,
+		.of_match_table = of_match_ptr(tegra_pcie_of_match),
 	},
 	.probe = tegra_pcie_probe,
 	.remove = __devexit_p(tegra_pcie_remove),
-- 
1.7.10.4


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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-11 15:05     ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-11 15:05 UTC (permalink / raw)
  To: linux-arm-kernel

This commit adds support for instantiating the Tegra PCIe controller
from a device tree.

Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>

---
Changes in v2:
- increase compile coverage by using the IS_ENABLED() macro
- disable node by default
---
 .../devicetree/bindings/pci/tegra-pcie.txt         |   23 ++++
 arch/arm/boot/dts/tegra20.dtsi                     |    9 ++
 arch/arm/mach-tegra/pcie.c                         |  120 +++++++++++++++++++-
 3 files changed, 149 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pci/tegra-pcie.txt

diff --git a/Documentation/devicetree/bindings/pci/tegra-pcie.txt b/Documentation/devicetree/bindings/pci/tegra-pcie.txt
new file mode 100644
index 0000000..10bbc40
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/tegra-pcie.txt
@@ -0,0 +1,23 @@
+NVIDIA Tegra PCIe controller
+
+Required properties:
+- compatible: "nvidia,tegra20-pcie"
+- reg: physical base address and length of the controller's registers
+- interrupts: the interrupt outputs of the controller
+
+Optional properties:
+- pex-clk-supply: supply voltage for internal reference clock
+- vdd-supply: power supply for controller (1.05V)
+
+Example:
+
+	pci at 80000000 {
+		compatible = "nvidia,tegra20-pcie",
+		reg = <0x80000000 0x400000   /* PCIe AFI registers */
+		       0x80400000 0x010000>; /* PCI I/O space */
+		interrupts = < 0 98 0x04    /* controller interrupt */
+		               0 99 0x04 >; /* MSI interrupt */
+
+		pex-clk-supply = <&ldo0_reg>;
+		vdd-supply = <&pcie_reg>;
+	};
diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index fa56519..b212658 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -199,6 +199,15 @@
 		#size-cells = <0>;
 	};
 
+	pci {
+		compatible = "nvidia,tegra20-pcie";
+		reg = <0x80000000 0x400000   /* PCIe AFI registers */
+		       0x80400000 0x010000>; /* PCI I/O space */
+		interrupts = < 0 98 0x04    /* controller interrupt */
+		               0 99 0x04 >; /* MSI interrupt */
+		status = "disable";
+	};
+
 	usb at c5000000 {
 		compatible = "nvidia,tegra20-ehci", "usb-ehci";
 		reg = <0xc5000000 0x4000>;
diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c
index 3c8c953..f24923b 100644
--- a/arch/arm/mach-tegra/pcie.c
+++ b/arch/arm/mach-tegra/pcie.c
@@ -37,6 +37,8 @@
 #include <linux/delay.h>
 #include <linux/export.h>
 #include <linux/msi.h>
+#include <linux/of.h>
+#include <linux/regulator/consumer.h>
 
 #include <asm/sizes.h>
 #include <asm/mach/irq.h>
@@ -242,6 +244,9 @@ struct tegra_pcie_info {
 	struct clk		*pll_e;
 
 	struct tegra_pcie_msi	*msi;
+
+	struct regulator *pex_clk_supply;
+	struct regulator *vdd_supply;
 };
 
 static inline struct tegra_pcie_info *sys_to_pcie(struct pci_sys_data *sys)
@@ -1194,6 +1199,99 @@ static int tegra_pcie_disable_msi(struct platform_device *pdev)
 	return 0;
 }
 
+static int tegra_pcie_dt_init(struct platform_device *pdev)
+{
+	struct tegra_pcie_info *pcie = platform_get_drvdata(pdev);
+	int err;
+
+	if (!IS_ERR_OR_NULL(pcie->vdd_supply)) {
+		err = regulator_enable(pcie->vdd_supply);
+		if (err < 0) {
+			dev_err(&pdev->dev,
+				"failed to enable VDD regulator: %d\n", err);
+			return err;
+		}
+	}
+
+	if (!IS_ERR_OR_NULL(pcie->pex_clk_supply)) {
+		err = regulator_enable(pcie->pex_clk_supply);
+		if (err < 0) {
+			dev_err(&pdev->dev,
+				"failed to enable pex-clk regulator: %d\n",
+				err);
+			return err;
+		}
+	}
+
+	return 0;
+}
+
+static int tegra_pcie_dt_exit(struct platform_device *pdev)
+{
+	struct tegra_pcie_info *pcie = platform_get_drvdata(pdev);
+	int err;
+
+	if (!IS_ERR_OR_NULL(pcie->pex_clk_supply)) {
+		err = regulator_disable(pcie->pex_clk_supply);
+		if (err < 0) {
+			dev_err(&pdev->dev,
+				"failed to disable pex-clk regulator: %d\n",
+				err);
+			return err;
+		}
+	}
+
+	if (!IS_ERR_OR_NULL(pcie->vdd_supply)) {
+		err = regulator_disable(pcie->vdd_supply);
+		if (err < 0) {
+			dev_err(&pdev->dev,
+				"failed to disable VDD regulator: %d\n", err);
+			return err;
+		}
+	}
+
+	return 0;
+}
+
+static struct tegra_pcie_pdata *tegra_pcie_parse_dt(struct platform_device *pdev)
+{
+	struct tegra_pcie_info *pcie = platform_get_drvdata(pdev);
+	struct device_node *node = pdev->dev.of_node;
+	struct tegra_pcie_pdata *pdata;
+	unsigned int i;
+
+	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		return NULL;
+
+	pdata->init = tegra_pcie_dt_init;
+	pdata->exit = tegra_pcie_dt_exit;
+
+	if (of_find_property(node, "vdd-supply", NULL)) {
+		pcie->vdd_supply = regulator_get(&pdev->dev, "vdd");
+		if (IS_ERR_OR_NULL(pcie->vdd_supply))
+			return ERR_PTR(-EPROBE_DEFER);
+	}
+
+	if (of_find_property(node, "pex-clk-supply", NULL)) {
+		pcie->pex_clk_supply = regulator_get(&pdev->dev, "pex-clk");
+		if (IS_ERR_OR_NULL(pcie->pex_clk_supply))
+			return ERR_PTR(-EPROBE_DEFER);
+	}
+
+	for (i = 0; i < TEGRA_PCIE_MAX_PORTS; i++)
+		pdata->enable_ports[i] = true;
+
+	return pdata;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id tegra_pcie_of_match[] = {
+	{ .compatible = "nvidia,tegra20-pcie", },
+	{ },
+};
+#endif
+
 static int __devinit tegra_pcie_probe(struct platform_device *pdev)
 {
 	struct tegra_pcie_pdata *pdata = pdev->dev.platform_data;
@@ -1202,9 +1300,6 @@ static int __devinit tegra_pcie_probe(struct platform_device *pdev)
 	struct hw_pci hw;
 	int err;
 
-	if (!pdata->enable_ports[0] && !pdata->enable_ports[1])
-		return -ENODEV;
-
 	pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL);
 	if (!pcie)
 		return -ENOMEM;
@@ -1212,6 +1307,20 @@ static int __devinit tegra_pcie_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, pcie);
 	pcie->dev = &pdev->dev;
 
+	if (IS_ENABLED(CONFIG_OF)) {
+		if (!pdata && pdev->dev.of_node) {
+			pdata = tegra_pcie_parse_dt(pdev);
+			if (IS_ERR(pdata))
+				return PTR_ERR(pdata);
+		}
+	}
+
+	if (!pdata)
+		return -ENODEV;
+
+	if (!pdata->enable_ports[0] && !pdata->enable_ports[1])
+		return -ENODEV;
+
 	pcibios_min_mem = 0;
 
 	err = tegra_pcie_get_resources(pdev);
@@ -1266,6 +1375,7 @@ static int __devinit tegra_pcie_probe(struct platform_device *pdev)
 
 static int __devexit tegra_pcie_remove(struct platform_device *pdev)
 {
+	struct tegra_pcie_info *pcie = platform_get_drvdata(pdev);
 	struct tegra_pcie_pdata *pdata = pdev->dev.platform_data;
 	int err;
 
@@ -1285,6 +1395,9 @@ static int __devexit tegra_pcie_remove(struct platform_device *pdev)
 			return err;
 	}
 
+	regulator_put(pcie->pex_clk_supply);
+	regulator_put(pcie->vdd_supply);
+
 	return 0;
 }
 
@@ -1292,6 +1405,7 @@ static struct platform_driver tegra_pcie_driver = {
 	.driver = {
 		.name = "tegra-pcie",
 		.owner = THIS_MODULE,
+		.of_match_table = of_match_ptr(tegra_pcie_of_match),
 	},
 	.probe = tegra_pcie_probe,
 	.remove = __devexit_p(tegra_pcie_remove),
-- 
1.7.10.4

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

* [PATCH v2 08/10] ARM: tegra: harmony: Initialize regulators from DT
  2012-06-11 15:05 ` Thierry Reding
@ 2012-06-11 15:05   ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-11 15:05 UTC (permalink / raw)
  To: linux-tegra
  Cc: Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson, Stephen Warren

Device tree support for the TPS6586x PMU used on Harmony has recently
been added. This commit adds the required device tree nodes to probe the
PMU from the device tree.

Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>

---
Changes in v2:
- new patch
---
 arch/arm/boot/dts/tegra-harmony.dts    |   83 ++++++++++++++++++++++++++++++++
 arch/arm/mach-tegra/board-dt-tegra20.c |    6 ---
 2 files changed, 83 insertions(+), 6 deletions(-)

diff --git a/arch/arm/boot/dts/tegra-harmony.dts b/arch/arm/boot/dts/tegra-harmony.dts
index f146dbf..c98aa2a 100644
--- a/arch/arm/boot/dts/tegra-harmony.dts
+++ b/arch/arm/boot/dts/tegra-harmony.dts
@@ -275,6 +275,89 @@
 	i2c@7000d000 {
 		status = "okay";
 		clock-frequency = <400000>;
+
+		tps6586x@34 {
+			compatible = "ti,tps6586x";
+			reg = <0x34>;
+			interrupts = <0 88 0x4>;
+
+			#gpio-cells = <2>;
+			gpio-controller;
+
+			regulators {
+				sm0 {
+					regulator-min-microvolt = < 725000>;
+					regulator-max-microvolt = <1500000>;
+					regulator-boot-on;
+					regulator-always-on;
+				};
+
+				sm1 {
+					regulator-min-microvolt = < 725000>;
+					regulator-max-microvolt = <1500000>;
+					regulator-boot-on;
+					regulator-always-on;
+				};
+
+				sm2 {
+					regulator-min-microvolt = <3000000>;
+					regulator-max-microvolt = <4550000>;
+					regulator-boot-on;
+					regulator-always-on;
+				};
+
+				ldo0 {
+					regulator-name = "PCIE CLK";
+					regulator-min-microvolt = <3300000>;
+					regulator-max-microvolt = <3300000>;
+				};
+
+				ldo1 {
+					regulator-min-microvolt = < 725000>;
+					regulator-max-microvolt = <1500000>;
+				};
+
+				ldo2 {
+					regulator-min-microvolt = < 725000>;
+					regulator-max-microvolt = <1500000>;
+				};
+
+				ldo3 {
+					regulator-min-microvolt = <1250000>;
+					regulator-max-microvolt = <3300000>;
+				};
+
+				ldo4 {
+					regulator-min-microvolt = <1700000>;
+					regulator-max-microvolt = <2475000>;
+				};
+
+				ldo5 {
+					regulator-min-microvolt = <1250000>;
+					regulator-max-microvolt = <3300000>;
+				};
+
+				ldo6 {
+					regulator-min-microvolt = <1250000>;
+					regulator-max-microvolt = <3300000>;
+				};
+
+				ldo7 {
+					regulator-min-microvolt = <1250000>;
+					regulator-max-microvolt = <3300000>;
+				};
+
+				ldo8 {
+					regulator-min-microvolt = <1250000>;
+					regulator-max-microvolt = <3300000>;
+				};
+
+				ldo9 {
+					regulator-min-microvolt = <1250000>;
+					regulator-max-microvolt = <3300000>;
+				};
+			};
+		};
 	};
 
 	pmc {
diff --git a/arch/arm/mach-tegra/board-dt-tegra20.c b/arch/arm/mach-tegra/board-dt-tegra20.c
index 0f29c05..a9a54e6 100644
--- a/arch/arm/mach-tegra/board-dt-tegra20.c
+++ b/arch/arm/mach-tegra/board-dt-tegra20.c
@@ -136,12 +136,6 @@ static void __init harmony_init(void)
 {
 	int ret;
 
-	ret = harmony_regulator_init();
-	if (ret) {
-		pr_err("harmony_regulator_init() failed: %d\n", ret);
-		return;
-	}
-
 	ret = harmony_pcie_init();
 	if (ret)
 		pr_err("harmony_pcie_init() failed: %d\n", ret);
-- 
1.7.10.4

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

* [PATCH v2 08/10] ARM: tegra: harmony: Initialize regulators from DT
@ 2012-06-11 15:05   ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-11 15:05 UTC (permalink / raw)
  To: linux-arm-kernel

Device tree support for the TPS6586x PMU used on Harmony has recently
been added. This commit adds the required device tree nodes to probe the
PMU from the device tree.

Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>

---
Changes in v2:
- new patch
---
 arch/arm/boot/dts/tegra-harmony.dts    |   83 ++++++++++++++++++++++++++++++++
 arch/arm/mach-tegra/board-dt-tegra20.c |    6 ---
 2 files changed, 83 insertions(+), 6 deletions(-)

diff --git a/arch/arm/boot/dts/tegra-harmony.dts b/arch/arm/boot/dts/tegra-harmony.dts
index f146dbf..c98aa2a 100644
--- a/arch/arm/boot/dts/tegra-harmony.dts
+++ b/arch/arm/boot/dts/tegra-harmony.dts
@@ -275,6 +275,89 @@
 	i2c at 7000d000 {
 		status = "okay";
 		clock-frequency = <400000>;
+
+		tps6586x at 34 {
+			compatible = "ti,tps6586x";
+			reg = <0x34>;
+			interrupts = <0 88 0x4>;
+
+			#gpio-cells = <2>;
+			gpio-controller;
+
+			regulators {
+				sm0 {
+					regulator-min-microvolt = < 725000>;
+					regulator-max-microvolt = <1500000>;
+					regulator-boot-on;
+					regulator-always-on;
+				};
+
+				sm1 {
+					regulator-min-microvolt = < 725000>;
+					regulator-max-microvolt = <1500000>;
+					regulator-boot-on;
+					regulator-always-on;
+				};
+
+				sm2 {
+					regulator-min-microvolt = <3000000>;
+					regulator-max-microvolt = <4550000>;
+					regulator-boot-on;
+					regulator-always-on;
+				};
+
+				ldo0 {
+					regulator-name = "PCIE CLK";
+					regulator-min-microvolt = <3300000>;
+					regulator-max-microvolt = <3300000>;
+				};
+
+				ldo1 {
+					regulator-min-microvolt = < 725000>;
+					regulator-max-microvolt = <1500000>;
+				};
+
+				ldo2 {
+					regulator-min-microvolt = < 725000>;
+					regulator-max-microvolt = <1500000>;
+				};
+
+				ldo3 {
+					regulator-min-microvolt = <1250000>;
+					regulator-max-microvolt = <3300000>;
+				};
+
+				ldo4 {
+					regulator-min-microvolt = <1700000>;
+					regulator-max-microvolt = <2475000>;
+				};
+
+				ldo5 {
+					regulator-min-microvolt = <1250000>;
+					regulator-max-microvolt = <3300000>;
+				};
+
+				ldo6 {
+					regulator-min-microvolt = <1250000>;
+					regulator-max-microvolt = <3300000>;
+				};
+
+				ldo7 {
+					regulator-min-microvolt = <1250000>;
+					regulator-max-microvolt = <3300000>;
+				};
+
+				ldo8 {
+					regulator-min-microvolt = <1250000>;
+					regulator-max-microvolt = <3300000>;
+				};
+
+				ldo9 {
+					regulator-min-microvolt = <1250000>;
+					regulator-max-microvolt = <3300000>;
+				};
+			};
+		};
 	};
 
 	pmc {
diff --git a/arch/arm/mach-tegra/board-dt-tegra20.c b/arch/arm/mach-tegra/board-dt-tegra20.c
index 0f29c05..a9a54e6 100644
--- a/arch/arm/mach-tegra/board-dt-tegra20.c
+++ b/arch/arm/mach-tegra/board-dt-tegra20.c
@@ -136,12 +136,6 @@ static void __init harmony_init(void)
 {
 	int ret;
 
-	ret = harmony_regulator_init();
-	if (ret) {
-		pr_err("harmony_regulator_init() failed: %d\n", ret);
-		return;
-	}
-
 	ret = harmony_pcie_init();
 	if (ret)
 		pr_err("harmony_pcie_init() failed: %d\n", ret);
-- 
1.7.10.4

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

* [PATCH v2 09/10] ARM: tegra: harmony: Initialize PCIe from DT
  2012-06-11 15:05 ` Thierry Reding
  (?)
@ 2012-06-11 15:05     ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-11 15:05 UTC (permalink / raw)
  To: linux-tegra-u79uwXL29TY76Z2rM5mHXA
  Cc: Jesse Barnes, linux-pci-u79uwXL29TY76Z2rM5mHXA, Grant Likely,
	Rob Herring, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	Russell King, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Colin Cross, Olof Johansson, Stephen Warren

With the device tree support in place, probe the PCIe controller from
the device tree and remove the corresponding workaround in the board
file.

Signed-off-by: Thierry Reding <thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>

---
Changes in v2:
- new patch
---
 arch/arm/boot/dts/tegra-harmony.dts    |   19 +++++++++++++++++--
 arch/arm/mach-tegra/board-dt-tegra20.c |   14 --------------
 2 files changed, 17 insertions(+), 16 deletions(-)

diff --git a/arch/arm/boot/dts/tegra-harmony.dts b/arch/arm/boot/dts/tegra-harmony.dts
index c98aa2a..1dc907f 100644
--- a/arch/arm/boot/dts/tegra-harmony.dts
+++ b/arch/arm/boot/dts/tegra-harmony.dts
@@ -276,7 +276,7 @@
 		status = "okay";
 		clock-frequency = <400000>;
 
-		tps6586x@34 {
+		pmu: tps6586x@34 {
 			compatible = "ti,tps6586x";
 			reg = <0x34>;
 			interrupts = <0 88 0x4>;
@@ -306,7 +306,7 @@
 					regulator-always-on;
 				};
 
-				ldo0 {
+				pci_clk_reg: ldo0 {
 					regulator-name = "PCIE CLK";
 					regulator-min-microvolt = <3300000>;
 					regulator-max-microvolt = <3300000>;
@@ -364,6 +364,21 @@
 		nvidia,invert-interrupt;
 	};
 
+	pci_vdd_reg: fixedregulator@0 {
+		compatible = "regulator-fixed";
+		regulator-name = "PCIE VDD";
+		regulator-min-microvolt = <1050000>;
+		regulator-max-microvolt = <1050000>;
+		enable-active-high;
+		gpio = <&pmu 2 0>;
+	};
+
+	pci {
+		pex-clk-supply = <&pci_clk_reg>;
+		vdd-supply = <&pci_vdd_reg>;
+		status = "okay";
+	};
+
 	usb@c5000000 {
 		status = "okay";
 	};
diff --git a/arch/arm/mach-tegra/board-dt-tegra20.c b/arch/arm/mach-tegra/board-dt-tegra20.c
index a9a54e6..c7b6ae2 100644
--- a/arch/arm/mach-tegra/board-dt-tegra20.c
+++ b/arch/arm/mach-tegra/board-dt-tegra20.c
@@ -131,17 +131,6 @@ static void __init trimslice_init(void)
 }
 #endif
 
-#ifdef CONFIG_MACH_HARMONY
-static void __init harmony_init(void)
-{
-	int ret;
-
-	ret = harmony_pcie_init();
-	if (ret)
-		pr_err("harmony_pcie_init() failed: %d\n", ret);
-}
-#endif
-
 #ifdef CONFIG_MACH_PAZ00
 static void __init paz00_init(void)
 {
@@ -156,9 +145,6 @@ static struct {
 #ifdef CONFIG_MACH_TRIMSLICE
 	{ "compulab,trimslice", trimslice_init },
 #endif
-#ifdef CONFIG_MACH_HARMONY
-	{ "nvidia,harmony", harmony_init },
-#endif
 #ifdef CONFIG_MACH_PAZ00
 	{ "compal,paz00", paz00_init },
 #endif
-- 
1.7.10.4

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

* [PATCH v2 09/10] ARM: tegra: harmony: Initialize PCIe from DT
@ 2012-06-11 15:05     ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-11 15:05 UTC (permalink / raw)
  To: linux-tegra
  Cc: Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson, Stephen Warren

With the device tree support in place, probe the PCIe controller from
the device tree and remove the corresponding workaround in the board
file.

Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>

---
Changes in v2:
- new patch
---
 arch/arm/boot/dts/tegra-harmony.dts    |   19 +++++++++++++++++--
 arch/arm/mach-tegra/board-dt-tegra20.c |   14 --------------
 2 files changed, 17 insertions(+), 16 deletions(-)

diff --git a/arch/arm/boot/dts/tegra-harmony.dts b/arch/arm/boot/dts/tegra-harmony.dts
index c98aa2a..1dc907f 100644
--- a/arch/arm/boot/dts/tegra-harmony.dts
+++ b/arch/arm/boot/dts/tegra-harmony.dts
@@ -276,7 +276,7 @@
 		status = "okay";
 		clock-frequency = <400000>;
 
-		tps6586x@34 {
+		pmu: tps6586x@34 {
 			compatible = "ti,tps6586x";
 			reg = <0x34>;
 			interrupts = <0 88 0x4>;
@@ -306,7 +306,7 @@
 					regulator-always-on;
 				};
 
-				ldo0 {
+				pci_clk_reg: ldo0 {
 					regulator-name = "PCIE CLK";
 					regulator-min-microvolt = <3300000>;
 					regulator-max-microvolt = <3300000>;
@@ -364,6 +364,21 @@
 		nvidia,invert-interrupt;
 	};
 
+	pci_vdd_reg: fixedregulator@0 {
+		compatible = "regulator-fixed";
+		regulator-name = "PCIE VDD";
+		regulator-min-microvolt = <1050000>;
+		regulator-max-microvolt = <1050000>;
+		enable-active-high;
+		gpio = <&pmu 2 0>;
+	};
+
+	pci {
+		pex-clk-supply = <&pci_clk_reg>;
+		vdd-supply = <&pci_vdd_reg>;
+		status = "okay";
+	};
+
 	usb@c5000000 {
 		status = "okay";
 	};
diff --git a/arch/arm/mach-tegra/board-dt-tegra20.c b/arch/arm/mach-tegra/board-dt-tegra20.c
index a9a54e6..c7b6ae2 100644
--- a/arch/arm/mach-tegra/board-dt-tegra20.c
+++ b/arch/arm/mach-tegra/board-dt-tegra20.c
@@ -131,17 +131,6 @@ static void __init trimslice_init(void)
 }
 #endif
 
-#ifdef CONFIG_MACH_HARMONY
-static void __init harmony_init(void)
-{
-	int ret;
-
-	ret = harmony_pcie_init();
-	if (ret)
-		pr_err("harmony_pcie_init() failed: %d\n", ret);
-}
-#endif
-
 #ifdef CONFIG_MACH_PAZ00
 static void __init paz00_init(void)
 {
@@ -156,9 +145,6 @@ static struct {
 #ifdef CONFIG_MACH_TRIMSLICE
 	{ "compulab,trimslice", trimslice_init },
 #endif
-#ifdef CONFIG_MACH_HARMONY
-	{ "nvidia,harmony", harmony_init },
-#endif
 #ifdef CONFIG_MACH_PAZ00
 	{ "compal,paz00", paz00_init },
 #endif
-- 
1.7.10.4


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

* [PATCH v2 09/10] ARM: tegra: harmony: Initialize PCIe from DT
@ 2012-06-11 15:05     ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-11 15:05 UTC (permalink / raw)
  To: linux-arm-kernel

With the device tree support in place, probe the PCIe controller from
the device tree and remove the corresponding workaround in the board
file.

Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>

---
Changes in v2:
- new patch
---
 arch/arm/boot/dts/tegra-harmony.dts    |   19 +++++++++++++++++--
 arch/arm/mach-tegra/board-dt-tegra20.c |   14 --------------
 2 files changed, 17 insertions(+), 16 deletions(-)

diff --git a/arch/arm/boot/dts/tegra-harmony.dts b/arch/arm/boot/dts/tegra-harmony.dts
index c98aa2a..1dc907f 100644
--- a/arch/arm/boot/dts/tegra-harmony.dts
+++ b/arch/arm/boot/dts/tegra-harmony.dts
@@ -276,7 +276,7 @@
 		status = "okay";
 		clock-frequency = <400000>;
 
-		tps6586x at 34 {
+		pmu: tps6586x at 34 {
 			compatible = "ti,tps6586x";
 			reg = <0x34>;
 			interrupts = <0 88 0x4>;
@@ -306,7 +306,7 @@
 					regulator-always-on;
 				};
 
-				ldo0 {
+				pci_clk_reg: ldo0 {
 					regulator-name = "PCIE CLK";
 					regulator-min-microvolt = <3300000>;
 					regulator-max-microvolt = <3300000>;
@@ -364,6 +364,21 @@
 		nvidia,invert-interrupt;
 	};
 
+	pci_vdd_reg: fixedregulator at 0 {
+		compatible = "regulator-fixed";
+		regulator-name = "PCIE VDD";
+		regulator-min-microvolt = <1050000>;
+		regulator-max-microvolt = <1050000>;
+		enable-active-high;
+		gpio = <&pmu 2 0>;
+	};
+
+	pci {
+		pex-clk-supply = <&pci_clk_reg>;
+		vdd-supply = <&pci_vdd_reg>;
+		status = "okay";
+	};
+
 	usb at c5000000 {
 		status = "okay";
 	};
diff --git a/arch/arm/mach-tegra/board-dt-tegra20.c b/arch/arm/mach-tegra/board-dt-tegra20.c
index a9a54e6..c7b6ae2 100644
--- a/arch/arm/mach-tegra/board-dt-tegra20.c
+++ b/arch/arm/mach-tegra/board-dt-tegra20.c
@@ -131,17 +131,6 @@ static void __init trimslice_init(void)
 }
 #endif
 
-#ifdef CONFIG_MACH_HARMONY
-static void __init harmony_init(void)
-{
-	int ret;
-
-	ret = harmony_pcie_init();
-	if (ret)
-		pr_err("harmony_pcie_init() failed: %d\n", ret);
-}
-#endif
-
 #ifdef CONFIG_MACH_PAZ00
 static void __init paz00_init(void)
 {
@@ -156,9 +145,6 @@ static struct {
 #ifdef CONFIG_MACH_TRIMSLICE
 	{ "compulab,trimslice", trimslice_init },
 #endif
-#ifdef CONFIG_MACH_HARMONY
-	{ "nvidia,harmony", harmony_init },
-#endif
 #ifdef CONFIG_MACH_PAZ00
 	{ "compal,paz00", paz00_init },
 #endif
-- 
1.7.10.4

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

* [PATCH v2 10/10] ARM: tegra: trimslice: Initialize PCIe from DT
  2012-06-11 15:05 ` Thierry Reding
@ 2012-06-11 15:05   ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-11 15:05 UTC (permalink / raw)
  To: linux-tegra
  Cc: Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson, Stephen Warren

With the device tree support in place, probe the PCIe controller from
the device tree and remove the corresponding workaround in the board
file.

Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>

---
Changes in v2:
- new patch
---
 arch/arm/boot/dts/tegra-trimslice.dts  |    4 ++++
 arch/arm/mach-tegra/board-dt-tegra20.c |   18 ------------------
 2 files changed, 4 insertions(+), 18 deletions(-)

diff --git a/arch/arm/boot/dts/tegra-trimslice.dts b/arch/arm/boot/dts/tegra-trimslice.dts
index 9de5636..fc48f371 100644
--- a/arch/arm/boot/dts/tegra-trimslice.dts
+++ b/arch/arm/boot/dts/tegra-trimslice.dts
@@ -274,6 +274,10 @@
 		};
 	};
 
+	pci {
+		status = "okay";
+	};
+
 	usb@c5000000 {
 		status = "okay";
 	};
diff --git a/arch/arm/mach-tegra/board-dt-tegra20.c b/arch/arm/mach-tegra/board-dt-tegra20.c
index c7b6ae2..3a8b825 100644
--- a/arch/arm/mach-tegra/board-dt-tegra20.c
+++ b/arch/arm/mach-tegra/board-dt-tegra20.c
@@ -116,21 +116,6 @@ static void __init tegra_dt_init(void)
 				tegra20_auxdata_lookup, NULL);
 }
 
-#ifdef CONFIG_MACH_TRIMSLICE
-static struct tegra_pcie_pdata trimslice_pcie_pdata = {
-	.enable_ports = {
-		[0] = true,
-		[1] = true,
-	},
-};
-
-static void __init trimslice_init(void)
-{
-	tegra_pcie_device.dev.platform_data = &trimslice_pcie_pdata;
-	platform_device_register(&tegra_pcie_device);
-}
-#endif
-
 #ifdef CONFIG_MACH_PAZ00
 static void __init paz00_init(void)
 {
@@ -142,9 +127,6 @@ static struct {
 	char *machine;
 	void (*init)(void);
 } board_init_funcs[] = {
-#ifdef CONFIG_MACH_TRIMSLICE
-	{ "compulab,trimslice", trimslice_init },
-#endif
 #ifdef CONFIG_MACH_PAZ00
 	{ "compal,paz00", paz00_init },
 #endif
-- 
1.7.10.4

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

* [PATCH v2 10/10] ARM: tegra: trimslice: Initialize PCIe from DT
@ 2012-06-11 15:05   ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-11 15:05 UTC (permalink / raw)
  To: linux-arm-kernel

With the device tree support in place, probe the PCIe controller from
the device tree and remove the corresponding workaround in the board
file.

Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>

---
Changes in v2:
- new patch
---
 arch/arm/boot/dts/tegra-trimslice.dts  |    4 ++++
 arch/arm/mach-tegra/board-dt-tegra20.c |   18 ------------------
 2 files changed, 4 insertions(+), 18 deletions(-)

diff --git a/arch/arm/boot/dts/tegra-trimslice.dts b/arch/arm/boot/dts/tegra-trimslice.dts
index 9de5636..fc48f371 100644
--- a/arch/arm/boot/dts/tegra-trimslice.dts
+++ b/arch/arm/boot/dts/tegra-trimslice.dts
@@ -274,6 +274,10 @@
 		};
 	};
 
+	pci {
+		status = "okay";
+	};
+
 	usb at c5000000 {
 		status = "okay";
 	};
diff --git a/arch/arm/mach-tegra/board-dt-tegra20.c b/arch/arm/mach-tegra/board-dt-tegra20.c
index c7b6ae2..3a8b825 100644
--- a/arch/arm/mach-tegra/board-dt-tegra20.c
+++ b/arch/arm/mach-tegra/board-dt-tegra20.c
@@ -116,21 +116,6 @@ static void __init tegra_dt_init(void)
 				tegra20_auxdata_lookup, NULL);
 }
 
-#ifdef CONFIG_MACH_TRIMSLICE
-static struct tegra_pcie_pdata trimslice_pcie_pdata = {
-	.enable_ports = {
-		[0] = true,
-		[1] = true,
-	},
-};
-
-static void __init trimslice_init(void)
-{
-	tegra_pcie_device.dev.platform_data = &trimslice_pcie_pdata;
-	platform_device_register(&tegra_pcie_device);
-}
-#endif
-
 #ifdef CONFIG_MACH_PAZ00
 static void __init paz00_init(void)
 {
@@ -142,9 +127,6 @@ static struct {
 	char *machine;
 	void (*init)(void);
 } board_init_funcs[] = {
-#ifdef CONFIG_MACH_TRIMSLICE
-	{ "compulab,trimslice", trimslice_init },
-#endif
 #ifdef CONFIG_MACH_PAZ00
 	{ "compal,paz00", paz00_init },
 #endif
-- 
1.7.10.4

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

* Re: [PATCH v2 05/10] ARM: tegra: Rewrite PCIe support as a driver
  2012-06-11 15:05   ` Thierry Reding
@ 2012-06-11 21:09     ` Stephen Warren
  -1 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-11 21:09 UTC (permalink / raw)
  To: Thierry Reding
  Cc: linux-tegra, Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson

On 06/11/2012 09:05 AM, Thierry Reding wrote:
> This commit adds a platform device driver for the PCIe controller on
> Tegra SOCs. Current users of the old code (TrimSlice and Harmony) are
> converted and now initialize and register a corresponding platform
> device.

> diff --git a/arch/arm/mach-tegra/devices.c b/arch/arm/mach-tegra/devices.c

> +static struct resource tegra_pcie_resources[] = {
> +	[0] = {
> +		.start = TEGRA_PCIE_BASE,
> +		.end = TEGRA_PCIE_BASE + TEGRA_PCIE_SIZE - 1,
> +		.flags = IORESOURCE_MEM,
> +	},
> +	[1] = {
> +		.start = TEGRA_PCIE_MMIO_BASE,
> +		.end = TEGRA_PCIE_MMIO_BASE + TEGRA_PCIE_MMIO_SIZE - 1,
> +		.flags = IORESOURCE_MEM,
> +	},
> +	[2] = {
> +		.start = INT_PCIE_INTR,
> +		.end = INT_PCIE_INTR,
> +		.flags = IORESOURCE_IRQ,
> +	},
> +};

I'm not sure those resources either cover all the necessary regions, nor
are as fine-grained as they should be ...

In particular, in pcie.c, I see separate afi_writel() and pads_writel()
implying those are separate regions.

Also, I see the following hard-code specific addresses, and are still
used by the driver after conversion:

> #define MEM_BASE_0              (TEGRA_PCIE_BASE + SZ_256M)
> #define MEM_SIZE_0              SZ_128M
> #define MEM_BASE_1              (MEM_BASE_0 + MEM_SIZE_0)
> #define MEM_SIZE_1              SZ_128M
> #define PREFETCH_MEM_BASE_0     (MEM_BASE_1 + MEM_SIZE_1)
> #define PREFETCH_MEM_SIZE_0     SZ_128M
> #define PREFETCH_MEM_BASE_1     (PREFETCH_MEM_BASE_0 + PREFETCH_MEM_SIZE_0)
> #define PREFETCH_MEM_SIZE_1     SZ_128M

Also, there's a comment describing the register layout in terms of a
number of separate regions:

> /*
>  * Tegra2 defines 1GB in the AXI address map for PCIe.
>  *
>  * That address space is split into different regions, with sizes and
>  * offsets as follows:
>  *
>  * 0x80000000 - 0x80003fff - PCI controller registers
>  * 0x80004000 - 0x80103fff - PCI configuration space
>  * 0x80104000 - 0x80203fff - PCI extended configuration space
>  * 0x80203fff - 0x803fffff - unused
>  * 0x80400000 - 0x8040ffff - downstream IO
>  * 0x80410000 - 0x8fffffff - unused
>  * 0x90000000 - 0x9fffffff - non-prefetchable memory
>  * 0xa0000000 - 0xbfffffff - prefetchable memory
>  */

(the latter 2 regions at least being also split in half for each of the
2 host ports)

Shouldn't each of these regions be a separate entry in the platform
device resources.

This perhaps isn't that relevant for Tegra20 alone, but Tegra30 supports
3 host ports instead of 2 (hence I presume alters the internal layout of
the 1G chunk of physical memory space allocated to PCIe), and moves the
PCIe area from 2G..3G to 0G..1G (so invalidates the hard-coded
*_MEM_BASE_* above).

That said, I'm not sure whether Tegra20's and Tegra30's PCIe controllers
are similar enough to make a shared driver worthwhile/possible.
(Although our downstream Android driver appears to handle both with a
very small number of ifdefs). If they are similar, then I think my
comments above should be addressed. If they are not similar, then I
think you can just have a single 1G memory region in the resources, and
split it up internally, rather than needing separate resources for
different parts of the address space.

While we can easily fix this kind of driver internals so this doesn't
seem like a big deal, this kind of change would impact the device tree
binding, so it seems that we need to sort it out before DT conversion.

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

* [PATCH v2 05/10] ARM: tegra: Rewrite PCIe support as a driver
@ 2012-06-11 21:09     ` Stephen Warren
  0 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-11 21:09 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/11/2012 09:05 AM, Thierry Reding wrote:
> This commit adds a platform device driver for the PCIe controller on
> Tegra SOCs. Current users of the old code (TrimSlice and Harmony) are
> converted and now initialize and register a corresponding platform
> device.

> diff --git a/arch/arm/mach-tegra/devices.c b/arch/arm/mach-tegra/devices.c

> +static struct resource tegra_pcie_resources[] = {
> +	[0] = {
> +		.start = TEGRA_PCIE_BASE,
> +		.end = TEGRA_PCIE_BASE + TEGRA_PCIE_SIZE - 1,
> +		.flags = IORESOURCE_MEM,
> +	},
> +	[1] = {
> +		.start = TEGRA_PCIE_MMIO_BASE,
> +		.end = TEGRA_PCIE_MMIO_BASE + TEGRA_PCIE_MMIO_SIZE - 1,
> +		.flags = IORESOURCE_MEM,
> +	},
> +	[2] = {
> +		.start = INT_PCIE_INTR,
> +		.end = INT_PCIE_INTR,
> +		.flags = IORESOURCE_IRQ,
> +	},
> +};

I'm not sure those resources either cover all the necessary regions, nor
are as fine-grained as they should be ...

In particular, in pcie.c, I see separate afi_writel() and pads_writel()
implying those are separate regions.

Also, I see the following hard-code specific addresses, and are still
used by the driver after conversion:

> #define MEM_BASE_0              (TEGRA_PCIE_BASE + SZ_256M)
> #define MEM_SIZE_0              SZ_128M
> #define MEM_BASE_1              (MEM_BASE_0 + MEM_SIZE_0)
> #define MEM_SIZE_1              SZ_128M
> #define PREFETCH_MEM_BASE_0     (MEM_BASE_1 + MEM_SIZE_1)
> #define PREFETCH_MEM_SIZE_0     SZ_128M
> #define PREFETCH_MEM_BASE_1     (PREFETCH_MEM_BASE_0 + PREFETCH_MEM_SIZE_0)
> #define PREFETCH_MEM_SIZE_1     SZ_128M

Also, there's a comment describing the register layout in terms of a
number of separate regions:

> /*
>  * Tegra2 defines 1GB in the AXI address map for PCIe.
>  *
>  * That address space is split into different regions, with sizes and
>  * offsets as follows:
>  *
>  * 0x80000000 - 0x80003fff - PCI controller registers
>  * 0x80004000 - 0x80103fff - PCI configuration space
>  * 0x80104000 - 0x80203fff - PCI extended configuration space
>  * 0x80203fff - 0x803fffff - unused
>  * 0x80400000 - 0x8040ffff - downstream IO
>  * 0x80410000 - 0x8fffffff - unused
>  * 0x90000000 - 0x9fffffff - non-prefetchable memory
>  * 0xa0000000 - 0xbfffffff - prefetchable memory
>  */

(the latter 2 regions at least being also split in half for each of the
2 host ports)

Shouldn't each of these regions be a separate entry in the platform
device resources.

This perhaps isn't that relevant for Tegra20 alone, but Tegra30 supports
3 host ports instead of 2 (hence I presume alters the internal layout of
the 1G chunk of physical memory space allocated to PCIe), and moves the
PCIe area from 2G..3G to 0G..1G (so invalidates the hard-coded
*_MEM_BASE_* above).

That said, I'm not sure whether Tegra20's and Tegra30's PCIe controllers
are similar enough to make a shared driver worthwhile/possible.
(Although our downstream Android driver appears to handle both with a
very small number of ifdefs). If they are similar, then I think my
comments above should be addressed. If they are not similar, then I
think you can just have a single 1G memory region in the resources, and
split it up internally, rather than needing separate resources for
different parts of the address space.

While we can easily fix this kind of driver internals so this doesn't
seem like a big deal, this kind of change would impact the device tree
binding, so it seems that we need to sort it out before DT conversion.

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

* Re: [PATCH v2 06/10] ARM: tegra: pcie: Add MSI support
  2012-06-11 15:05   ` Thierry Reding
  (?)
@ 2012-06-11 21:19       ` Stephen Warren
  -1 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-11 21:19 UTC (permalink / raw)
  To: Thierry Reding
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jesse Barnes,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, Grant Likely, Rob Herring,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Russell King,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Colin Cross,
	Olof Johansson

On 06/11/2012 09:05 AM, Thierry Reding wrote:
> This commit adds support for message signaled interrupts to the Tegra
> PCIe controller. Based on code by Krishna Kishore <kthota-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>.

> diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c

> +static irqreturn_t tegra_pcie_msi_irq(int irq, void *data)
...
> +			irq = irq_find_mapping(pcie->msi->domain, index);
> +			if (irq) {
> +				if (test_bit(index, pcie->msi->used))
> +					generic_handle_irq(irq);

This invokes the handler first ...

...
> +			/* clear the interrupt */
> +			afi_writel(pcie, 1 << offset, AFI_MSI_VEC0 + i * 4);
> +			/* see if there's any more pending in this vector */
> +			reg = afi_readl(pcie, AFI_MSI_VEC0 + i * 4);

... then clears the interrupt status in the PCIe controller. Won't that
lose interrupts if one is raised between when the handler clears the
root-cause, and when this code clears the received interrupt status?

> +static int tegra_pcie_disable_msi(struct platform_device *pdev)

Should this free pcie->msi->pages?

Why allocate pcie->msi separately; why not include the fields directly
into struct tegra_pcie_info *pcie?

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

* Re: [PATCH v2 06/10] ARM: tegra: pcie: Add MSI support
@ 2012-06-11 21:19       ` Stephen Warren
  0 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-11 21:19 UTC (permalink / raw)
  To: Thierry Reding
  Cc: linux-tegra, Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson

On 06/11/2012 09:05 AM, Thierry Reding wrote:
> This commit adds support for message signaled interrupts to the Tegra
> PCIe controller. Based on code by Krishna Kishore <kthota@nvidia.com>.

> diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c

> +static irqreturn_t tegra_pcie_msi_irq(int irq, void *data)
...
> +			irq = irq_find_mapping(pcie->msi->domain, index);
> +			if (irq) {
> +				if (test_bit(index, pcie->msi->used))
> +					generic_handle_irq(irq);

This invokes the handler first ...

...
> +			/* clear the interrupt */
> +			afi_writel(pcie, 1 << offset, AFI_MSI_VEC0 + i * 4);
> +			/* see if there's any more pending in this vector */
> +			reg = afi_readl(pcie, AFI_MSI_VEC0 + i * 4);

... then clears the interrupt status in the PCIe controller. Won't that
lose interrupts if one is raised between when the handler clears the
root-cause, and when this code clears the received interrupt status?

> +static int tegra_pcie_disable_msi(struct platform_device *pdev)

Should this free pcie->msi->pages?

Why allocate pcie->msi separately; why not include the fields directly
into struct tegra_pcie_info *pcie?

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

* [PATCH v2 06/10] ARM: tegra: pcie: Add MSI support
@ 2012-06-11 21:19       ` Stephen Warren
  0 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-11 21:19 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/11/2012 09:05 AM, Thierry Reding wrote:
> This commit adds support for message signaled interrupts to the Tegra
> PCIe controller. Based on code by Krishna Kishore <kthota@nvidia.com>.

> diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c

> +static irqreturn_t tegra_pcie_msi_irq(int irq, void *data)
...
> +			irq = irq_find_mapping(pcie->msi->domain, index);
> +			if (irq) {
> +				if (test_bit(index, pcie->msi->used))
> +					generic_handle_irq(irq);

This invokes the handler first ...

...
> +			/* clear the interrupt */
> +			afi_writel(pcie, 1 << offset, AFI_MSI_VEC0 + i * 4);
> +			/* see if there's any more pending in this vector */
> +			reg = afi_readl(pcie, AFI_MSI_VEC0 + i * 4);

... then clears the interrupt status in the PCIe controller. Won't that
lose interrupts if one is raised between when the handler clears the
root-cause, and when this code clears the received interrupt status?

> +static int tegra_pcie_disable_msi(struct platform_device *pdev)

Should this free pcie->msi->pages?

Why allocate pcie->msi separately; why not include the fields directly
into struct tegra_pcie_info *pcie?

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

* Re: [PATCH v2 05/10] ARM: tegra: Rewrite PCIe support as a driver
  2012-06-11 15:05   ` Thierry Reding
  (?)
@ 2012-06-11 21:22       ` Stephen Warren
  -1 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-11 21:22 UTC (permalink / raw)
  To: Thierry Reding
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jesse Barnes,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, Grant Likely, Rob Herring,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Russell King,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Colin Cross,
	Olof Johansson

On 06/11/2012 09:05 AM, Thierry Reding wrote:
> This commit adds a platform device driver for the PCIe controller on
> Tegra SOCs. Current users of the old code (TrimSlice and Harmony) are
> converted and now initialize and register a corresponding platform
> device.

> -static int tegra_pcie_clocks_get(void)
> +static int tegra_pcie_clocks_get(struct tegra_pcie_info *pcie)
>  {
>  	int err;
>  
> -	tegra_pcie.pex_clk = clk_get(NULL, "pex");
> -	if (IS_ERR(tegra_pcie.pex_clk))
> -		return PTR_ERR(tegra_pcie.pex_clk);
> +	pcie->pex_clk = clk_get(NULL, "pex");
> +	if (IS_ERR(pcie->pex_clk))
> +		return PTR_ERR(pcie->pex_clk);

While we're changing this, can we convert this to devm_clk_get(), and ...

> -	tegra_pcie.regs = ioremap_nocache(TEGRA_PCIE_BASE, PCIE_IOMAP_SZ);
> -	if (tegra_pcie.regs == NULL) {
> -		pr_err("PCIE: Failed to map PCI/AFI registers\n");
> +	regs = request_mem_region(regs->start, resource_size(regs), "PCI/AFI");
> +	if (regs == NULL) {
> +		dev_err(&pdev->dev, "failed to request PCI/AFI region: %d\n", err);
> +		goto err_req_reg;
> +	}
> +
> +	pcie->regs = ioremap_nocache(regs->start, resource_size(regs));
> +	if (pcie->regs == NULL) {
> +		dev_err(&pdev->dev, "failed to map PCI/AFI registers\n");
>  		err = -ENOMEM;
>  		goto err_map_reg;
>  	}

... that to devm_request_and_ioremap(). That would allow a bunch of the
cleanup code to be deleted rather than just modified.

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

* Re: [PATCH v2 05/10] ARM: tegra: Rewrite PCIe support as a driver
@ 2012-06-11 21:22       ` Stephen Warren
  0 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-11 21:22 UTC (permalink / raw)
  To: Thierry Reding
  Cc: linux-tegra, Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson

On 06/11/2012 09:05 AM, Thierry Reding wrote:
> This commit adds a platform device driver for the PCIe controller on
> Tegra SOCs. Current users of the old code (TrimSlice and Harmony) are
> converted and now initialize and register a corresponding platform
> device.

> -static int tegra_pcie_clocks_get(void)
> +static int tegra_pcie_clocks_get(struct tegra_pcie_info *pcie)
>  {
>  	int err;
>  
> -	tegra_pcie.pex_clk = clk_get(NULL, "pex");
> -	if (IS_ERR(tegra_pcie.pex_clk))
> -		return PTR_ERR(tegra_pcie.pex_clk);
> +	pcie->pex_clk = clk_get(NULL, "pex");
> +	if (IS_ERR(pcie->pex_clk))
> +		return PTR_ERR(pcie->pex_clk);

While we're changing this, can we convert this to devm_clk_get(), and ...

> -	tegra_pcie.regs = ioremap_nocache(TEGRA_PCIE_BASE, PCIE_IOMAP_SZ);
> -	if (tegra_pcie.regs == NULL) {
> -		pr_err("PCIE: Failed to map PCI/AFI registers\n");
> +	regs = request_mem_region(regs->start, resource_size(regs), "PCI/AFI");
> +	if (regs == NULL) {
> +		dev_err(&pdev->dev, "failed to request PCI/AFI region: %d\n", err);
> +		goto err_req_reg;
> +	}
> +
> +	pcie->regs = ioremap_nocache(regs->start, resource_size(regs));
> +	if (pcie->regs == NULL) {
> +		dev_err(&pdev->dev, "failed to map PCI/AFI registers\n");
>  		err = -ENOMEM;
>  		goto err_map_reg;
>  	}

... that to devm_request_and_ioremap(). That would allow a bunch of the
cleanup code to be deleted rather than just modified.

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

* [PATCH v2 05/10] ARM: tegra: Rewrite PCIe support as a driver
@ 2012-06-11 21:22       ` Stephen Warren
  0 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-11 21:22 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/11/2012 09:05 AM, Thierry Reding wrote:
> This commit adds a platform device driver for the PCIe controller on
> Tegra SOCs. Current users of the old code (TrimSlice and Harmony) are
> converted and now initialize and register a corresponding platform
> device.

> -static int tegra_pcie_clocks_get(void)
> +static int tegra_pcie_clocks_get(struct tegra_pcie_info *pcie)
>  {
>  	int err;
>  
> -	tegra_pcie.pex_clk = clk_get(NULL, "pex");
> -	if (IS_ERR(tegra_pcie.pex_clk))
> -		return PTR_ERR(tegra_pcie.pex_clk);
> +	pcie->pex_clk = clk_get(NULL, "pex");
> +	if (IS_ERR(pcie->pex_clk))
> +		return PTR_ERR(pcie->pex_clk);

While we're changing this, can we convert this to devm_clk_get(), and ...

> -	tegra_pcie.regs = ioremap_nocache(TEGRA_PCIE_BASE, PCIE_IOMAP_SZ);
> -	if (tegra_pcie.regs == NULL) {
> -		pr_err("PCIE: Failed to map PCI/AFI registers\n");
> +	regs = request_mem_region(regs->start, resource_size(regs), "PCI/AFI");
> +	if (regs == NULL) {
> +		dev_err(&pdev->dev, "failed to request PCI/AFI region: %d\n", err);
> +		goto err_req_reg;
> +	}
> +
> +	pcie->regs = ioremap_nocache(regs->start, resource_size(regs));
> +	if (pcie->regs == NULL) {
> +		dev_err(&pdev->dev, "failed to map PCI/AFI registers\n");
>  		err = -ENOMEM;
>  		goto err_map_reg;
>  	}

... that to devm_request_and_ioremap(). That would allow a bunch of the
cleanup code to be deleted rather than just modified.

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-11 15:05     ` Thierry Reding
@ 2012-06-11 21:33       ` Stephen Warren
  -1 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-11 21:33 UTC (permalink / raw)
  To: Thierry Reding
  Cc: linux-tegra, Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson

On 06/11/2012 09:05 AM, Thierry Reding wrote:
> This commit adds support for instantiating the Tegra PCIe controller
> from a device tree.

> +++ b/Documentation/devicetree/bindings/pci/tegra-pcie.txt

Can we please name this nvidia,tegra20-pcie.txt to match the naming of
all the other Tegra bindings.

> +Required properties:
> +- compatible: "nvidia,tegra20-pcie"
> +- reg: physical base address and length of the controller's registers

Since there's more than one range now, that should specify how many
entries are required and what they represent.

> +Optional properties:
> +- pex-clk-supply: supply voltage for internal reference clock
> +- vdd-supply: power supply for controller (1.05V)

Those shouldn't be optional. If the board has no regulator, the board's
.dts should provide a fixed always-on regulator that those properties
can refer to, so that the driver can always get() those regulators.

> diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi

> +	pci {
...
> +		status = "disable";

That should be "disabled"; sorry for providing a bad example.

> diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c

> +static struct tegra_pcie_pdata *tegra_pcie_parse_dt(struct platform_device *pdev)

> +	if (of_find_property(node, "vdd-supply", NULL)) {

As mentioned above, that if statement should be removed, since the
regulators shouldn't be optional.

> +		pcie->vdd_supply = regulator_get(&pdev->dev, "vdd");

Those could be devm_regulator_get(). Then tegra_pcie_remove() wouldn't
have to put() them.

> +	for (i = 0; i < TEGRA_PCIE_MAX_PORTS; i++)
> +		pdata->enable_ports[i] = true;

Shouldn't the DT indicate which ports are used? I assume there's some
reason that the existing driver allows that to be configured, rather
than always enabling all ports. At least, enumeration time wasted on
non-existent ports springs to mind, and perhaps attempting to enable
port 1 when port 0 is x4 and using all the lanes would cause errors in
port 0?

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-11 21:33       ` Stephen Warren
  0 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-11 21:33 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/11/2012 09:05 AM, Thierry Reding wrote:
> This commit adds support for instantiating the Tegra PCIe controller
> from a device tree.

> +++ b/Documentation/devicetree/bindings/pci/tegra-pcie.txt

Can we please name this nvidia,tegra20-pcie.txt to match the naming of
all the other Tegra bindings.

> +Required properties:
> +- compatible: "nvidia,tegra20-pcie"
> +- reg: physical base address and length of the controller's registers

Since there's more than one range now, that should specify how many
entries are required and what they represent.

> +Optional properties:
> +- pex-clk-supply: supply voltage for internal reference clock
> +- vdd-supply: power supply for controller (1.05V)

Those shouldn't be optional. If the board has no regulator, the board's
.dts should provide a fixed always-on regulator that those properties
can refer to, so that the driver can always get() those regulators.

> diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi

> +	pci {
...
> +		status = "disable";

That should be "disabled"; sorry for providing a bad example.

> diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c

> +static struct tegra_pcie_pdata *tegra_pcie_parse_dt(struct platform_device *pdev)

> +	if (of_find_property(node, "vdd-supply", NULL)) {

As mentioned above, that if statement should be removed, since the
regulators shouldn't be optional.

> +		pcie->vdd_supply = regulator_get(&pdev->dev, "vdd");

Those could be devm_regulator_get(). Then tegra_pcie_remove() wouldn't
have to put() them.

> +	for (i = 0; i < TEGRA_PCIE_MAX_PORTS; i++)
> +		pdata->enable_ports[i] = true;

Shouldn't the DT indicate which ports are used? I assume there's some
reason that the existing driver allows that to be configured, rather
than always enabling all ports. At least, enumeration time wasted on
non-existent ports springs to mind, and perhaps attempting to enable
port 1 when port 0 is x4 and using all the lanes would cause errors in
port 0?

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

* Re: [PATCH v2 08/10] ARM: tegra: harmony: Initialize regulators from DT
  2012-06-11 15:05   ` Thierry Reding
@ 2012-06-11 21:36     ` Stephen Warren
  -1 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-11 21:36 UTC (permalink / raw)
  To: Thierry Reding
  Cc: linux-tegra, Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson

On 06/11/2012 09:05 AM, Thierry Reding wrote:
> Device tree support for the TPS6586x PMU used on Harmony has recently
> been added. This commit adds the required device tree nodes to probe the
> PMU from the device tree.

> diff --git a/arch/arm/boot/dts/tegra-harmony.dts b/arch/arm/boot/dts/tegra-harmony.dts

> +		tps6586x@34 {
> +			compatible = "ti,tps6586x";
> +			reg = <0x34>;
> +			interrupts = <0 88 0x4>;
> +
> +			#gpio-cells = <2>;
> +			gpio-controller;
> +
> +			regulators {

Per the TPS65911 discussion on regulator bindings, this node should have:

	#address-cells = <1>;
	#size-cells = <0>;

> +				sm0 {

Each of these nodes should be named regulator@0, regulator@1, etc.

Within each of these nodes, you need a matching reg property.

	reg = <0>;

and something to identify which regulator within the chip this node
configurations, although I don't think we've reached a final decision on
the property name.

See the the following for details:

http://www.spinics.net/lists/linux-tegra/msg05577.html

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

* [PATCH v2 08/10] ARM: tegra: harmony: Initialize regulators from DT
@ 2012-06-11 21:36     ` Stephen Warren
  0 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-11 21:36 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/11/2012 09:05 AM, Thierry Reding wrote:
> Device tree support for the TPS6586x PMU used on Harmony has recently
> been added. This commit adds the required device tree nodes to probe the
> PMU from the device tree.

> diff --git a/arch/arm/boot/dts/tegra-harmony.dts b/arch/arm/boot/dts/tegra-harmony.dts

> +		tps6586x at 34 {
> +			compatible = "ti,tps6586x";
> +			reg = <0x34>;
> +			interrupts = <0 88 0x4>;
> +
> +			#gpio-cells = <2>;
> +			gpio-controller;
> +
> +			regulators {

Per the TPS65911 discussion on regulator bindings, this node should have:

	#address-cells = <1>;
	#size-cells = <0>;

> +				sm0 {

Each of these nodes should be named regulator at 0, regulator at 1, etc.

Within each of these nodes, you need a matching reg property.

	reg = <0>;

and something to identify which regulator within the chip this node
configurations, although I don't think we've reached a final decision on
the property name.

See the the following for details:

http://www.spinics.net/lists/linux-tegra/msg05577.html

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

* Re: [PATCH v2 09/10] ARM: tegra: harmony: Initialize PCIe from DT
  2012-06-11 15:05     ` Thierry Reding
  (?)
@ 2012-06-11 21:41         ` Stephen Warren
  -1 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-11 21:41 UTC (permalink / raw)
  To: Thierry Reding
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jesse Barnes,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, Grant Likely, Rob Herring,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Russell King,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Colin Cross,
	Olof Johansson

On 06/11/2012 09:05 AM, Thierry Reding wrote:
> With the device tree support in place, probe the PCIe controller from
> the device tree and remove the corresponding workaround in the board
> file.

> diff --git a/arch/arm/boot/dts/tegra-harmony.dts b/arch/arm/boot/dts/tegra-harmony.dts

> +	pci_vdd_reg: fixedregulator@0 {

I think that'd usually just be "regulator@0".

If you need the "@0" part to differentiate between multiple regulators,
the node needs a reg property too:

	reg = <0 0>;

although then I wonder about putting the regulator under the root node,
since the address wouldn't really make sense...

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

* Re: [PATCH v2 09/10] ARM: tegra: harmony: Initialize PCIe from DT
@ 2012-06-11 21:41         ` Stephen Warren
  0 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-11 21:41 UTC (permalink / raw)
  To: Thierry Reding
  Cc: linux-tegra, Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson

On 06/11/2012 09:05 AM, Thierry Reding wrote:
> With the device tree support in place, probe the PCIe controller from
> the device tree and remove the corresponding workaround in the board
> file.

> diff --git a/arch/arm/boot/dts/tegra-harmony.dts b/arch/arm/boot/dts/tegra-harmony.dts

> +	pci_vdd_reg: fixedregulator@0 {

I think that'd usually just be "regulator@0".

If you need the "@0" part to differentiate between multiple regulators,
the node needs a reg property too:

	reg = <0 0>;

although then I wonder about putting the regulator under the root node,
since the address wouldn't really make sense...

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

* [PATCH v2 09/10] ARM: tegra: harmony: Initialize PCIe from DT
@ 2012-06-11 21:41         ` Stephen Warren
  0 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-11 21:41 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/11/2012 09:05 AM, Thierry Reding wrote:
> With the device tree support in place, probe the PCIe controller from
> the device tree and remove the corresponding workaround in the board
> file.

> diff --git a/arch/arm/boot/dts/tegra-harmony.dts b/arch/arm/boot/dts/tegra-harmony.dts

> +	pci_vdd_reg: fixedregulator at 0 {

I think that'd usually just be "regulator at 0".

If you need the "@0" part to differentiate between multiple regulators,
the node needs a reg property too:

	reg = <0 0>;

although then I wonder about putting the regulator under the root node,
since the address wouldn't really make sense...

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

* Re: [PATCH v2 05/10] ARM: tegra: Rewrite PCIe support as a driver
  2012-06-11 21:22       ` Stephen Warren
  (?)
@ 2012-06-12  4:59           ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-12  4:59 UTC (permalink / raw)
  To: Stephen Warren
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jesse Barnes,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, Grant Likely, Rob Herring,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Russell King,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Colin Cross,
	Olof Johansson

[-- Attachment #1: Type: text/plain, Size: 1607 bytes --]

* Stephen Warren wrote:
> On 06/11/2012 09:05 AM, Thierry Reding wrote:
> > This commit adds a platform device driver for the PCIe controller on
> > Tegra SOCs. Current users of the old code (TrimSlice and Harmony) are
> > converted and now initialize and register a corresponding platform
> > device.
> 
> > -static int tegra_pcie_clocks_get(void)
> > +static int tegra_pcie_clocks_get(struct tegra_pcie_info *pcie)
> >  {
> >  	int err;
> >  
> > -	tegra_pcie.pex_clk = clk_get(NULL, "pex");
> > -	if (IS_ERR(tegra_pcie.pex_clk))
> > -		return PTR_ERR(tegra_pcie.pex_clk);
> > +	pcie->pex_clk = clk_get(NULL, "pex");
> > +	if (IS_ERR(pcie->pex_clk))
> > +		return PTR_ERR(pcie->pex_clk);
> 
> While we're changing this, can we convert this to devm_clk_get(), and ...

Will do.

> > -	tegra_pcie.regs = ioremap_nocache(TEGRA_PCIE_BASE, PCIE_IOMAP_SZ);
> > -	if (tegra_pcie.regs == NULL) {
> > -		pr_err("PCIE: Failed to map PCI/AFI registers\n");
> > +	regs = request_mem_region(regs->start, resource_size(regs), "PCI/AFI");
> > +	if (regs == NULL) {
> > +		dev_err(&pdev->dev, "failed to request PCI/AFI region: %d\n", err);
> > +		goto err_req_reg;
> > +	}
> > +
> > +	pcie->regs = ioremap_nocache(regs->start, resource_size(regs));
> > +	if (pcie->regs == NULL) {
> > +		dev_err(&pdev->dev, "failed to map PCI/AFI registers\n");
> >  		err = -ENOMEM;
> >  		goto err_map_reg;
> >  	}
> 
> ... that to devm_request_and_ioremap(). That would allow a bunch of the
> cleanup code to be deleted rather than just modified.

Yes, I'll fix that up as well.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* Re: [PATCH v2 05/10] ARM: tegra: Rewrite PCIe support as a driver
@ 2012-06-12  4:59           ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-12  4:59 UTC (permalink / raw)
  To: Stephen Warren
  Cc: linux-tegra, Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson

[-- Attachment #1: Type: text/plain, Size: 1607 bytes --]

* Stephen Warren wrote:
> On 06/11/2012 09:05 AM, Thierry Reding wrote:
> > This commit adds a platform device driver for the PCIe controller on
> > Tegra SOCs. Current users of the old code (TrimSlice and Harmony) are
> > converted and now initialize and register a corresponding platform
> > device.
> 
> > -static int tegra_pcie_clocks_get(void)
> > +static int tegra_pcie_clocks_get(struct tegra_pcie_info *pcie)
> >  {
> >  	int err;
> >  
> > -	tegra_pcie.pex_clk = clk_get(NULL, "pex");
> > -	if (IS_ERR(tegra_pcie.pex_clk))
> > -		return PTR_ERR(tegra_pcie.pex_clk);
> > +	pcie->pex_clk = clk_get(NULL, "pex");
> > +	if (IS_ERR(pcie->pex_clk))
> > +		return PTR_ERR(pcie->pex_clk);
> 
> While we're changing this, can we convert this to devm_clk_get(), and ...

Will do.

> > -	tegra_pcie.regs = ioremap_nocache(TEGRA_PCIE_BASE, PCIE_IOMAP_SZ);
> > -	if (tegra_pcie.regs == NULL) {
> > -		pr_err("PCIE: Failed to map PCI/AFI registers\n");
> > +	regs = request_mem_region(regs->start, resource_size(regs), "PCI/AFI");
> > +	if (regs == NULL) {
> > +		dev_err(&pdev->dev, "failed to request PCI/AFI region: %d\n", err);
> > +		goto err_req_reg;
> > +	}
> > +
> > +	pcie->regs = ioremap_nocache(regs->start, resource_size(regs));
> > +	if (pcie->regs == NULL) {
> > +		dev_err(&pdev->dev, "failed to map PCI/AFI registers\n");
> >  		err = -ENOMEM;
> >  		goto err_map_reg;
> >  	}
> 
> ... that to devm_request_and_ioremap(). That would allow a bunch of the
> cleanup code to be deleted rather than just modified.

Yes, I'll fix that up as well.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* [PATCH v2 05/10] ARM: tegra: Rewrite PCIe support as a driver
@ 2012-06-12  4:59           ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-12  4:59 UTC (permalink / raw)
  To: linux-arm-kernel

* Stephen Warren wrote:
> On 06/11/2012 09:05 AM, Thierry Reding wrote:
> > This commit adds a platform device driver for the PCIe controller on
> > Tegra SOCs. Current users of the old code (TrimSlice and Harmony) are
> > converted and now initialize and register a corresponding platform
> > device.
> 
> > -static int tegra_pcie_clocks_get(void)
> > +static int tegra_pcie_clocks_get(struct tegra_pcie_info *pcie)
> >  {
> >  	int err;
> >  
> > -	tegra_pcie.pex_clk = clk_get(NULL, "pex");
> > -	if (IS_ERR(tegra_pcie.pex_clk))
> > -		return PTR_ERR(tegra_pcie.pex_clk);
> > +	pcie->pex_clk = clk_get(NULL, "pex");
> > +	if (IS_ERR(pcie->pex_clk))
> > +		return PTR_ERR(pcie->pex_clk);
> 
> While we're changing this, can we convert this to devm_clk_get(), and ...

Will do.

> > -	tegra_pcie.regs = ioremap_nocache(TEGRA_PCIE_BASE, PCIE_IOMAP_SZ);
> > -	if (tegra_pcie.regs == NULL) {
> > -		pr_err("PCIE: Failed to map PCI/AFI registers\n");
> > +	regs = request_mem_region(regs->start, resource_size(regs), "PCI/AFI");
> > +	if (regs == NULL) {
> > +		dev_err(&pdev->dev, "failed to request PCI/AFI region: %d\n", err);
> > +		goto err_req_reg;
> > +	}
> > +
> > +	pcie->regs = ioremap_nocache(regs->start, resource_size(regs));
> > +	if (pcie->regs == NULL) {
> > +		dev_err(&pdev->dev, "failed to map PCI/AFI registers\n");
> >  		err = -ENOMEM;
> >  		goto err_map_reg;
> >  	}
> 
> ... that to devm_request_and_ioremap(). That would allow a bunch of the
> cleanup code to be deleted rather than just modified.

Yes, I'll fix that up as well.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120612/4cfb6a75/attachment.sig>

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

* Re: [PATCH v2 06/10] ARM: tegra: pcie: Add MSI support
  2012-06-11 21:19       ` Stephen Warren
@ 2012-06-12  5:07         ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-12  5:07 UTC (permalink / raw)
  To: Stephen Warren
  Cc: linux-tegra, Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson

[-- Attachment #1: Type: text/plain, Size: 1959 bytes --]

* Stephen Warren wrote:
> On 06/11/2012 09:05 AM, Thierry Reding wrote:
> > This commit adds support for message signaled interrupts to the Tegra
> > PCIe controller. Based on code by Krishna Kishore <kthota@nvidia.com>.
> 
> > diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c
> 
> > +static irqreturn_t tegra_pcie_msi_irq(int irq, void *data)
> ...
> > +			irq = irq_find_mapping(pcie->msi->domain, index);
> > +			if (irq) {
> > +				if (test_bit(index, pcie->msi->used))
> > +					generic_handle_irq(irq);
> 
> This invokes the handler first ...
> 
> ...
> > +			/* clear the interrupt */
> > +			afi_writel(pcie, 1 << offset, AFI_MSI_VEC0 + i * 4);
> > +			/* see if there's any more pending in this vector */
> > +			reg = afi_readl(pcie, AFI_MSI_VEC0 + i * 4);
> 
> ... then clears the interrupt status in the PCIe controller. Won't that
> lose interrupts if one is raised between when the handler clears the
> root-cause, and when this code clears the received interrupt status?

It certainly doesn't follow the conventional way of clearing the interrupt
first. I carried this from the original MSI patch, but I'll move the
interrupt clearing up and retest.

> > +static int tegra_pcie_disable_msi(struct platform_device *pdev)
> 
> Should this free pcie->msi->pages?

Yes it should. I actually mention making that change in the changelog but
in fact didn't.

> Why allocate pcie->msi separately; why not include the fields directly
> into struct tegra_pcie_info *pcie?

For one I find this easier to read. If this wasn't a separate structure, each
of the individual fields would get an msi_ prefix anyway so there isn't much
to be gained from keeping them directly in tegra_pcie_info.

Second, and more importantly, this will keep the size of struct
tegra_pcie_info smaller if PCI_MSI is not selected because there is just one
unused pointer instead of five unused fields.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* [PATCH v2 06/10] ARM: tegra: pcie: Add MSI support
@ 2012-06-12  5:07         ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-12  5:07 UTC (permalink / raw)
  To: linux-arm-kernel

* Stephen Warren wrote:
> On 06/11/2012 09:05 AM, Thierry Reding wrote:
> > This commit adds support for message signaled interrupts to the Tegra
> > PCIe controller. Based on code by Krishna Kishore <kthota@nvidia.com>.
> 
> > diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c
> 
> > +static irqreturn_t tegra_pcie_msi_irq(int irq, void *data)
> ...
> > +			irq = irq_find_mapping(pcie->msi->domain, index);
> > +			if (irq) {
> > +				if (test_bit(index, pcie->msi->used))
> > +					generic_handle_irq(irq);
> 
> This invokes the handler first ...
> 
> ...
> > +			/* clear the interrupt */
> > +			afi_writel(pcie, 1 << offset, AFI_MSI_VEC0 + i * 4);
> > +			/* see if there's any more pending in this vector */
> > +			reg = afi_readl(pcie, AFI_MSI_VEC0 + i * 4);
> 
> ... then clears the interrupt status in the PCIe controller. Won't that
> lose interrupts if one is raised between when the handler clears the
> root-cause, and when this code clears the received interrupt status?

It certainly doesn't follow the conventional way of clearing the interrupt
first. I carried this from the original MSI patch, but I'll move the
interrupt clearing up and retest.

> > +static int tegra_pcie_disable_msi(struct platform_device *pdev)
> 
> Should this free pcie->msi->pages?

Yes it should. I actually mention making that change in the changelog but
in fact didn't.

> Why allocate pcie->msi separately; why not include the fields directly
> into struct tegra_pcie_info *pcie?

For one I find this easier to read. If this wasn't a separate structure, each
of the individual fields would get an msi_ prefix anyway so there isn't much
to be gained from keeping them directly in tegra_pcie_info.

Second, and more importantly, this will keep the size of struct
tegra_pcie_info smaller if PCI_MSI is not selected because there is just one
unused pointer instead of five unused fields.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120612/ca927330/attachment.sig>

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

* Re: [PATCH v2 06/10] ARM: tegra: pcie: Add MSI support
  2012-06-12  5:07         ` Thierry Reding
@ 2012-06-12  5:33           ` Stephen Warren
  -1 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-12  5:33 UTC (permalink / raw)
  To: Thierry Reding
  Cc: linux-tegra, Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson

On 06/11/2012 11:07 PM, Thierry Reding wrote:
> * Stephen Warren wrote:
>> On 06/11/2012 09:05 AM, Thierry Reding wrote:
>>> This commit adds support for message signaled interrupts to the
>>> Tegra PCIe controller. Based on code by Krishna Kishore
>>> <kthota@nvidia.com>.
...
>> Why allocate pcie->msi separately; why not include the fields
>> directly into struct tegra_pcie_info *pcie?
...
> Second, and more importantly, this will keep the size of struct 
> tegra_pcie_info smaller if PCI_MSI is not selected because there is
> just one unused pointer instead of five unused fields.

Well, you can always ifdef out the structure fields too, right?

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

* [PATCH v2 06/10] ARM: tegra: pcie: Add MSI support
@ 2012-06-12  5:33           ` Stephen Warren
  0 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-12  5:33 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/11/2012 11:07 PM, Thierry Reding wrote:
> * Stephen Warren wrote:
>> On 06/11/2012 09:05 AM, Thierry Reding wrote:
>>> This commit adds support for message signaled interrupts to the
>>> Tegra PCIe controller. Based on code by Krishna Kishore
>>> <kthota@nvidia.com>.
...
>> Why allocate pcie->msi separately; why not include the fields
>> directly into struct tegra_pcie_info *pcie?
...
> Second, and more importantly, this will keep the size of struct 
> tegra_pcie_info smaller if PCI_MSI is not selected because there is
> just one unused pointer instead of five unused fields.

Well, you can always ifdef out the structure fields too, right?

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

* Re: [PATCH v2 06/10] ARM: tegra: pcie: Add MSI support
  2012-06-12  5:33           ` Stephen Warren
  (?)
@ 2012-06-12  5:41               ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-12  5:41 UTC (permalink / raw)
  To: Stephen Warren
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jesse Barnes,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, Grant Likely, Rob Herring,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Russell King,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Colin Cross,
	Olof Johansson

[-- Attachment #1: Type: text/plain, Size: 1217 bytes --]

* Stephen Warren wrote:
> On 06/11/2012 11:07 PM, Thierry Reding wrote:
> > * Stephen Warren wrote:
> >> On 06/11/2012 09:05 AM, Thierry Reding wrote:
> >>> This commit adds support for message signaled interrupts to the
> >>> Tegra PCIe controller. Based on code by Krishna Kishore
> >>> <kthota-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>.
> ...
> >> Why allocate pcie->msi separately; why not include the fields
> >> directly into struct tegra_pcie_info *pcie?
> ...
> > Second, and more importantly, this will keep the size of struct 
> > tegra_pcie_info smaller if PCI_MSI is not selected because there is
> > just one unused pointer instead of five unused fields.
> 
> Well, you can always ifdef out the structure fields too, right?

Not if you use the IS_ENABLED() macro. It's supposed to increase compile
coverage for a trade-off in memory usage because like in this case some
fields may be unused.

I find this very convenient because it prevents situations where build
errors don't show up until somebody uses the code in an unusual
configuration. For developers this makes it really easy because they don't
have to test every possible permutation of configuration options.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* Re: [PATCH v2 06/10] ARM: tegra: pcie: Add MSI support
@ 2012-06-12  5:41               ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-12  5:41 UTC (permalink / raw)
  To: Stephen Warren
  Cc: linux-tegra, Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson

[-- Attachment #1: Type: text/plain, Size: 1188 bytes --]

* Stephen Warren wrote:
> On 06/11/2012 11:07 PM, Thierry Reding wrote:
> > * Stephen Warren wrote:
> >> On 06/11/2012 09:05 AM, Thierry Reding wrote:
> >>> This commit adds support for message signaled interrupts to the
> >>> Tegra PCIe controller. Based on code by Krishna Kishore
> >>> <kthota@nvidia.com>.
> ...
> >> Why allocate pcie->msi separately; why not include the fields
> >> directly into struct tegra_pcie_info *pcie?
> ...
> > Second, and more importantly, this will keep the size of struct 
> > tegra_pcie_info smaller if PCI_MSI is not selected because there is
> > just one unused pointer instead of five unused fields.
> 
> Well, you can always ifdef out the structure fields too, right?

Not if you use the IS_ENABLED() macro. It's supposed to increase compile
coverage for a trade-off in memory usage because like in this case some
fields may be unused.

I find this very convenient because it prevents situations where build
errors don't show up until somebody uses the code in an unusual
configuration. For developers this makes it really easy because they don't
have to test every possible permutation of configuration options.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* [PATCH v2 06/10] ARM: tegra: pcie: Add MSI support
@ 2012-06-12  5:41               ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-12  5:41 UTC (permalink / raw)
  To: linux-arm-kernel

* Stephen Warren wrote:
> On 06/11/2012 11:07 PM, Thierry Reding wrote:
> > * Stephen Warren wrote:
> >> On 06/11/2012 09:05 AM, Thierry Reding wrote:
> >>> This commit adds support for message signaled interrupts to the
> >>> Tegra PCIe controller. Based on code by Krishna Kishore
> >>> <kthota@nvidia.com>.
> ...
> >> Why allocate pcie->msi separately; why not include the fields
> >> directly into struct tegra_pcie_info *pcie?
> ...
> > Second, and more importantly, this will keep the size of struct 
> > tegra_pcie_info smaller if PCI_MSI is not selected because there is
> > just one unused pointer instead of five unused fields.
> 
> Well, you can always ifdef out the structure fields too, right?

Not if you use the IS_ENABLED() macro. It's supposed to increase compile
coverage for a trade-off in memory usage because like in this case some
fields may be unused.

I find this very convenient because it prevents situations where build
errors don't show up until somebody uses the code in an unusual
configuration. For developers this makes it really easy because they don't
have to test every possible permutation of configuration options.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120612/2e8846d7/attachment.sig>

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

* Re: [PATCH v2 09/10] ARM: tegra: harmony: Initialize PCIe from DT
  2012-06-11 21:41         ` Stephen Warren
  (?)
@ 2012-06-12  5:48             ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-12  5:48 UTC (permalink / raw)
  To: Stephen Warren
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jesse Barnes,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, Grant Likely, Rob Herring,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Russell King,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Colin Cross,
	Olof Johansson

[-- Attachment #1: Type: text/plain, Size: 1075 bytes --]

* Stephen Warren wrote:
> On 06/11/2012 09:05 AM, Thierry Reding wrote:
> > With the device tree support in place, probe the PCIe controller from
> > the device tree and remove the corresponding workaround in the board
> > file.
> 
> > diff --git a/arch/arm/boot/dts/tegra-harmony.dts b/arch/arm/boot/dts/tegra-harmony.dts
> 
> > +	pci_vdd_reg: fixedregulator@0 {
> 
> I think that'd usually just be "regulator@0".
> 
> If you need the "@0" part to differentiate between multiple regulators,
> the node needs a reg property too:
> 
> 	reg = <0 0>;
> 
> although then I wonder about putting the regulator under the root node,
> since the address wouldn't really make sense...

Perhaps we should add a new "regulators" node under the root node to collect
this kind of regulators that don't fit anywhere else. Looking at the code,
something like this should work:

	/ {
		...

		regulators {
			compatible = "simple-bus";
			#address-cells = <1>;
			#size-cells = <0>;

			pci_vdd_reg: regulator@0 {
				reg = <0>;
			};
		};
	};

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* Re: [PATCH v2 09/10] ARM: tegra: harmony: Initialize PCIe from DT
@ 2012-06-12  5:48             ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-12  5:48 UTC (permalink / raw)
  To: Stephen Warren
  Cc: linux-tegra, Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson

[-- Attachment #1: Type: text/plain, Size: 1075 bytes --]

* Stephen Warren wrote:
> On 06/11/2012 09:05 AM, Thierry Reding wrote:
> > With the device tree support in place, probe the PCIe controller from
> > the device tree and remove the corresponding workaround in the board
> > file.
> 
> > diff --git a/arch/arm/boot/dts/tegra-harmony.dts b/arch/arm/boot/dts/tegra-harmony.dts
> 
> > +	pci_vdd_reg: fixedregulator@0 {
> 
> I think that'd usually just be "regulator@0".
> 
> If you need the "@0" part to differentiate between multiple regulators,
> the node needs a reg property too:
> 
> 	reg = <0 0>;
> 
> although then I wonder about putting the regulator under the root node,
> since the address wouldn't really make sense...

Perhaps we should add a new "regulators" node under the root node to collect
this kind of regulators that don't fit anywhere else. Looking at the code,
something like this should work:

	/ {
		...

		regulators {
			compatible = "simple-bus";
			#address-cells = <1>;
			#size-cells = <0>;

			pci_vdd_reg: regulator@0 {
				reg = <0>;
			};
		};
	};

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* [PATCH v2 09/10] ARM: tegra: harmony: Initialize PCIe from DT
@ 2012-06-12  5:48             ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-12  5:48 UTC (permalink / raw)
  To: linux-arm-kernel

* Stephen Warren wrote:
> On 06/11/2012 09:05 AM, Thierry Reding wrote:
> > With the device tree support in place, probe the PCIe controller from
> > the device tree and remove the corresponding workaround in the board
> > file.
> 
> > diff --git a/arch/arm/boot/dts/tegra-harmony.dts b/arch/arm/boot/dts/tegra-harmony.dts
> 
> > +	pci_vdd_reg: fixedregulator at 0 {
> 
> I think that'd usually just be "regulator at 0".
> 
> If you need the "@0" part to differentiate between multiple regulators,
> the node needs a reg property too:
> 
> 	reg = <0 0>;
> 
> although then I wonder about putting the regulator under the root node,
> since the address wouldn't really make sense...

Perhaps we should add a new "regulators" node under the root node to collect
this kind of regulators that don't fit anywhere else. Looking at the code,
something like this should work:

	/ {
		...

		regulators {
			compatible = "simple-bus";
			#address-cells = <1>;
			#size-cells = <0>;

			pci_vdd_reg: regulator at 0 {
				reg = <0>;
			};
		};
	};

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120612/4b13eac2/attachment.sig>

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

* Re: [PATCH v2 06/10] ARM: tegra: pcie: Add MSI support
  2012-06-12  5:07         ` Thierry Reding
  (?)
@ 2012-06-12  6:10             ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-12  6:10 UTC (permalink / raw)
  To: Stephen Warren
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jesse Barnes,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, Grant Likely, Rob Herring,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Russell King,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Colin Cross,
	Olof Johansson

[-- Attachment #1: Type: text/plain, Size: 677 bytes --]

* Thierry Reding wrote:
> * Stephen Warren wrote:
> > On 06/11/2012 09:05 AM, Thierry Reding wrote:
[...]
> > > +static int tegra_pcie_disable_msi(struct platform_device *pdev)
> > 
> > Should this free pcie->msi->pages?
> 
> Yes it should. I actually mention making that change in the changelog but
> in fact didn't.

This is really moot because the driver cannot be built as a module currently
because arch_setup_msi_irq() and arch_teardown_msi_irq() need to be built-in
so tegra_pcie_disable_msi() will be called only just before the machine is
shut down.

Perhaps this is something that should be addressed? Or is it just not worth
the effort?

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* Re: [PATCH v2 06/10] ARM: tegra: pcie: Add MSI support
@ 2012-06-12  6:10             ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-12  6:10 UTC (permalink / raw)
  To: Stephen Warren
  Cc: linux-tegra, Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson

[-- Attachment #1: Type: text/plain, Size: 677 bytes --]

* Thierry Reding wrote:
> * Stephen Warren wrote:
> > On 06/11/2012 09:05 AM, Thierry Reding wrote:
[...]
> > > +static int tegra_pcie_disable_msi(struct platform_device *pdev)
> > 
> > Should this free pcie->msi->pages?
> 
> Yes it should. I actually mention making that change in the changelog but
> in fact didn't.

This is really moot because the driver cannot be built as a module currently
because arch_setup_msi_irq() and arch_teardown_msi_irq() need to be built-in
so tegra_pcie_disable_msi() will be called only just before the machine is
shut down.

Perhaps this is something that should be addressed? Or is it just not worth
the effort?

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* [PATCH v2 06/10] ARM: tegra: pcie: Add MSI support
@ 2012-06-12  6:10             ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-12  6:10 UTC (permalink / raw)
  To: linux-arm-kernel

* Thierry Reding wrote:
> * Stephen Warren wrote:
> > On 06/11/2012 09:05 AM, Thierry Reding wrote:
[...]
> > > +static int tegra_pcie_disable_msi(struct platform_device *pdev)
> > 
> > Should this free pcie->msi->pages?
> 
> Yes it should. I actually mention making that change in the changelog but
> in fact didn't.

This is really moot because the driver cannot be built as a module currently
because arch_setup_msi_irq() and arch_teardown_msi_irq() need to be built-in
so tegra_pcie_disable_msi() will be called only just before the machine is
shut down.

Perhaps this is something that should be addressed? Or is it just not worth
the effort?

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120612/92722551/attachment.sig>

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

* Re: [PATCH v2 08/10] ARM: tegra: harmony: Initialize regulators from DT
  2012-06-11 21:36     ` Stephen Warren
  (?)
@ 2012-06-12  6:13         ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-12  6:13 UTC (permalink / raw)
  To: Stephen Warren
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jesse Barnes,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, Grant Likely, Rob Herring,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Russell King,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Colin Cross,
	Olof Johansson

[-- Attachment #1: Type: text/plain, Size: 1355 bytes --]

* Stephen Warren wrote:
> On 06/11/2012 09:05 AM, Thierry Reding wrote:
> > Device tree support for the TPS6586x PMU used on Harmony has recently
> > been added. This commit adds the required device tree nodes to probe the
> > PMU from the device tree.
> 
> > diff --git a/arch/arm/boot/dts/tegra-harmony.dts b/arch/arm/boot/dts/tegra-harmony.dts
> 
> > +		tps6586x@34 {
> > +			compatible = "ti,tps6586x";
> > +			reg = <0x34>;
> > +			interrupts = <0 88 0x4>;
> > +
> > +			#gpio-cells = <2>;
> > +			gpio-controller;
> > +
> > +			regulators {
> 
> Per the TPS65911 discussion on regulator bindings, this node should have:
> 
> 	#address-cells = <1>;
> 	#size-cells = <0>;
> 
> > +				sm0 {
> 
> Each of these nodes should be named regulator@0, regulator@1, etc.
> 
> Within each of these nodes, you need a matching reg property.
> 
> 	reg = <0>;
> 
> and something to identify which regulator within the chip this node
> configurations, although I don't think we've reached a final decision on
> the property name.
> 
> See the the following for details:
> 
> http://www.spinics.net/lists/linux-tegra/msg05577.html

Okay, I'll monitor that discussion and see what you end up with. I guess I'll
have to update the tps6586x binding when that decision has been reached and
add a patch to this series.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* Re: [PATCH v2 08/10] ARM: tegra: harmony: Initialize regulators from DT
@ 2012-06-12  6:13         ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-12  6:13 UTC (permalink / raw)
  To: Stephen Warren
  Cc: linux-tegra, Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson

[-- Attachment #1: Type: text/plain, Size: 1355 bytes --]

* Stephen Warren wrote:
> On 06/11/2012 09:05 AM, Thierry Reding wrote:
> > Device tree support for the TPS6586x PMU used on Harmony has recently
> > been added. This commit adds the required device tree nodes to probe the
> > PMU from the device tree.
> 
> > diff --git a/arch/arm/boot/dts/tegra-harmony.dts b/arch/arm/boot/dts/tegra-harmony.dts
> 
> > +		tps6586x@34 {
> > +			compatible = "ti,tps6586x";
> > +			reg = <0x34>;
> > +			interrupts = <0 88 0x4>;
> > +
> > +			#gpio-cells = <2>;
> > +			gpio-controller;
> > +
> > +			regulators {
> 
> Per the TPS65911 discussion on regulator bindings, this node should have:
> 
> 	#address-cells = <1>;
> 	#size-cells = <0>;
> 
> > +				sm0 {
> 
> Each of these nodes should be named regulator@0, regulator@1, etc.
> 
> Within each of these nodes, you need a matching reg property.
> 
> 	reg = <0>;
> 
> and something to identify which regulator within the chip this node
> configurations, although I don't think we've reached a final decision on
> the property name.
> 
> See the the following for details:
> 
> http://www.spinics.net/lists/linux-tegra/msg05577.html

Okay, I'll monitor that discussion and see what you end up with. I guess I'll
have to update the tps6586x binding when that decision has been reached and
add a patch to this series.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* [PATCH v2 08/10] ARM: tegra: harmony: Initialize regulators from DT
@ 2012-06-12  6:13         ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-12  6:13 UTC (permalink / raw)
  To: linux-arm-kernel

* Stephen Warren wrote:
> On 06/11/2012 09:05 AM, Thierry Reding wrote:
> > Device tree support for the TPS6586x PMU used on Harmony has recently
> > been added. This commit adds the required device tree nodes to probe the
> > PMU from the device tree.
> 
> > diff --git a/arch/arm/boot/dts/tegra-harmony.dts b/arch/arm/boot/dts/tegra-harmony.dts
> 
> > +		tps6586x at 34 {
> > +			compatible = "ti,tps6586x";
> > +			reg = <0x34>;
> > +			interrupts = <0 88 0x4>;
> > +
> > +			#gpio-cells = <2>;
> > +			gpio-controller;
> > +
> > +			regulators {
> 
> Per the TPS65911 discussion on regulator bindings, this node should have:
> 
> 	#address-cells = <1>;
> 	#size-cells = <0>;
> 
> > +				sm0 {
> 
> Each of these nodes should be named regulator at 0, regulator at 1, etc.
> 
> Within each of these nodes, you need a matching reg property.
> 
> 	reg = <0>;
> 
> and something to identify which regulator within the chip this node
> configurations, although I don't think we've reached a final decision on
> the property name.
> 
> See the the following for details:
> 
> http://www.spinics.net/lists/linux-tegra/msg05577.html

Okay, I'll monitor that discussion and see what you end up with. I guess I'll
have to update the tps6586x binding when that decision has been reached and
add a patch to this series.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120612/d3908777/attachment.sig>

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-11 21:33       ` Stephen Warren
@ 2012-06-12  6:21         ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-12  6:21 UTC (permalink / raw)
  To: Stephen Warren
  Cc: linux-tegra, Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson

[-- Attachment #1: Type: text/plain, Size: 2654 bytes --]

* Stephen Warren wrote:
> On 06/11/2012 09:05 AM, Thierry Reding wrote:
> > This commit adds support for instantiating the Tegra PCIe controller
> > from a device tree.
> 
> > +++ b/Documentation/devicetree/bindings/pci/tegra-pcie.txt
> 
> Can we please name this nvidia,tegra20-pcie.txt to match the naming of
> all the other Tegra bindings.

Yes, will do.

> > +Required properties:
> > +- compatible: "nvidia,tegra20-pcie"
> > +- reg: physical base address and length of the controller's registers
> 
> Since there's more than one range now, that should specify how many
> entries are required and what they represent.

Okay.

> > +Optional properties:
> > +- pex-clk-supply: supply voltage for internal reference clock
> > +- vdd-supply: power supply for controller (1.05V)
> 
> Those shouldn't be optional. If the board has no regulator, the board's
> .dts should provide a fixed always-on regulator that those properties
> can refer to, so that the driver can always get() those regulators.

That'll add more dummy regulators and I don't think sprinkling them across
the DTS is going to work very well. Maybe collecting them under a top-level
"regulators" node is a good option. If you have a better alternative, I'm all
open for it.

> > diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
> 
> > +	pci {
> ...
> > +		status = "disable";
> 
> That should be "disabled"; sorry for providing a bad example.

Yes.

> > diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c
> 
> > +static struct tegra_pcie_pdata *tegra_pcie_parse_dt(struct platform_device *pdev)
> 
> > +	if (of_find_property(node, "vdd-supply", NULL)) {
> 
> As mentioned above, that if statement should be removed, since the
> regulators shouldn't be optional.

Okay.

> > +		pcie->vdd_supply = regulator_get(&pdev->dev, "vdd");
> 
> Those could be devm_regulator_get(). Then tegra_pcie_remove() wouldn't
> have to put() them.

Okay.

> > +	for (i = 0; i < TEGRA_PCIE_MAX_PORTS; i++)
> > +		pdata->enable_ports[i] = true;
> 
> Shouldn't the DT indicate which ports are used? I assume there's some
> reason that the existing driver allows that to be configured, rather
> than always enabling all ports. At least, enumeration time wasted on
> non-existent ports springs to mind, and perhaps attempting to enable
> port 1 when port 0 is x4 and using all the lanes would cause errors in
> port 0?

Yes, that's been on my mind as well. I'm not sure about the best binding for
this. Perhaps something like:

	pci {
		enable-ports = <0 1 2>;
	};

Would do?

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-12  6:21         ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-12  6:21 UTC (permalink / raw)
  To: linux-arm-kernel

* Stephen Warren wrote:
> On 06/11/2012 09:05 AM, Thierry Reding wrote:
> > This commit adds support for instantiating the Tegra PCIe controller
> > from a device tree.
> 
> > +++ b/Documentation/devicetree/bindings/pci/tegra-pcie.txt
> 
> Can we please name this nvidia,tegra20-pcie.txt to match the naming of
> all the other Tegra bindings.

Yes, will do.

> > +Required properties:
> > +- compatible: "nvidia,tegra20-pcie"
> > +- reg: physical base address and length of the controller's registers
> 
> Since there's more than one range now, that should specify how many
> entries are required and what they represent.

Okay.

> > +Optional properties:
> > +- pex-clk-supply: supply voltage for internal reference clock
> > +- vdd-supply: power supply for controller (1.05V)
> 
> Those shouldn't be optional. If the board has no regulator, the board's
> .dts should provide a fixed always-on regulator that those properties
> can refer to, so that the driver can always get() those regulators.

That'll add more dummy regulators and I don't think sprinkling them across
the DTS is going to work very well. Maybe collecting them under a top-level
"regulators" node is a good option. If you have a better alternative, I'm all
open for it.

> > diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
> 
> > +	pci {
> ...
> > +		status = "disable";
> 
> That should be "disabled"; sorry for providing a bad example.

Yes.

> > diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c
> 
> > +static struct tegra_pcie_pdata *tegra_pcie_parse_dt(struct platform_device *pdev)
> 
> > +	if (of_find_property(node, "vdd-supply", NULL)) {
> 
> As mentioned above, that if statement should be removed, since the
> regulators shouldn't be optional.

Okay.

> > +		pcie->vdd_supply = regulator_get(&pdev->dev, "vdd");
> 
> Those could be devm_regulator_get(). Then tegra_pcie_remove() wouldn't
> have to put() them.

Okay.

> > +	for (i = 0; i < TEGRA_PCIE_MAX_PORTS; i++)
> > +		pdata->enable_ports[i] = true;
> 
> Shouldn't the DT indicate which ports are used? I assume there's some
> reason that the existing driver allows that to be configured, rather
> than always enabling all ports. At least, enumeration time wasted on
> non-existent ports springs to mind, and perhaps attempting to enable
> port 1 when port 0 is x4 and using all the lanes would cause errors in
> port 0?

Yes, that's been on my mind as well. I'm not sure about the best binding for
this. Perhaps something like:

	pci {
		enable-ports = <0 1 2>;
	};

Would do?

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120612/525d5b8b/attachment.sig>

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

* Re: [PATCH v2 05/10] ARM: tegra: Rewrite PCIe support as a driver
  2012-06-11 21:09     ` Stephen Warren
  (?)
@ 2012-06-12  6:41         ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-12  6:41 UTC (permalink / raw)
  To: Stephen Warren
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jesse Barnes,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, Grant Likely, Rob Herring,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Russell King,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Colin Cross,
	Olof Johansson

[-- Attachment #1: Type: text/plain, Size: 4739 bytes --]

* Stephen Warren wrote:
> On 06/11/2012 09:05 AM, Thierry Reding wrote:
> > This commit adds a platform device driver for the PCIe controller on
> > Tegra SOCs. Current users of the old code (TrimSlice and Harmony) are
> > converted and now initialize and register a corresponding platform
> > device.
> 
> > diff --git a/arch/arm/mach-tegra/devices.c b/arch/arm/mach-tegra/devices.c
> 
> > +static struct resource tegra_pcie_resources[] = {
> > +	[0] = {
> > +		.start = TEGRA_PCIE_BASE,
> > +		.end = TEGRA_PCIE_BASE + TEGRA_PCIE_SIZE - 1,
> > +		.flags = IORESOURCE_MEM,
> > +	},
> > +	[1] = {
> > +		.start = TEGRA_PCIE_MMIO_BASE,
> > +		.end = TEGRA_PCIE_MMIO_BASE + TEGRA_PCIE_MMIO_SIZE - 1,
> > +		.flags = IORESOURCE_MEM,
> > +	},
> > +	[2] = {
> > +		.start = INT_PCIE_INTR,
> > +		.end = INT_PCIE_INTR,
> > +		.flags = IORESOURCE_IRQ,
> > +	},
> > +};
> 
> I'm not sure those resources either cover all the necessary regions, nor
> are as fine-grained as they should be ...
> 
> In particular, in pcie.c, I see separate afi_writel() and pads_writel()
> implying those are separate regions.
> 
> Also, I see the following hard-code specific addresses, and are still
> used by the driver after conversion:
> 
> > #define MEM_BASE_0              (TEGRA_PCIE_BASE + SZ_256M)
> > #define MEM_SIZE_0              SZ_128M
> > #define MEM_BASE_1              (MEM_BASE_0 + MEM_SIZE_0)
> > #define MEM_SIZE_1              SZ_128M
> > #define PREFETCH_MEM_BASE_0     (MEM_BASE_1 + MEM_SIZE_1)
> > #define PREFETCH_MEM_SIZE_0     SZ_128M
> > #define PREFETCH_MEM_BASE_1     (PREFETCH_MEM_BASE_0 + PREFETCH_MEM_SIZE_0)
> > #define PREFETCH_MEM_SIZE_1     SZ_128M
> 
> Also, there's a comment describing the register layout in terms of a
> number of separate regions:
> 
> > /*
> >  * Tegra2 defines 1GB in the AXI address map for PCIe.
> >  *
> >  * That address space is split into different regions, with sizes and
> >  * offsets as follows:
> >  *
> >  * 0x80000000 - 0x80003fff - PCI controller registers
> >  * 0x80004000 - 0x80103fff - PCI configuration space
> >  * 0x80104000 - 0x80203fff - PCI extended configuration space
> >  * 0x80203fff - 0x803fffff - unused
> >  * 0x80400000 - 0x8040ffff - downstream IO
> >  * 0x80410000 - 0x8fffffff - unused
> >  * 0x90000000 - 0x9fffffff - non-prefetchable memory
> >  * 0xa0000000 - 0xbfffffff - prefetchable memory
> >  */
> 
> (the latter 2 regions at least being also split in half for each of the
> 2 host ports)

I was thinking that maybe each port should be represented as a child node,
but I'm not sure that's going to work too well because the children of the
pci node are supposed to be PCI busses/devices. I'll have to check whether
they could just as well be children of the PCIe port nodes.

That way each port could get an own set of register ranges to better describe
the actual layout. AFAICT the even partitioning of the non-prefetchable and
prefetchable memory regions is arbitrary and it could potentially be useful
to make it configurable via the DT.

> Shouldn't each of these regions be a separate entry in the platform
> device resources.
> 
> This perhaps isn't that relevant for Tegra20 alone, but Tegra30 supports
> 3 host ports instead of 2 (hence I presume alters the internal layout of
> the 1G chunk of physical memory space allocated to PCIe), and moves the
> PCIe area from 2G..3G to 0G..1G (so invalidates the hard-coded
> *_MEM_BASE_* above).

> That said, I'm not sure whether Tegra20's and Tegra30's PCIe controllers
> are similar enough to make a shared driver worthwhile/possible.
> (Although our downstream Android driver appears to handle both with a
> very small number of ifdefs).

> If they are similar, then I think my comments above should be addressed.
> If they are not similar, then I think you can just have a single 1G
> memory region in the resources, and split it up internally, rather than
> needing separate resources for different parts of the address space.

Unfortunately the PCIe controller is very badly documented in the TRM, so
this information is hard to locate (I guess the best source is one of the
downstream drivers).

Last time I looked they seemed to be simple enough to handle the differences
using OF compatible matches. I believe apart from the PCIe area changes there
were some differences in how the MSI were setup.

> While we can easily fix this kind of driver internals so this doesn't
> seem like a big deal, this kind of change would impact the device tree
> binding, so it seems that we need to sort it out before DT conversion.

Yes, we should at least try to get it right from the start.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* Re: [PATCH v2 05/10] ARM: tegra: Rewrite PCIe support as a driver
@ 2012-06-12  6:41         ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-12  6:41 UTC (permalink / raw)
  To: Stephen Warren
  Cc: linux-tegra, Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson

[-- Attachment #1: Type: text/plain, Size: 4739 bytes --]

* Stephen Warren wrote:
> On 06/11/2012 09:05 AM, Thierry Reding wrote:
> > This commit adds a platform device driver for the PCIe controller on
> > Tegra SOCs. Current users of the old code (TrimSlice and Harmony) are
> > converted and now initialize and register a corresponding platform
> > device.
> 
> > diff --git a/arch/arm/mach-tegra/devices.c b/arch/arm/mach-tegra/devices.c
> 
> > +static struct resource tegra_pcie_resources[] = {
> > +	[0] = {
> > +		.start = TEGRA_PCIE_BASE,
> > +		.end = TEGRA_PCIE_BASE + TEGRA_PCIE_SIZE - 1,
> > +		.flags = IORESOURCE_MEM,
> > +	},
> > +	[1] = {
> > +		.start = TEGRA_PCIE_MMIO_BASE,
> > +		.end = TEGRA_PCIE_MMIO_BASE + TEGRA_PCIE_MMIO_SIZE - 1,
> > +		.flags = IORESOURCE_MEM,
> > +	},
> > +	[2] = {
> > +		.start = INT_PCIE_INTR,
> > +		.end = INT_PCIE_INTR,
> > +		.flags = IORESOURCE_IRQ,
> > +	},
> > +};
> 
> I'm not sure those resources either cover all the necessary regions, nor
> are as fine-grained as they should be ...
> 
> In particular, in pcie.c, I see separate afi_writel() and pads_writel()
> implying those are separate regions.
> 
> Also, I see the following hard-code specific addresses, and are still
> used by the driver after conversion:
> 
> > #define MEM_BASE_0              (TEGRA_PCIE_BASE + SZ_256M)
> > #define MEM_SIZE_0              SZ_128M
> > #define MEM_BASE_1              (MEM_BASE_0 + MEM_SIZE_0)
> > #define MEM_SIZE_1              SZ_128M
> > #define PREFETCH_MEM_BASE_0     (MEM_BASE_1 + MEM_SIZE_1)
> > #define PREFETCH_MEM_SIZE_0     SZ_128M
> > #define PREFETCH_MEM_BASE_1     (PREFETCH_MEM_BASE_0 + PREFETCH_MEM_SIZE_0)
> > #define PREFETCH_MEM_SIZE_1     SZ_128M
> 
> Also, there's a comment describing the register layout in terms of a
> number of separate regions:
> 
> > /*
> >  * Tegra2 defines 1GB in the AXI address map for PCIe.
> >  *
> >  * That address space is split into different regions, with sizes and
> >  * offsets as follows:
> >  *
> >  * 0x80000000 - 0x80003fff - PCI controller registers
> >  * 0x80004000 - 0x80103fff - PCI configuration space
> >  * 0x80104000 - 0x80203fff - PCI extended configuration space
> >  * 0x80203fff - 0x803fffff - unused
> >  * 0x80400000 - 0x8040ffff - downstream IO
> >  * 0x80410000 - 0x8fffffff - unused
> >  * 0x90000000 - 0x9fffffff - non-prefetchable memory
> >  * 0xa0000000 - 0xbfffffff - prefetchable memory
> >  */
> 
> (the latter 2 regions at least being also split in half for each of the
> 2 host ports)

I was thinking that maybe each port should be represented as a child node,
but I'm not sure that's going to work too well because the children of the
pci node are supposed to be PCI busses/devices. I'll have to check whether
they could just as well be children of the PCIe port nodes.

That way each port could get an own set of register ranges to better describe
the actual layout. AFAICT the even partitioning of the non-prefetchable and
prefetchable memory regions is arbitrary and it could potentially be useful
to make it configurable via the DT.

> Shouldn't each of these regions be a separate entry in the platform
> device resources.
> 
> This perhaps isn't that relevant for Tegra20 alone, but Tegra30 supports
> 3 host ports instead of 2 (hence I presume alters the internal layout of
> the 1G chunk of physical memory space allocated to PCIe), and moves the
> PCIe area from 2G..3G to 0G..1G (so invalidates the hard-coded
> *_MEM_BASE_* above).

> That said, I'm not sure whether Tegra20's and Tegra30's PCIe controllers
> are similar enough to make a shared driver worthwhile/possible.
> (Although our downstream Android driver appears to handle both with a
> very small number of ifdefs).

> If they are similar, then I think my comments above should be addressed.
> If they are not similar, then I think you can just have a single 1G
> memory region in the resources, and split it up internally, rather than
> needing separate resources for different parts of the address space.

Unfortunately the PCIe controller is very badly documented in the TRM, so
this information is hard to locate (I guess the best source is one of the
downstream drivers).

Last time I looked they seemed to be simple enough to handle the differences
using OF compatible matches. I believe apart from the PCIe area changes there
were some differences in how the MSI were setup.

> While we can easily fix this kind of driver internals so this doesn't
> seem like a big deal, this kind of change would impact the device tree
> binding, so it seems that we need to sort it out before DT conversion.

Yes, we should at least try to get it right from the start.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* [PATCH v2 05/10] ARM: tegra: Rewrite PCIe support as a driver
@ 2012-06-12  6:41         ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-12  6:41 UTC (permalink / raw)
  To: linux-arm-kernel

* Stephen Warren wrote:
> On 06/11/2012 09:05 AM, Thierry Reding wrote:
> > This commit adds a platform device driver for the PCIe controller on
> > Tegra SOCs. Current users of the old code (TrimSlice and Harmony) are
> > converted and now initialize and register a corresponding platform
> > device.
> 
> > diff --git a/arch/arm/mach-tegra/devices.c b/arch/arm/mach-tegra/devices.c
> 
> > +static struct resource tegra_pcie_resources[] = {
> > +	[0] = {
> > +		.start = TEGRA_PCIE_BASE,
> > +		.end = TEGRA_PCIE_BASE + TEGRA_PCIE_SIZE - 1,
> > +		.flags = IORESOURCE_MEM,
> > +	},
> > +	[1] = {
> > +		.start = TEGRA_PCIE_MMIO_BASE,
> > +		.end = TEGRA_PCIE_MMIO_BASE + TEGRA_PCIE_MMIO_SIZE - 1,
> > +		.flags = IORESOURCE_MEM,
> > +	},
> > +	[2] = {
> > +		.start = INT_PCIE_INTR,
> > +		.end = INT_PCIE_INTR,
> > +		.flags = IORESOURCE_IRQ,
> > +	},
> > +};
> 
> I'm not sure those resources either cover all the necessary regions, nor
> are as fine-grained as they should be ...
> 
> In particular, in pcie.c, I see separate afi_writel() and pads_writel()
> implying those are separate regions.
> 
> Also, I see the following hard-code specific addresses, and are still
> used by the driver after conversion:
> 
> > #define MEM_BASE_0              (TEGRA_PCIE_BASE + SZ_256M)
> > #define MEM_SIZE_0              SZ_128M
> > #define MEM_BASE_1              (MEM_BASE_0 + MEM_SIZE_0)
> > #define MEM_SIZE_1              SZ_128M
> > #define PREFETCH_MEM_BASE_0     (MEM_BASE_1 + MEM_SIZE_1)
> > #define PREFETCH_MEM_SIZE_0     SZ_128M
> > #define PREFETCH_MEM_BASE_1     (PREFETCH_MEM_BASE_0 + PREFETCH_MEM_SIZE_0)
> > #define PREFETCH_MEM_SIZE_1     SZ_128M
> 
> Also, there's a comment describing the register layout in terms of a
> number of separate regions:
> 
> > /*
> >  * Tegra2 defines 1GB in the AXI address map for PCIe.
> >  *
> >  * That address space is split into different regions, with sizes and
> >  * offsets as follows:
> >  *
> >  * 0x80000000 - 0x80003fff - PCI controller registers
> >  * 0x80004000 - 0x80103fff - PCI configuration space
> >  * 0x80104000 - 0x80203fff - PCI extended configuration space
> >  * 0x80203fff - 0x803fffff - unused
> >  * 0x80400000 - 0x8040ffff - downstream IO
> >  * 0x80410000 - 0x8fffffff - unused
> >  * 0x90000000 - 0x9fffffff - non-prefetchable memory
> >  * 0xa0000000 - 0xbfffffff - prefetchable memory
> >  */
> 
> (the latter 2 regions at least being also split in half for each of the
> 2 host ports)

I was thinking that maybe each port should be represented as a child node,
but I'm not sure that's going to work too well because the children of the
pci node are supposed to be PCI busses/devices. I'll have to check whether
they could just as well be children of the PCIe port nodes.

That way each port could get an own set of register ranges to better describe
the actual layout. AFAICT the even partitioning of the non-prefetchable and
prefetchable memory regions is arbitrary and it could potentially be useful
to make it configurable via the DT.

> Shouldn't each of these regions be a separate entry in the platform
> device resources.
> 
> This perhaps isn't that relevant for Tegra20 alone, but Tegra30 supports
> 3 host ports instead of 2 (hence I presume alters the internal layout of
> the 1G chunk of physical memory space allocated to PCIe), and moves the
> PCIe area from 2G..3G to 0G..1G (so invalidates the hard-coded
> *_MEM_BASE_* above).

> That said, I'm not sure whether Tegra20's and Tegra30's PCIe controllers
> are similar enough to make a shared driver worthwhile/possible.
> (Although our downstream Android driver appears to handle both with a
> very small number of ifdefs).

> If they are similar, then I think my comments above should be addressed.
> If they are not similar, then I think you can just have a single 1G
> memory region in the resources, and split it up internally, rather than
> needing separate resources for different parts of the address space.

Unfortunately the PCIe controller is very badly documented in the TRM, so
this information is hard to locate (I guess the best source is one of the
downstream drivers).

Last time I looked they seemed to be simple enough to handle the differences
using OF compatible matches. I believe apart from the PCIe area changes there
were some differences in how the MSI were setup.

> While we can easily fix this kind of driver internals so this doesn't
> seem like a big deal, this kind of change would impact the device tree
> binding, so it seems that we need to sort it out before DT conversion.

Yes, we should at least try to get it right from the start.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120612/bc94282d/attachment-0001.sig>

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

* Re: [PATCH v2 05/10] ARM: tegra: Rewrite PCIe support as a driver
  2012-06-12  6:41         ` Thierry Reding
@ 2012-06-12  7:24           ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-12  7:24 UTC (permalink / raw)
  To: Stephen Warren
  Cc: linux-tegra, Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson

[-- Attachment #1: Type: text/plain, Size: 803 bytes --]

* Thierry Reding wrote:
> AFAICT the even partitioning of the non-prefetchable and prefetchable
> memory regions is arbitrary and it could potentially be useful to make
> it configurable via the DT.

So it turns out that this isn't true. But apart from the comments in the
driver I couldn't find any reference to how the prefetch and non-prefetch
ranges are partitioned. Judging by the code for Tegra2 this is evenly
partitioned among ports 0 and 1 but it would be interesting to know this is
done on Tegra3. Is there any way you can find out?

It'd also be nice if some better documentation for the PCIe controller could
be made available. The Tegra2 TRM doesn't contain any of the AFI or PADS
registers and while the Tegra3 TRM documents more registers, their offsets
are completely missing.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* [PATCH v2 05/10] ARM: tegra: Rewrite PCIe support as a driver
@ 2012-06-12  7:24           ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-12  7:24 UTC (permalink / raw)
  To: linux-arm-kernel

* Thierry Reding wrote:
> AFAICT the even partitioning of the non-prefetchable and prefetchable
> memory regions is arbitrary and it could potentially be useful to make
> it configurable via the DT.

So it turns out that this isn't true. But apart from the comments in the
driver I couldn't find any reference to how the prefetch and non-prefetch
ranges are partitioned. Judging by the code for Tegra2 this is evenly
partitioned among ports 0 and 1 but it would be interesting to know this is
done on Tegra3. Is there any way you can find out?

It'd also be nice if some better documentation for the PCIe controller could
be made available. The Tegra2 TRM doesn't contain any of the AFI or PADS
registers and while the Tegra3 TRM documents more registers, their offsets
are completely missing.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120612/0a21f4a7/attachment.sig>

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

* Re: [PATCH v2 09/10] ARM: tegra: harmony: Initialize PCIe from DT
  2012-06-12  5:48             ` Thierry Reding
  (?)
@ 2012-06-12 15:38                 ` Stephen Warren
  -1 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-12 15:38 UTC (permalink / raw)
  To: Thierry Reding
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jesse Barnes,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, Grant Likely, Rob Herring,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Russell King,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Colin Cross,
	Olof Johansson

On 06/11/2012 11:48 PM, Thierry Reding wrote:
> * Stephen Warren wrote:
>> On 06/11/2012 09:05 AM, Thierry Reding wrote:
>>> With the device tree support in place, probe the PCIe
>>> controller from the device tree and remove the corresponding
>>> workaround in the board file.
>> 
>>> diff --git a/arch/arm/boot/dts/tegra-harmony.dts
>>> b/arch/arm/boot/dts/tegra-harmony.dts
>> 
>>> +	pci_vdd_reg: fixedregulator@0 {
>> 
>> I think that'd usually just be "regulator@0".
>> 
>> If you need the "@0" part to differentiate between multiple
>> regulators, the node needs a reg property too:
>> 
>> reg = <0 0>;
>> 
>> although then I wonder about putting the regulator under the root
>> node, since the address wouldn't really make sense...
> 
> Perhaps we should add a new "regulators" node under the root node
> to collect this kind of regulators that don't fit anywhere else.
> Looking at the code, something like this should work:
> 
> / { ...
> 
> regulators { compatible = "simple-bus"; #address-cells = <1>; 
> #size-cells = <0>;
> 
> pci_vdd_reg: regulator@0 { reg = <0>; }; }; };

That seems like a good idea, and there's certainly precedent for doing
exactly that in other ARM .dts files already.

To maintain .dts alphabetical sorting of non-addressed nodes, this new
node should slot in just before the sound node, near the end of the file.

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

* Re: [PATCH v2 09/10] ARM: tegra: harmony: Initialize PCIe from DT
@ 2012-06-12 15:38                 ` Stephen Warren
  0 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-12 15:38 UTC (permalink / raw)
  To: Thierry Reding
  Cc: linux-tegra, Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson

On 06/11/2012 11:48 PM, Thierry Reding wrote:
> * Stephen Warren wrote:
>> On 06/11/2012 09:05 AM, Thierry Reding wrote:
>>> With the device tree support in place, probe the PCIe
>>> controller from the device tree and remove the corresponding
>>> workaround in the board file.
>> 
>>> diff --git a/arch/arm/boot/dts/tegra-harmony.dts
>>> b/arch/arm/boot/dts/tegra-harmony.dts
>> 
>>> +	pci_vdd_reg: fixedregulator@0 {
>> 
>> I think that'd usually just be "regulator@0".
>> 
>> If you need the "@0" part to differentiate between multiple
>> regulators, the node needs a reg property too:
>> 
>> reg = <0 0>;
>> 
>> although then I wonder about putting the regulator under the root
>> node, since the address wouldn't really make sense...
> 
> Perhaps we should add a new "regulators" node under the root node
> to collect this kind of regulators that don't fit anywhere else.
> Looking at the code, something like this should work:
> 
> / { ...
> 
> regulators { compatible = "simple-bus"; #address-cells = <1>; 
> #size-cells = <0>;
> 
> pci_vdd_reg: regulator@0 { reg = <0>; }; }; };

That seems like a good idea, and there's certainly precedent for doing
exactly that in other ARM .dts files already.

To maintain .dts alphabetical sorting of non-addressed nodes, this new
node should slot in just before the sound node, near the end of the file.

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

* [PATCH v2 09/10] ARM: tegra: harmony: Initialize PCIe from DT
@ 2012-06-12 15:38                 ` Stephen Warren
  0 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-12 15:38 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/11/2012 11:48 PM, Thierry Reding wrote:
> * Stephen Warren wrote:
>> On 06/11/2012 09:05 AM, Thierry Reding wrote:
>>> With the device tree support in place, probe the PCIe
>>> controller from the device tree and remove the corresponding
>>> workaround in the board file.
>> 
>>> diff --git a/arch/arm/boot/dts/tegra-harmony.dts
>>> b/arch/arm/boot/dts/tegra-harmony.dts
>> 
>>> +	pci_vdd_reg: fixedregulator at 0 {
>> 
>> I think that'd usually just be "regulator at 0".
>> 
>> If you need the "@0" part to differentiate between multiple
>> regulators, the node needs a reg property too:
>> 
>> reg = <0 0>;
>> 
>> although then I wonder about putting the regulator under the root
>> node, since the address wouldn't really make sense...
> 
> Perhaps we should add a new "regulators" node under the root node
> to collect this kind of regulators that don't fit anywhere else.
> Looking at the code, something like this should work:
> 
> / { ...
> 
> regulators { compatible = "simple-bus"; #address-cells = <1>; 
> #size-cells = <0>;
> 
> pci_vdd_reg: regulator at 0 { reg = <0>; }; }; };

That seems like a good idea, and there's certainly precedent for doing
exactly that in other ARM .dts files already.

To maintain .dts alphabetical sorting of non-addressed nodes, this new
node should slot in just before the sound node, near the end of the file.

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

* Re: [PATCH v2 06/10] ARM: tegra: pcie: Add MSI support
  2012-06-12  6:10             ` Thierry Reding
  (?)
@ 2012-06-12 15:40                 ` Stephen Warren
  -1 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-12 15:40 UTC (permalink / raw)
  To: Thierry Reding
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jesse Barnes,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, Grant Likely, Rob Herring,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Russell King,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Colin Cross,
	Olof Johansson

On 06/12/2012 12:10 AM, Thierry Reding wrote:
> * Thierry Reding wrote:
>> * Stephen Warren wrote:
>>> On 06/11/2012 09:05 AM, Thierry Reding wrote:
> [...]
>>>> +static int tegra_pcie_disable_msi(struct platform_device
>>>> *pdev)
>>> 
>>> Should this free pcie->msi->pages?
>> 
>> Yes it should. I actually mention making that change in the
>> changelog but in fact didn't.
> 
> This is really moot because the driver cannot be built as a module
> currently because arch_setup_msi_irq() and arch_teardown_msi_irq()
> need to be built-in so tegra_pcie_disable_msi() will be called only
> just before the machine is shut down.
> 
> Perhaps this is something that should be addressed? Or is it just
> not worth the effort?

Well, if the driver provides a shutdown/removal path at all, it seems
like it should be complete. I assume it's trivial to free those pages?

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

* Re: [PATCH v2 06/10] ARM: tegra: pcie: Add MSI support
@ 2012-06-12 15:40                 ` Stephen Warren
  0 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-12 15:40 UTC (permalink / raw)
  To: Thierry Reding
  Cc: linux-tegra, Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson

On 06/12/2012 12:10 AM, Thierry Reding wrote:
> * Thierry Reding wrote:
>> * Stephen Warren wrote:
>>> On 06/11/2012 09:05 AM, Thierry Reding wrote:
> [...]
>>>> +static int tegra_pcie_disable_msi(struct platform_device
>>>> *pdev)
>>> 
>>> Should this free pcie->msi->pages?
>> 
>> Yes it should. I actually mention making that change in the
>> changelog but in fact didn't.
> 
> This is really moot because the driver cannot be built as a module
> currently because arch_setup_msi_irq() and arch_teardown_msi_irq()
> need to be built-in so tegra_pcie_disable_msi() will be called only
> just before the machine is shut down.
> 
> Perhaps this is something that should be addressed? Or is it just
> not worth the effort?

Well, if the driver provides a shutdown/removal path at all, it seems
like it should be complete. I assume it's trivial to free those pages?

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

* [PATCH v2 06/10] ARM: tegra: pcie: Add MSI support
@ 2012-06-12 15:40                 ` Stephen Warren
  0 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-12 15:40 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/12/2012 12:10 AM, Thierry Reding wrote:
> * Thierry Reding wrote:
>> * Stephen Warren wrote:
>>> On 06/11/2012 09:05 AM, Thierry Reding wrote:
> [...]
>>>> +static int tegra_pcie_disable_msi(struct platform_device
>>>> *pdev)
>>> 
>>> Should this free pcie->msi->pages?
>> 
>> Yes it should. I actually mention making that change in the
>> changelog but in fact didn't.
> 
> This is really moot because the driver cannot be built as a module
> currently because arch_setup_msi_irq() and arch_teardown_msi_irq()
> need to be built-in so tegra_pcie_disable_msi() will be called only
> just before the machine is shut down.
> 
> Perhaps this is something that should be addressed? Or is it just
> not worth the effort?

Well, if the driver provides a shutdown/removal path at all, it seems
like it should be complete. I assume it's trivial to free those pages?

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-12  6:21         ` Thierry Reding
@ 2012-06-12 15:44           ` Stephen Warren
  -1 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-12 15:44 UTC (permalink / raw)
  To: Thierry Reding
  Cc: linux-tegra, Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson

On 06/12/2012 12:21 AM, Thierry Reding wrote:
> * Stephen Warren wrote:
>> On 06/11/2012 09:05 AM, Thierry Reding wrote:
>>> This commit adds support for instantiating the Tegra PCIe
>>> controller from a device tree.
>> 
>>> +++ b/Documentation/devicetree/bindings/pci/tegra-pcie.txt
>> 
>> Can we please name this nvidia,tegra20-pcie.txt to match the
>> naming of all the other Tegra bindings.
> 
> Yes, will do.
> 
>>> +Required properties: +- compatible: "nvidia,tegra20-pcie" +-
>>> reg: physical base address and length of the controller's
>>> registers
>> 
>> Since there's more than one range now, that should specify how
>> many entries are required and what they represent.
> 
> Okay.
> 
>>> +Optional properties: +- pex-clk-supply: supply voltage for
>>> internal reference clock +- vdd-supply: power supply for
>>> controller (1.05V)
>> 
>> Those shouldn't be optional. If the board has no regulator, the
>> board's .dts should provide a fixed always-on regulator that
>> those properties can refer to, so that the driver can always
>> get() those regulators.
> 
> That'll add more dummy regulators and I don't think sprinkling them
> across the DTS is going to work very well. Maybe collecting them
> under a top-level "regulators" node is a good option. If you have a
> better alternative, I'm all open for it.
> 
>>> diff --git a/arch/arm/boot/dts/tegra20.dtsi
>>> b/arch/arm/boot/dts/tegra20.dtsi
>> 
>>> +	pci {
>> ...
>>> +		status = "disable";
>> 
>> That should be "disabled"; sorry for providing a bad example.
> 
> Yes.
> 
>>> diff --git a/arch/arm/mach-tegra/pcie.c
>>> b/arch/arm/mach-tegra/pcie.c
>> 
>>> +static struct tegra_pcie_pdata *tegra_pcie_parse_dt(struct
>>> platform_device *pdev)
>> 
>>> +	if (of_find_property(node, "vdd-supply", NULL)) {
>> 
>> As mentioned above, that if statement should be removed, since
>> the regulators shouldn't be optional.
> 
> Okay.
> 
>>> +		pcie->vdd_supply = regulator_get(&pdev->dev, "vdd");
>> 
>> Those could be devm_regulator_get(). Then tegra_pcie_remove()
>> wouldn't have to put() them.
> 
> Okay.
> 
>>> +	for (i = 0; i < TEGRA_PCIE_MAX_PORTS; i++) +
>>> pdata->enable_ports[i] = true;
>> 
>> Shouldn't the DT indicate which ports are used? I assume there's
>> some reason that the existing driver allows that to be
>> configured, rather than always enabling all ports. At least,
>> enumeration time wasted on non-existent ports springs to mind,
>> and perhaps attempting to enable port 1 when port 0 is x4 and
>> using all the lanes would cause errors in port 0?
> 
> Yes, that's been on my mind as well. I'm not sure about the best
> binding for this. Perhaps something like:
> 
> pci { enable-ports = <0 1 2>; };
> 
> Would do?

That seems reasonable, although since the property is presumably
something specific to the Tegra PCIe binding, not generic, I think it
should be nvidia,enable-ports.

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-12 15:44           ` Stephen Warren
  0 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-12 15:44 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/12/2012 12:21 AM, Thierry Reding wrote:
> * Stephen Warren wrote:
>> On 06/11/2012 09:05 AM, Thierry Reding wrote:
>>> This commit adds support for instantiating the Tegra PCIe
>>> controller from a device tree.
>> 
>>> +++ b/Documentation/devicetree/bindings/pci/tegra-pcie.txt
>> 
>> Can we please name this nvidia,tegra20-pcie.txt to match the
>> naming of all the other Tegra bindings.
> 
> Yes, will do.
> 
>>> +Required properties: +- compatible: "nvidia,tegra20-pcie" +-
>>> reg: physical base address and length of the controller's
>>> registers
>> 
>> Since there's more than one range now, that should specify how
>> many entries are required and what they represent.
> 
> Okay.
> 
>>> +Optional properties: +- pex-clk-supply: supply voltage for
>>> internal reference clock +- vdd-supply: power supply for
>>> controller (1.05V)
>> 
>> Those shouldn't be optional. If the board has no regulator, the
>> board's .dts should provide a fixed always-on regulator that
>> those properties can refer to, so that the driver can always
>> get() those regulators.
> 
> That'll add more dummy regulators and I don't think sprinkling them
> across the DTS is going to work very well. Maybe collecting them
> under a top-level "regulators" node is a good option. If you have a
> better alternative, I'm all open for it.
> 
>>> diff --git a/arch/arm/boot/dts/tegra20.dtsi
>>> b/arch/arm/boot/dts/tegra20.dtsi
>> 
>>> +	pci {
>> ...
>>> +		status = "disable";
>> 
>> That should be "disabled"; sorry for providing a bad example.
> 
> Yes.
> 
>>> diff --git a/arch/arm/mach-tegra/pcie.c
>>> b/arch/arm/mach-tegra/pcie.c
>> 
>>> +static struct tegra_pcie_pdata *tegra_pcie_parse_dt(struct
>>> platform_device *pdev)
>> 
>>> +	if (of_find_property(node, "vdd-supply", NULL)) {
>> 
>> As mentioned above, that if statement should be removed, since
>> the regulators shouldn't be optional.
> 
> Okay.
> 
>>> +		pcie->vdd_supply = regulator_get(&pdev->dev, "vdd");
>> 
>> Those could be devm_regulator_get(). Then tegra_pcie_remove()
>> wouldn't have to put() them.
> 
> Okay.
> 
>>> +	for (i = 0; i < TEGRA_PCIE_MAX_PORTS; i++) +
>>> pdata->enable_ports[i] = true;
>> 
>> Shouldn't the DT indicate which ports are used? I assume there's
>> some reason that the existing driver allows that to be
>> configured, rather than always enabling all ports. At least,
>> enumeration time wasted on non-existent ports springs to mind,
>> and perhaps attempting to enable port 1 when port 0 is x4 and
>> using all the lanes would cause errors in port 0?
> 
> Yes, that's been on my mind as well. I'm not sure about the best
> binding for this. Perhaps something like:
> 
> pci { enable-ports = <0 1 2>; };
> 
> Would do?

That seems reasonable, although since the property is presumably
something specific to the Tegra PCIe binding, not generic, I think it
should be nvidia,enable-ports.

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

* Re: [PATCH v2 05/10] ARM: tegra: Rewrite PCIe support as a driver
  2012-06-12  7:24           ` Thierry Reding
  (?)
@ 2012-06-12 16:00               ` Stephen Warren
  -1 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-12 16:00 UTC (permalink / raw)
  To: Thierry Reding
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jesse Barnes,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, Grant Likely, Rob Herring,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Russell King,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Colin Cross,
	Olof Johansson

On 06/12/2012 01:24 AM, Thierry Reding wrote:
> * Thierry Reding wrote:
>> AFAICT the even partitioning of the non-prefetchable and 
>> prefetchable memory regions is arbitrary and it could
>> potentially be useful to make it configurable via the DT.
> 
> So it turns out that this isn't true. But apart from the comments 
> in the driver I couldn't find any reference to how the prefetch
> and non-prefetch ranges are partitioned. Judging by the code for
> Tegra2 this is evenly partitioned among ports 0 and 1 but it would
> be interesting to know this is done on Tegra3. Is there any way
> you can find out?
> 
> It'd also be nice if some better documentation for the PCIe 
> controller could be made available. The Tegra2 TRM doesn't contain 
> any of the AFI or PADS registers and while the Tegra3 TRM
> documents more registers, their offsets are completely missing.

I've filed a bug to request better documentation.

Looking at our downstream driver, the quoted comment below implies
that the address space layout is pretty arbitrary and programmable at
least for Tegra30. The code in function
tegra_pcie_setup_translations() appears to support this (and is
executed for both Tegra20 and Tegra30, even though the comment for
Tegra20 doesn't mention any programmability).

Tegra20:

> /*
>  * Tegra2 defines 1GB in the AXI address map for PCIe.
>  *
>  * That address space is split into different regions, with sizes and
>  * offsets as follows:
>  *
>  * 0x80000000 - 0x80003fff - PCI controller registers
>  * 0x80004000 - 0x80103fff - PCI configuration space
>  * 0x80104000 - 0x80203fff - PCI extended configuration space
>  * 0x80203fff - 0x803fffff - unused
>  * 0x80400000 - 0x8040ffff - downstream IO
>  * 0x80410000 - 0x8fffffff - unused
>  * 0x90000000 - 0x9fffffff - non-prefetchable memory
>  * 0xa0000000 - 0xbfffffff - prefetchable memory
>  */

(I guess by "is split", it means the driver sets it up that way, not
that the HW is fixed that way)

Tegra30:

> /*
>  * AXI address map for the PCIe aperture , defines 1GB in the AXI
>  *  address map for PCIe.
>  *
>  *  That address space is split into different regions, with sizes and
>  *  offsets as follows. Exepct for the Register space, SW is free to slice the
>  *  regions as it chooces.
>  *
>  *  The split below seems to work fine for now.
>  *
>  *  0x0000_0000 to 0x00ff_ffff - Register space          16MB.
>  *  0x0100_0000 to 0x01ff_ffff - Config space            16MB.
>  *  0x0200_0000 to 0x02ff_ffff - Extended config space   16MB.
>  *  0x0300_0000 to 0x03ff_ffff - Downstream IO space
>  *   ... Will be filled with other BARS like MSI/upstream IO etc.
>  *  0x1000_0000 to 0x1fff_ffff - non-prefetchable memory aperture
>  *  0x2000_0000 to 0x3fff_ffff - Prefetchable memory aperture
>  *
>  *  Config and Extended config sizes are choosen to support
>  *  maximum of 256 devices,
>  *  which is good enough for all the current use cases.
>  *
>  */

From
http://nv-tegra.nvidia.com/gitweb/?p=linux-2.6.git;a=blob;f=arch/arm/mach-tegra/pcie.c;h=b98d4892b5ee46120a9777a969e820a0b5cbb68a;hb=android-tegra-nv-3.1

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

* Re: [PATCH v2 05/10] ARM: tegra: Rewrite PCIe support as a driver
@ 2012-06-12 16:00               ` Stephen Warren
  0 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-12 16:00 UTC (permalink / raw)
  To: Thierry Reding
  Cc: linux-tegra, Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson

On 06/12/2012 01:24 AM, Thierry Reding wrote:
> * Thierry Reding wrote:
>> AFAICT the even partitioning of the non-prefetchable and 
>> prefetchable memory regions is arbitrary and it could
>> potentially be useful to make it configurable via the DT.
> 
> So it turns out that this isn't true. But apart from the comments 
> in the driver I couldn't find any reference to how the prefetch
> and non-prefetch ranges are partitioned. Judging by the code for
> Tegra2 this is evenly partitioned among ports 0 and 1 but it would
> be interesting to know this is done on Tegra3. Is there any way
> you can find out?
> 
> It'd also be nice if some better documentation for the PCIe 
> controller could be made available. The Tegra2 TRM doesn't contain 
> any of the AFI or PADS registers and while the Tegra3 TRM
> documents more registers, their offsets are completely missing.

I've filed a bug to request better documentation.

Looking at our downstream driver, the quoted comment below implies
that the address space layout is pretty arbitrary and programmable at
least for Tegra30. The code in function
tegra_pcie_setup_translations() appears to support this (and is
executed for both Tegra20 and Tegra30, even though the comment for
Tegra20 doesn't mention any programmability).

Tegra20:

> /*
>  * Tegra2 defines 1GB in the AXI address map for PCIe.
>  *
>  * That address space is split into different regions, with sizes and
>  * offsets as follows:
>  *
>  * 0x80000000 - 0x80003fff - PCI controller registers
>  * 0x80004000 - 0x80103fff - PCI configuration space
>  * 0x80104000 - 0x80203fff - PCI extended configuration space
>  * 0x80203fff - 0x803fffff - unused
>  * 0x80400000 - 0x8040ffff - downstream IO
>  * 0x80410000 - 0x8fffffff - unused
>  * 0x90000000 - 0x9fffffff - non-prefetchable memory
>  * 0xa0000000 - 0xbfffffff - prefetchable memory
>  */

(I guess by "is split", it means the driver sets it up that way, not
that the HW is fixed that way)

Tegra30:

> /*
>  * AXI address map for the PCIe aperture , defines 1GB in the AXI
>  *  address map for PCIe.
>  *
>  *  That address space is split into different regions, with sizes and
>  *  offsets as follows. Exepct for the Register space, SW is free to slice the
>  *  regions as it chooces.
>  *
>  *  The split below seems to work fine for now.
>  *
>  *  0x0000_0000 to 0x00ff_ffff - Register space          16MB.
>  *  0x0100_0000 to 0x01ff_ffff - Config space            16MB.
>  *  0x0200_0000 to 0x02ff_ffff - Extended config space   16MB.
>  *  0x0300_0000 to 0x03ff_ffff - Downstream IO space
>  *   ... Will be filled with other BARS like MSI/upstream IO etc.
>  *  0x1000_0000 to 0x1fff_ffff - non-prefetchable memory aperture
>  *  0x2000_0000 to 0x3fff_ffff - Prefetchable memory aperture
>  *
>  *  Config and Extended config sizes are choosen to support
>  *  maximum of 256 devices,
>  *  which is good enough for all the current use cases.
>  *
>  */

From
http://nv-tegra.nvidia.com/gitweb/?p=linux-2.6.git;a=blob;f=arch/arm/mach-tegra/pcie.c;h=b98d4892b5ee46120a9777a969e820a0b5cbb68a;hb=android-tegra-nv-3.1

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

* [PATCH v2 05/10] ARM: tegra: Rewrite PCIe support as a driver
@ 2012-06-12 16:00               ` Stephen Warren
  0 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-12 16:00 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/12/2012 01:24 AM, Thierry Reding wrote:
> * Thierry Reding wrote:
>> AFAICT the even partitioning of the non-prefetchable and 
>> prefetchable memory regions is arbitrary and it could
>> potentially be useful to make it configurable via the DT.
> 
> So it turns out that this isn't true. But apart from the comments 
> in the driver I couldn't find any reference to how the prefetch
> and non-prefetch ranges are partitioned. Judging by the code for
> Tegra2 this is evenly partitioned among ports 0 and 1 but it would
> be interesting to know this is done on Tegra3. Is there any way
> you can find out?
> 
> It'd also be nice if some better documentation for the PCIe 
> controller could be made available. The Tegra2 TRM doesn't contain 
> any of the AFI or PADS registers and while the Tegra3 TRM
> documents more registers, their offsets are completely missing.

I've filed a bug to request better documentation.

Looking at our downstream driver, the quoted comment below implies
that the address space layout is pretty arbitrary and programmable at
least for Tegra30. The code in function
tegra_pcie_setup_translations() appears to support this (and is
executed for both Tegra20 and Tegra30, even though the comment for
Tegra20 doesn't mention any programmability).

Tegra20:

> /*
>  * Tegra2 defines 1GB in the AXI address map for PCIe.
>  *
>  * That address space is split into different regions, with sizes and
>  * offsets as follows:
>  *
>  * 0x80000000 - 0x80003fff - PCI controller registers
>  * 0x80004000 - 0x80103fff - PCI configuration space
>  * 0x80104000 - 0x80203fff - PCI extended configuration space
>  * 0x80203fff - 0x803fffff - unused
>  * 0x80400000 - 0x8040ffff - downstream IO
>  * 0x80410000 - 0x8fffffff - unused
>  * 0x90000000 - 0x9fffffff - non-prefetchable memory
>  * 0xa0000000 - 0xbfffffff - prefetchable memory
>  */

(I guess by "is split", it means the driver sets it up that way, not
that the HW is fixed that way)

Tegra30:

> /*
>  * AXI address map for the PCIe aperture , defines 1GB in the AXI
>  *  address map for PCIe.
>  *
>  *  That address space is split into different regions, with sizes and
>  *  offsets as follows. Exepct for the Register space, SW is free to slice the
>  *  regions as it chooces.
>  *
>  *  The split below seems to work fine for now.
>  *
>  *  0x0000_0000 to 0x00ff_ffff - Register space          16MB.
>  *  0x0100_0000 to 0x01ff_ffff - Config space            16MB.
>  *  0x0200_0000 to 0x02ff_ffff - Extended config space   16MB.
>  *  0x0300_0000 to 0x03ff_ffff - Downstream IO space
>  *   ... Will be filled with other BARS like MSI/upstream IO etc.
>  *  0x1000_0000 to 0x1fff_ffff - non-prefetchable memory aperture
>  *  0x2000_0000 to 0x3fff_ffff - Prefetchable memory aperture
>  *
>  *  Config and Extended config sizes are choosen to support
>  *  maximum of 256 devices,
>  *  which is good enough for all the current use cases.
>  *
>  */

From
http://nv-tegra.nvidia.com/gitweb/?p=linux-2.6.git;a=blob;f=arch/arm/mach-tegra/pcie.c;h=b98d4892b5ee46120a9777a969e820a0b5cbb68a;hb=android-tegra-nv-3.1

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-12 15:44           ` Stephen Warren
  (?)
@ 2012-06-12 17:20               ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-12 17:20 UTC (permalink / raw)
  To: Stephen Warren
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jesse Barnes,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, Grant Likely, Rob Herring,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Russell King,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Colin Cross,
	Olof Johansson

[-- Attachment #1: Type: text/plain, Size: 4770 bytes --]

* Stephen Warren wrote:
> On 06/12/2012 12:21 AM, Thierry Reding wrote:
> > * Stephen Warren wrote:
> >> On 06/11/2012 09:05 AM, Thierry Reding wrote:
> >>> This commit adds support for instantiating the Tegra PCIe
> >>> controller from a device tree.
> >> 
> >>> +++ b/Documentation/devicetree/bindings/pci/tegra-pcie.txt
> >> 
> >> Can we please name this nvidia,tegra20-pcie.txt to match the
> >> naming of all the other Tegra bindings.
> > 
> > Yes, will do.
> > 
> >>> +Required properties: +- compatible: "nvidia,tegra20-pcie" +-
> >>> reg: physical base address and length of the controller's
> >>> registers
> >> 
> >> Since there's more than one range now, that should specify how
> >> many entries are required and what they represent.
> > 
> > Okay.
> > 
> >>> +Optional properties: +- pex-clk-supply: supply voltage for
> >>> internal reference clock +- vdd-supply: power supply for
> >>> controller (1.05V)
> >> 
> >> Those shouldn't be optional. If the board has no regulator, the
> >> board's .dts should provide a fixed always-on regulator that
> >> those properties can refer to, so that the driver can always
> >> get() those regulators.
> > 
> > That'll add more dummy regulators and I don't think sprinkling them
> > across the DTS is going to work very well. Maybe collecting them
> > under a top-level "regulators" node is a good option. If you have a
> > better alternative, I'm all open for it.
> > 
> >>> diff --git a/arch/arm/boot/dts/tegra20.dtsi
> >>> b/arch/arm/boot/dts/tegra20.dtsi
> >> 
> >>> +	pci {
> >> ...
> >>> +		status = "disable";
> >> 
> >> That should be "disabled"; sorry for providing a bad example.
> > 
> > Yes.
> > 
> >>> diff --git a/arch/arm/mach-tegra/pcie.c
> >>> b/arch/arm/mach-tegra/pcie.c
> >> 
> >>> +static struct tegra_pcie_pdata *tegra_pcie_parse_dt(struct
> >>> platform_device *pdev)
> >> 
> >>> +	if (of_find_property(node, "vdd-supply", NULL)) {
> >> 
> >> As mentioned above, that if statement should be removed, since
> >> the regulators shouldn't be optional.
> > 
> > Okay.
> > 
> >>> +		pcie->vdd_supply = regulator_get(&pdev->dev, "vdd");
> >> 
> >> Those could be devm_regulator_get(). Then tegra_pcie_remove()
> >> wouldn't have to put() them.
> > 
> > Okay.
> > 
> >>> +	for (i = 0; i < TEGRA_PCIE_MAX_PORTS; i++) +
> >>> pdata->enable_ports[i] = true;
> >> 
> >> Shouldn't the DT indicate which ports are used? I assume there's
> >> some reason that the existing driver allows that to be
> >> configured, rather than always enabling all ports. At least,
> >> enumeration time wasted on non-existent ports springs to mind,
> >> and perhaps attempting to enable port 1 when port 0 is x4 and
> >> using all the lanes would cause errors in port 0?
> > 
> > Yes, that's been on my mind as well. I'm not sure about the best
> > binding for this. Perhaps something like:
> > 
> > pci { enable-ports = <0 1 2>; };
> > 
> > Would do?
> 
> That seems reasonable, although since the property is presumably
> something specific to the Tegra PCIe binding, not generic, I think it
> should be nvidia,enable-ports.

I came up with the following alternative:

	pci {
		compatible = "nvidia,tegra20-pcie";
		reg = <0x80003000 0x00000800   /* PADS registers */
		       0x80003800 0x00000200   /* AFI registers */
		       0x80004000 0x00100000   /* configuration space */
		       0x80104000 0x00100000   /* extended configuration space */
		       0x80400000 0x00010000   /* downstream I/O */
		       0x90000000 0x10000000   /* non-prefetchable memory */
		       0xa0000000 0x10000000>; /* prefetchable memory */
		interrupts = <0 98 0x04   /* controller interrupt */
		              0 99 0x04>; /* MSI interrupt */
		status = "disabled";

		ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */
			  0x80004000 0x80004000 0x00100000   /* configuration space */
			  0x80104000 0x80104000 0x00100000   /* extended configuration space */
			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */

		#address-cells = <1>;
		#size-cells = <1>;

		port@80000000 {
			reg = <0x80000000 0x00001000>;
			status = "disabled";
		};

		port@80001000 {
			reg = <0x80001000 0x00001000>;
			status = "disabled";
		};
	};

The "ranges" property can probably be cleaned up a bit, but the most
interesting part is the port@ children, which can simply be enabled in board
DTS files by setting the status property to "okay". I find that somewhat more
intuitive to the variant with an "enable-ports" property.

What do you think of this?

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-12 17:20               ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-12 17:20 UTC (permalink / raw)
  To: Stephen Warren
  Cc: linux-tegra, Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson

[-- Attachment #1: Type: text/plain, Size: 4770 bytes --]

* Stephen Warren wrote:
> On 06/12/2012 12:21 AM, Thierry Reding wrote:
> > * Stephen Warren wrote:
> >> On 06/11/2012 09:05 AM, Thierry Reding wrote:
> >>> This commit adds support for instantiating the Tegra PCIe
> >>> controller from a device tree.
> >> 
> >>> +++ b/Documentation/devicetree/bindings/pci/tegra-pcie.txt
> >> 
> >> Can we please name this nvidia,tegra20-pcie.txt to match the
> >> naming of all the other Tegra bindings.
> > 
> > Yes, will do.
> > 
> >>> +Required properties: +- compatible: "nvidia,tegra20-pcie" +-
> >>> reg: physical base address and length of the controller's
> >>> registers
> >> 
> >> Since there's more than one range now, that should specify how
> >> many entries are required and what they represent.
> > 
> > Okay.
> > 
> >>> +Optional properties: +- pex-clk-supply: supply voltage for
> >>> internal reference clock +- vdd-supply: power supply for
> >>> controller (1.05V)
> >> 
> >> Those shouldn't be optional. If the board has no regulator, the
> >> board's .dts should provide a fixed always-on regulator that
> >> those properties can refer to, so that the driver can always
> >> get() those regulators.
> > 
> > That'll add more dummy regulators and I don't think sprinkling them
> > across the DTS is going to work very well. Maybe collecting them
> > under a top-level "regulators" node is a good option. If you have a
> > better alternative, I'm all open for it.
> > 
> >>> diff --git a/arch/arm/boot/dts/tegra20.dtsi
> >>> b/arch/arm/boot/dts/tegra20.dtsi
> >> 
> >>> +	pci {
> >> ...
> >>> +		status = "disable";
> >> 
> >> That should be "disabled"; sorry for providing a bad example.
> > 
> > Yes.
> > 
> >>> diff --git a/arch/arm/mach-tegra/pcie.c
> >>> b/arch/arm/mach-tegra/pcie.c
> >> 
> >>> +static struct tegra_pcie_pdata *tegra_pcie_parse_dt(struct
> >>> platform_device *pdev)
> >> 
> >>> +	if (of_find_property(node, "vdd-supply", NULL)) {
> >> 
> >> As mentioned above, that if statement should be removed, since
> >> the regulators shouldn't be optional.
> > 
> > Okay.
> > 
> >>> +		pcie->vdd_supply = regulator_get(&pdev->dev, "vdd");
> >> 
> >> Those could be devm_regulator_get(). Then tegra_pcie_remove()
> >> wouldn't have to put() them.
> > 
> > Okay.
> > 
> >>> +	for (i = 0; i < TEGRA_PCIE_MAX_PORTS; i++) +
> >>> pdata->enable_ports[i] = true;
> >> 
> >> Shouldn't the DT indicate which ports are used? I assume there's
> >> some reason that the existing driver allows that to be
> >> configured, rather than always enabling all ports. At least,
> >> enumeration time wasted on non-existent ports springs to mind,
> >> and perhaps attempting to enable port 1 when port 0 is x4 and
> >> using all the lanes would cause errors in port 0?
> > 
> > Yes, that's been on my mind as well. I'm not sure about the best
> > binding for this. Perhaps something like:
> > 
> > pci { enable-ports = <0 1 2>; };
> > 
> > Would do?
> 
> That seems reasonable, although since the property is presumably
> something specific to the Tegra PCIe binding, not generic, I think it
> should be nvidia,enable-ports.

I came up with the following alternative:

	pci {
		compatible = "nvidia,tegra20-pcie";
		reg = <0x80003000 0x00000800   /* PADS registers */
		       0x80003800 0x00000200   /* AFI registers */
		       0x80004000 0x00100000   /* configuration space */
		       0x80104000 0x00100000   /* extended configuration space */
		       0x80400000 0x00010000   /* downstream I/O */
		       0x90000000 0x10000000   /* non-prefetchable memory */
		       0xa0000000 0x10000000>; /* prefetchable memory */
		interrupts = <0 98 0x04   /* controller interrupt */
		              0 99 0x04>; /* MSI interrupt */
		status = "disabled";

		ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */
			  0x80004000 0x80004000 0x00100000   /* configuration space */
			  0x80104000 0x80104000 0x00100000   /* extended configuration space */
			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */

		#address-cells = <1>;
		#size-cells = <1>;

		port@80000000 {
			reg = <0x80000000 0x00001000>;
			status = "disabled";
		};

		port@80001000 {
			reg = <0x80001000 0x00001000>;
			status = "disabled";
		};
	};

The "ranges" property can probably be cleaned up a bit, but the most
interesting part is the port@ children, which can simply be enabled in board
DTS files by setting the status property to "okay". I find that somewhat more
intuitive to the variant with an "enable-ports" property.

What do you think of this?

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-12 17:20               ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-12 17:20 UTC (permalink / raw)
  To: linux-arm-kernel

* Stephen Warren wrote:
> On 06/12/2012 12:21 AM, Thierry Reding wrote:
> > * Stephen Warren wrote:
> >> On 06/11/2012 09:05 AM, Thierry Reding wrote:
> >>> This commit adds support for instantiating the Tegra PCIe
> >>> controller from a device tree.
> >> 
> >>> +++ b/Documentation/devicetree/bindings/pci/tegra-pcie.txt
> >> 
> >> Can we please name this nvidia,tegra20-pcie.txt to match the
> >> naming of all the other Tegra bindings.
> > 
> > Yes, will do.
> > 
> >>> +Required properties: +- compatible: "nvidia,tegra20-pcie" +-
> >>> reg: physical base address and length of the controller's
> >>> registers
> >> 
> >> Since there's more than one range now, that should specify how
> >> many entries are required and what they represent.
> > 
> > Okay.
> > 
> >>> +Optional properties: +- pex-clk-supply: supply voltage for
> >>> internal reference clock +- vdd-supply: power supply for
> >>> controller (1.05V)
> >> 
> >> Those shouldn't be optional. If the board has no regulator, the
> >> board's .dts should provide a fixed always-on regulator that
> >> those properties can refer to, so that the driver can always
> >> get() those regulators.
> > 
> > That'll add more dummy regulators and I don't think sprinkling them
> > across the DTS is going to work very well. Maybe collecting them
> > under a top-level "regulators" node is a good option. If you have a
> > better alternative, I'm all open for it.
> > 
> >>> diff --git a/arch/arm/boot/dts/tegra20.dtsi
> >>> b/arch/arm/boot/dts/tegra20.dtsi
> >> 
> >>> +	pci {
> >> ...
> >>> +		status = "disable";
> >> 
> >> That should be "disabled"; sorry for providing a bad example.
> > 
> > Yes.
> > 
> >>> diff --git a/arch/arm/mach-tegra/pcie.c
> >>> b/arch/arm/mach-tegra/pcie.c
> >> 
> >>> +static struct tegra_pcie_pdata *tegra_pcie_parse_dt(struct
> >>> platform_device *pdev)
> >> 
> >>> +	if (of_find_property(node, "vdd-supply", NULL)) {
> >> 
> >> As mentioned above, that if statement should be removed, since
> >> the regulators shouldn't be optional.
> > 
> > Okay.
> > 
> >>> +		pcie->vdd_supply = regulator_get(&pdev->dev, "vdd");
> >> 
> >> Those could be devm_regulator_get(). Then tegra_pcie_remove()
> >> wouldn't have to put() them.
> > 
> > Okay.
> > 
> >>> +	for (i = 0; i < TEGRA_PCIE_MAX_PORTS; i++) +
> >>> pdata->enable_ports[i] = true;
> >> 
> >> Shouldn't the DT indicate which ports are used? I assume there's
> >> some reason that the existing driver allows that to be
> >> configured, rather than always enabling all ports. At least,
> >> enumeration time wasted on non-existent ports springs to mind,
> >> and perhaps attempting to enable port 1 when port 0 is x4 and
> >> using all the lanes would cause errors in port 0?
> > 
> > Yes, that's been on my mind as well. I'm not sure about the best
> > binding for this. Perhaps something like:
> > 
> > pci { enable-ports = <0 1 2>; };
> > 
> > Would do?
> 
> That seems reasonable, although since the property is presumably
> something specific to the Tegra PCIe binding, not generic, I think it
> should be nvidia,enable-ports.

I came up with the following alternative:

	pci {
		compatible = "nvidia,tegra20-pcie";
		reg = <0x80003000 0x00000800   /* PADS registers */
		       0x80003800 0x00000200   /* AFI registers */
		       0x80004000 0x00100000   /* configuration space */
		       0x80104000 0x00100000   /* extended configuration space */
		       0x80400000 0x00010000   /* downstream I/O */
		       0x90000000 0x10000000   /* non-prefetchable memory */
		       0xa0000000 0x10000000>; /* prefetchable memory */
		interrupts = <0 98 0x04   /* controller interrupt */
		              0 99 0x04>; /* MSI interrupt */
		status = "disabled";

		ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */
			  0x80004000 0x80004000 0x00100000   /* configuration space */
			  0x80104000 0x80104000 0x00100000   /* extended configuration space */
			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */

		#address-cells = <1>;
		#size-cells = <1>;

		port at 80000000 {
			reg = <0x80000000 0x00001000>;
			status = "disabled";
		};

		port at 80001000 {
			reg = <0x80001000 0x00001000>;
			status = "disabled";
		};
	};

The "ranges" property can probably be cleaned up a bit, but the most
interesting part is the port@ children, which can simply be enabled in board
DTS files by setting the status property to "okay". I find that somewhat more
intuitive to the variant with an "enable-ports" property.

What do you think of this?

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120612/9af0c2bb/attachment-0001.sig>

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

* Re: [PATCH v2 06/10] ARM: tegra: pcie: Add MSI support
  2012-06-12 15:40                 ` Stephen Warren
@ 2012-06-12 17:23                   ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-12 17:23 UTC (permalink / raw)
  To: Stephen Warren
  Cc: linux-tegra, Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson

[-- Attachment #1: Type: text/plain, Size: 1213 bytes --]

* Stephen Warren wrote:
> On 06/12/2012 12:10 AM, Thierry Reding wrote:
> > * Thierry Reding wrote:
> >> * Stephen Warren wrote:
> >>> On 06/11/2012 09:05 AM, Thierry Reding wrote:
> > [...]
> >>>> +static int tegra_pcie_disable_msi(struct platform_device
> >>>> *pdev)
> >>> 
> >>> Should this free pcie->msi->pages?
> >> 
> >> Yes it should. I actually mention making that change in the
> >> changelog but in fact didn't.
> > 
> > This is really moot because the driver cannot be built as a module
> > currently because arch_setup_msi_irq() and arch_teardown_msi_irq()
> > need to be built-in so tegra_pcie_disable_msi() will be called only
> > just before the machine is shut down.
> > 
> > Perhaps this is something that should be addressed? Or is it just
> > not worth the effort?
> 
> Well, if the driver provides a shutdown/removal path at all, it seems
> like it should be complete. I assume it's trivial to free those pages?

Yes, it's trivial and I'll definitely add it. What I was saying is that
it doesn't matter really, unless something is done to allow the driver
to be built as a module. It is also tedious to test the shutdown/removal
for built-in drivers.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* [PATCH v2 06/10] ARM: tegra: pcie: Add MSI support
@ 2012-06-12 17:23                   ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-12 17:23 UTC (permalink / raw)
  To: linux-arm-kernel

* Stephen Warren wrote:
> On 06/12/2012 12:10 AM, Thierry Reding wrote:
> > * Thierry Reding wrote:
> >> * Stephen Warren wrote:
> >>> On 06/11/2012 09:05 AM, Thierry Reding wrote:
> > [...]
> >>>> +static int tegra_pcie_disable_msi(struct platform_device
> >>>> *pdev)
> >>> 
> >>> Should this free pcie->msi->pages?
> >> 
> >> Yes it should. I actually mention making that change in the
> >> changelog but in fact didn't.
> > 
> > This is really moot because the driver cannot be built as a module
> > currently because arch_setup_msi_irq() and arch_teardown_msi_irq()
> > need to be built-in so tegra_pcie_disable_msi() will be called only
> > just before the machine is shut down.
> > 
> > Perhaps this is something that should be addressed? Or is it just
> > not worth the effort?
> 
> Well, if the driver provides a shutdown/removal path at all, it seems
> like it should be complete. I assume it's trivial to free those pages?

Yes, it's trivial and I'll definitely add it. What I was saying is that
it doesn't matter really, unless something is done to allow the driver
to be built as a module. It is also tedious to test the shutdown/removal
for built-in drivers.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120612/7b6113bc/attachment.sig>

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-12 17:20               ` Thierry Reding
@ 2012-06-12 19:10                   ` Mitch Bradley
  -1 siblings, 0 replies; 249+ messages in thread
From: Mitch Bradley @ 2012-06-12 19:10 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Russell King, linux-pci-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Jesse Barnes,
	Rob Herring, Colin Cross, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r


[-- Attachment #1.1: Type: text/plain, Size: 5624 bytes --]

On 6/12/2012 7:20 AM, Thierry Reding wrote:
> * Stephen Warren wrote:
>> On 06/12/2012 12:21 AM, Thierry Reding wrote:
>>> * Stephen Warren wrote:
>>>> On 06/11/2012 09:05 AM, Thierry Reding wrote:
>>>>> This commit adds support for instantiating the Tegra PCIe
>>>>> controller from a device tree.
>>>>
>>>>> +++ b/Documentation/devicetree/bindings/pci/tegra-pcie.txt
>>>>
>>>> Can we please name this nvidia,tegra20-pcie.txt to match the
>>>> naming of all the other Tegra bindings.
>>>
>>> Yes, will do.
>>>
>>>>> +Required properties: +- compatible: "nvidia,tegra20-pcie" +-
>>>>> reg: physical base address and length of the controller's
>>>>> registers
>>>>
>>>> Since there's more than one range now, that should specify how
>>>> many entries are required and what they represent.
>>>
>>> Okay.
>>>
>>>>> +Optional properties: +- pex-clk-supply: supply voltage for
>>>>> internal reference clock +- vdd-supply: power supply for
>>>>> controller (1.05V)
>>>>
>>>> Those shouldn't be optional. If the board has no regulator, the
>>>> board's .dts should provide a fixed always-on regulator that
>>>> those properties can refer to, so that the driver can always
>>>> get() those regulators.
>>>
>>> That'll add more dummy regulators and I don't think sprinkling them
>>> across the DTS is going to work very well. Maybe collecting them
>>> under a top-level "regulators" node is a good option. If you have a
>>> better alternative, I'm all open for it.
>>>
>>>>> diff --git a/arch/arm/boot/dts/tegra20.dtsi
>>>>> b/arch/arm/boot/dts/tegra20.dtsi
>>>>
>>>>> +	pci {
>>>> ...
>>>>> +		status = "disable";
>>>>
>>>> That should be "disabled"; sorry for providing a bad example.
>>>
>>> Yes.
>>>
>>>>> diff --git a/arch/arm/mach-tegra/pcie.c
>>>>> b/arch/arm/mach-tegra/pcie.c
>>>>
>>>>> +static struct tegra_pcie_pdata *tegra_pcie_parse_dt(struct
>>>>> platform_device *pdev)
>>>>
>>>>> +	if (of_find_property(node, "vdd-supply", NULL)) {
>>>>
>>>> As mentioned above, that if statement should be removed, since
>>>> the regulators shouldn't be optional.
>>>
>>> Okay.
>>>
>>>>> +		pcie->vdd_supply = regulator_get(&pdev->dev, "vdd");
>>>>
>>>> Those could be devm_regulator_get(). Then tegra_pcie_remove()
>>>> wouldn't have to put() them.
>>>
>>> Okay.
>>>
>>>>> +	for (i = 0; i<  TEGRA_PCIE_MAX_PORTS; i++) +
>>>>> pdata->enable_ports[i] = true;
>>>>
>>>> Shouldn't the DT indicate which ports are used? I assume there's
>>>> some reason that the existing driver allows that to be
>>>> configured, rather than always enabling all ports. At least,
>>>> enumeration time wasted on non-existent ports springs to mind,
>>>> and perhaps attempting to enable port 1 when port 0 is x4 and
>>>> using all the lanes would cause errors in port 0?
>>>
>>> Yes, that's been on my mind as well. I'm not sure about the best
>>> binding for this. Perhaps something like:
>>>
>>> pci { enable-ports =<0 1 2>; };
>>>
>>> Would do?
>>
>> That seems reasonable, although since the property is presumably
>> something specific to the Tegra PCIe binding, not generic, I think it
>> should be nvidia,enable-ports.
>
> I came up with the following alternative:
>
> 	pci {
> 		compatible = "nvidia,tegra20-pcie";
> 		reg =<0x80003000 0x00000800   /* PADS registers */
> 		       0x80003800 0x00000200   /* AFI registers */
> 		       0x80004000 0x00100000   /* configuration space */
> 		       0x80104000 0x00100000   /* extended configuration space */
> 		       0x80400000 0x00010000   /* downstream I/O */
> 		       0x90000000 0x10000000   /* non-prefetchable memory */
> 		       0xa0000000 0x10000000>; /* prefetchable memory */
> 		interrupts =<0 98 0x04   /* controller interrupt */
> 		              0 99 0x04>; /* MSI interrupt */
> 		status = "disabled";
>
> 		ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
> 			  0x80004000 0x80004000 0x00100000   /* configuration space */
> 			  0x80104000 0x80104000 0x00100000   /* extended configuration space */
> 			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
> 			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
> 			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
>
> 		#address-cells =<1>;
> 		#size-cells =<1>;
>
> 		port@80000000 {
> 			reg =<0x80000000 0x00001000>;
> 			status = "disabled";
> 		};
>
> 		port@80001000 {
> 			reg =<0x80001000 0x00001000>;
> 			status = "disabled";
> 		};
> 	};
>
> The "ranges" property can probably be cleaned up a bit, but the most
> interesting part is the port@ children, which can simply be enabled in board
> DTS files by setting the status property to "okay". I find that somewhat more
> intuitive to the variant with an "enable-ports" property.
>
> What do you think of this?

The problem is that children of a PCI-ish bus have specific expectations 
about the parent address format - the standard 3-address-cell PCI 
addressing.  So making a PCI bus node - even if it is PCIe - with 1 
address cell is a problem.

Also, if a given address range is listed in "reg", it should not also be 
listed in "ranges".  A block of addresses is either "claimed" by the 
parent node (reg property) or passed through to its children (ranges 
property), but not both.  "reg" entries are appropriate for entities 
that pertain to the overall control of the bus interface itself, while 
"ranges" entries are for chunks of address space that are overlaid onto 
child devices.

>
>
> Thierry
>
>
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss

[-- Attachment #1.2: Type: text/html, Size: 8974 bytes --]

[-- Attachment #2: Type: text/plain, Size: 192 bytes --]

_______________________________________________
devicetree-discuss mailing list
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
https://lists.ozlabs.org/listinfo/devicetree-discuss

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-12 19:10                   ` Mitch Bradley
  0 siblings, 0 replies; 249+ messages in thread
From: Mitch Bradley @ 2012-06-12 19:10 UTC (permalink / raw)
  To: linux-arm-kernel

On 6/12/2012 7:20 AM, Thierry Reding wrote:
> * Stephen Warren wrote:
>> On 06/12/2012 12:21 AM, Thierry Reding wrote:
>>> * Stephen Warren wrote:
>>>> On 06/11/2012 09:05 AM, Thierry Reding wrote:
>>>>> This commit adds support for instantiating the Tegra PCIe
>>>>> controller from a device tree.
>>>>
>>>>> +++ b/Documentation/devicetree/bindings/pci/tegra-pcie.txt
>>>>
>>>> Can we please name this nvidia,tegra20-pcie.txt to match the
>>>> naming of all the other Tegra bindings.
>>>
>>> Yes, will do.
>>>
>>>>> +Required properties: +- compatible: "nvidia,tegra20-pcie" +-
>>>>> reg: physical base address and length of the controller's
>>>>> registers
>>>>
>>>> Since there's more than one range now, that should specify how
>>>> many entries are required and what they represent.
>>>
>>> Okay.
>>>
>>>>> +Optional properties: +- pex-clk-supply: supply voltage for
>>>>> internal reference clock +- vdd-supply: power supply for
>>>>> controller (1.05V)
>>>>
>>>> Those shouldn't be optional. If the board has no regulator, the
>>>> board's .dts should provide a fixed always-on regulator that
>>>> those properties can refer to, so that the driver can always
>>>> get() those regulators.
>>>
>>> That'll add more dummy regulators and I don't think sprinkling them
>>> across the DTS is going to work very well. Maybe collecting them
>>> under a top-level "regulators" node is a good option. If you have a
>>> better alternative, I'm all open for it.
>>>
>>>>> diff --git a/arch/arm/boot/dts/tegra20.dtsi
>>>>> b/arch/arm/boot/dts/tegra20.dtsi
>>>>
>>>>> +	pci {
>>>> ...
>>>>> +		status = "disable";
>>>>
>>>> That should be "disabled"; sorry for providing a bad example.
>>>
>>> Yes.
>>>
>>>>> diff --git a/arch/arm/mach-tegra/pcie.c
>>>>> b/arch/arm/mach-tegra/pcie.c
>>>>
>>>>> +static struct tegra_pcie_pdata *tegra_pcie_parse_dt(struct
>>>>> platform_device *pdev)
>>>>
>>>>> +	if (of_find_property(node, "vdd-supply", NULL)) {
>>>>
>>>> As mentioned above, that if statement should be removed, since
>>>> the regulators shouldn't be optional.
>>>
>>> Okay.
>>>
>>>>> +		pcie->vdd_supply = regulator_get(&pdev->dev, "vdd");
>>>>
>>>> Those could be devm_regulator_get(). Then tegra_pcie_remove()
>>>> wouldn't have to put() them.
>>>
>>> Okay.
>>>
>>>>> +	for (i = 0; i<  TEGRA_PCIE_MAX_PORTS; i++) +
>>>>> pdata->enable_ports[i] = true;
>>>>
>>>> Shouldn't the DT indicate which ports are used? I assume there's
>>>> some reason that the existing driver allows that to be
>>>> configured, rather than always enabling all ports. At least,
>>>> enumeration time wasted on non-existent ports springs to mind,
>>>> and perhaps attempting to enable port 1 when port 0 is x4 and
>>>> using all the lanes would cause errors in port 0?
>>>
>>> Yes, that's been on my mind as well. I'm not sure about the best
>>> binding for this. Perhaps something like:
>>>
>>> pci { enable-ports =<0 1 2>; };
>>>
>>> Would do?
>>
>> That seems reasonable, although since the property is presumably
>> something specific to the Tegra PCIe binding, not generic, I think it
>> should be nvidia,enable-ports.
>
> I came up with the following alternative:
>
> 	pci {
> 		compatible = "nvidia,tegra20-pcie";
> 		reg =<0x80003000 0x00000800   /* PADS registers */
> 		       0x80003800 0x00000200   /* AFI registers */
> 		       0x80004000 0x00100000   /* configuration space */
> 		       0x80104000 0x00100000   /* extended configuration space */
> 		       0x80400000 0x00010000   /* downstream I/O */
> 		       0x90000000 0x10000000   /* non-prefetchable memory */
> 		       0xa0000000 0x10000000>; /* prefetchable memory */
> 		interrupts =<0 98 0x04   /* controller interrupt */
> 		              0 99 0x04>; /* MSI interrupt */
> 		status = "disabled";
>
> 		ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
> 			  0x80004000 0x80004000 0x00100000   /* configuration space */
> 			  0x80104000 0x80104000 0x00100000   /* extended configuration space */
> 			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
> 			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
> 			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
>
> 		#address-cells =<1>;
> 		#size-cells =<1>;
>
> 		port at 80000000 {
> 			reg =<0x80000000 0x00001000>;
> 			status = "disabled";
> 		};
>
> 		port at 80001000 {
> 			reg =<0x80001000 0x00001000>;
> 			status = "disabled";
> 		};
> 	};
>
> The "ranges" property can probably be cleaned up a bit, but the most
> interesting part is the port@ children, which can simply be enabled in board
> DTS files by setting the status property to "okay". I find that somewhat more
> intuitive to the variant with an "enable-ports" property.
>
> What do you think of this?

The problem is that children of a PCI-ish bus have specific expectations 
about the parent address format - the standard 3-address-cell PCI 
addressing.  So making a PCI bus node - even if it is PCIe - with 1 
address cell is a problem.

Also, if a given address range is listed in "reg", it should not also be 
listed in "ranges".  A block of addresses is either "claimed" by the 
parent node (reg property) or passed through to its children (ranges 
property), but not both.  "reg" entries are appropriate for entities 
that pertain to the overall control of the bus interface itself, while 
"ranges" entries are for chunks of address space that are overlaid onto 
child devices.

>
>
> Thierry
>
>
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss at lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120612/f97d2ef4/attachment-0001.html>

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-12 19:10                   ` Mitch Bradley
  (?)
@ 2012-06-12 19:46                       ` Stephen Warren
  -1 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-12 19:46 UTC (permalink / raw)
  To: Mitch Bradley
  Cc: Thierry Reding, Russell King, linux-pci-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Jesse Barnes, Colin Cross, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On 06/12/2012 01:10 PM, Mitch Bradley wrote:
> On 6/12/2012 7:20 AM, Thierry Reding wrote:
...
>> I came up with the following alternative:
>>
>> 	pci {
>> 		compatible = "nvidia,tegra20-pcie";
>> 		reg = <0x80003000 0x00000800   /* PADS registers */
>> 		       0x80003800 0x00000200   /* AFI registers */
>> 		       0x80004000 0x00100000   /* configuration space */
>> 		       0x80104000 0x00100000   /* extended configuration space */
>> 		       0x80400000 0x00010000   /* downstream I/O */
>> 		       0x90000000 0x10000000   /* non-prefetchable memory */
>> 		       0xa0000000 0x10000000>; /* prefetchable memory */
>> 		interrupts = <0 98 0x04   /* controller interrupt */
>> 		              0 99 0x04>; /* MSI interrupt */
>> 		status = "disabled";
>>
>> 		ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */
>> 			  0x80004000 0x80004000 0x00100000   /* configuration space */
>> 			  0x80104000 0x80104000 0x00100000   /* extended configuration space */
>> 			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
>> 			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
>> 			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
>>
>> 		#address-cells = <1>;
>> 		#size-cells = <1>;
>>
>> 		port@80000000 {
>> 			reg = <0x80000000 0x00001000>;
>> 			status = "disabled";
>> 		};
>>
>> 		port@80001000 {
>> 			reg = <0x80001000 0x00001000>;
>> 			status = "disabled";
>> 		};
>> 	};
>>
>> The "ranges" property can probably be cleaned up a bit, but the most
>> interesting part is the port@ children, which can simply be enabled in board
>> DTS files by setting the status property to "okay". I find that somewhat more
>> intuitive to the variant with an "enable-ports" property.
>>
>> What do you think of this?
> 
> The problem is that children of a PCI-ish bus have specific expectations
> about the parent address format - the standard 3-address-cell PCI
> addressing.  So making a PCI bus node - even if it is PCIe - with 1
> address cell is a problem.

Couldn't you put the #address-cells=<3> underneath each port node, and
put any PCIe devices there rather than under the main PCIe controller
node? I'm not sure how the interrupt mapping table etc. would work in
that case, but that seems to solve the addressing issue.

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-12 19:46                       ` Stephen Warren
  0 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-12 19:46 UTC (permalink / raw)
  To: Mitch Bradley
  Cc: Thierry Reding, Russell King, linux-pci, devicetree-discuss,
	Rob Herring, Jesse Barnes, Colin Cross, linux-tegra,
	linux-arm-kernel

On 06/12/2012 01:10 PM, Mitch Bradley wrote:
> On 6/12/2012 7:20 AM, Thierry Reding wrote:
...
>> I came up with the following alternative:
>>
>> 	pci {
>> 		compatible = "nvidia,tegra20-pcie";
>> 		reg = <0x80003000 0x00000800   /* PADS registers */
>> 		       0x80003800 0x00000200   /* AFI registers */
>> 		       0x80004000 0x00100000   /* configuration space */
>> 		       0x80104000 0x00100000   /* extended configuration space */
>> 		       0x80400000 0x00010000   /* downstream I/O */
>> 		       0x90000000 0x10000000   /* non-prefetchable memory */
>> 		       0xa0000000 0x10000000>; /* prefetchable memory */
>> 		interrupts = <0 98 0x04   /* controller interrupt */
>> 		              0 99 0x04>; /* MSI interrupt */
>> 		status = "disabled";
>>
>> 		ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */
>> 			  0x80004000 0x80004000 0x00100000   /* configuration space */
>> 			  0x80104000 0x80104000 0x00100000   /* extended configuration space */
>> 			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
>> 			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
>> 			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
>>
>> 		#address-cells = <1>;
>> 		#size-cells = <1>;
>>
>> 		port@80000000 {
>> 			reg = <0x80000000 0x00001000>;
>> 			status = "disabled";
>> 		};
>>
>> 		port@80001000 {
>> 			reg = <0x80001000 0x00001000>;
>> 			status = "disabled";
>> 		};
>> 	};
>>
>> The "ranges" property can probably be cleaned up a bit, but the most
>> interesting part is the port@ children, which can simply be enabled in board
>> DTS files by setting the status property to "okay". I find that somewhat more
>> intuitive to the variant with an "enable-ports" property.
>>
>> What do you think of this?
> 
> The problem is that children of a PCI-ish bus have specific expectations
> about the parent address format - the standard 3-address-cell PCI
> addressing.  So making a PCI bus node - even if it is PCIe - with 1
> address cell is a problem.

Couldn't you put the #address-cells=<3> underneath each port node, and
put any PCIe devices there rather than under the main PCIe controller
node? I'm not sure how the interrupt mapping table etc. would work in
that case, but that seems to solve the addressing issue.

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-12 19:46                       ` Stephen Warren
  0 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-12 19:46 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/12/2012 01:10 PM, Mitch Bradley wrote:
> On 6/12/2012 7:20 AM, Thierry Reding wrote:
...
>> I came up with the following alternative:
>>
>> 	pci {
>> 		compatible = "nvidia,tegra20-pcie";
>> 		reg = <0x80003000 0x00000800   /* PADS registers */
>> 		       0x80003800 0x00000200   /* AFI registers */
>> 		       0x80004000 0x00100000   /* configuration space */
>> 		       0x80104000 0x00100000   /* extended configuration space */
>> 		       0x80400000 0x00010000   /* downstream I/O */
>> 		       0x90000000 0x10000000   /* non-prefetchable memory */
>> 		       0xa0000000 0x10000000>; /* prefetchable memory */
>> 		interrupts = <0 98 0x04   /* controller interrupt */
>> 		              0 99 0x04>; /* MSI interrupt */
>> 		status = "disabled";
>>
>> 		ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */
>> 			  0x80004000 0x80004000 0x00100000   /* configuration space */
>> 			  0x80104000 0x80104000 0x00100000   /* extended configuration space */
>> 			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
>> 			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
>> 			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
>>
>> 		#address-cells = <1>;
>> 		#size-cells = <1>;
>>
>> 		port at 80000000 {
>> 			reg = <0x80000000 0x00001000>;
>> 			status = "disabled";
>> 		};
>>
>> 		port at 80001000 {
>> 			reg = <0x80001000 0x00001000>;
>> 			status = "disabled";
>> 		};
>> 	};
>>
>> The "ranges" property can probably be cleaned up a bit, but the most
>> interesting part is the port@ children, which can simply be enabled in board
>> DTS files by setting the status property to "okay". I find that somewhat more
>> intuitive to the variant with an "enable-ports" property.
>>
>> What do you think of this?
> 
> The problem is that children of a PCI-ish bus have specific expectations
> about the parent address format - the standard 3-address-cell PCI
> addressing.  So making a PCI bus node - even if it is PCIe - with 1
> address cell is a problem.

Couldn't you put the #address-cells=<3> underneath each port node, and
put any PCIe devices there rather than under the main PCIe controller
node? I'm not sure how the interrupt mapping table etc. would work in
that case, but that seems to solve the addressing issue.

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-12 19:46                       ` Stephen Warren
@ 2012-06-12 19:52                         ` Mitch Bradley
  -1 siblings, 0 replies; 249+ messages in thread
From: Mitch Bradley @ 2012-06-12 19:52 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Thierry Reding, Russell King, linux-pci, devicetree-discuss,
	Rob Herring, Jesse Barnes, Colin Cross, linux-tegra,
	linux-arm-kernel

On 6/12/2012 9:46 AM, Stephen Warren wrote:
> On 06/12/2012 01:10 PM, Mitch Bradley wrote:
>> On 6/12/2012 7:20 AM, Thierry Reding wrote:
> ...
>>> I came up with the following alternative:
>>>
>>> 	pci {
>>> 		compatible = "nvidia,tegra20-pcie";
>>> 		reg =<0x80003000 0x00000800   /* PADS registers */
>>> 		       0x80003800 0x00000200   /* AFI registers */
>>> 		       0x80004000 0x00100000   /* configuration space */
>>> 		       0x80104000 0x00100000   /* extended configuration space */
>>> 		       0x80400000 0x00010000   /* downstream I/O */
>>> 		       0x90000000 0x10000000   /* non-prefetchable memory */
>>> 		       0xa0000000 0x10000000>; /* prefetchable memory */
>>> 		interrupts =<0 98 0x04   /* controller interrupt */
>>> 		              0 99 0x04>; /* MSI interrupt */
>>> 		status = "disabled";
>>>
>>> 		ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
>>> 			  0x80004000 0x80004000 0x00100000   /* configuration space */
>>> 			  0x80104000 0x80104000 0x00100000   /* extended configuration space */
>>> 			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
>>> 			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
>>> 			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
>>>
>>> 		#address-cells =<1>;
>>> 		#size-cells =<1>;
>>>
>>> 		port@80000000 {
>>> 			reg =<0x80000000 0x00001000>;
>>> 			status = "disabled";
>>> 		};
>>>
>>> 		port@80001000 {
>>> 			reg =<0x80001000 0x00001000>;
>>> 			status = "disabled";
>>> 		};
>>> 	};
>>>
>>> The "ranges" property can probably be cleaned up a bit, but the most
>>> interesting part is the port@ children, which can simply be enabled in board
>>> DTS files by setting the status property to "okay". I find that somewhat more
>>> intuitive to the variant with an "enable-ports" property.
>>>
>>> What do you think of this?
>>
>> The problem is that children of a PCI-ish bus have specific expectations
>> about the parent address format - the standard 3-address-cell PCI
>> addressing.  So making a PCI bus node - even if it is PCIe - with 1
>> address cell is a problem.
>
> Couldn't you put the #address-cells=<3>  underneath each port node, and
> put any PCIe devices there rather than under the main PCIe controller
> node? I'm not sure how the interrupt mapping table etc. would work in
> that case, but that seems to solve the addressing issue.

Yes, that would work just fine, and in fact would be preferable, if a 
"root port" is essentially an independent PCI bus.  The parent of those 
root ports should not be named "pci", though, as it is not in itself a 
PCI bus.  It could be called "pcis".

>
>

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-12 19:52                         ` Mitch Bradley
  0 siblings, 0 replies; 249+ messages in thread
From: Mitch Bradley @ 2012-06-12 19:52 UTC (permalink / raw)
  To: linux-arm-kernel

On 6/12/2012 9:46 AM, Stephen Warren wrote:
> On 06/12/2012 01:10 PM, Mitch Bradley wrote:
>> On 6/12/2012 7:20 AM, Thierry Reding wrote:
> ...
>>> I came up with the following alternative:
>>>
>>> 	pci {
>>> 		compatible = "nvidia,tegra20-pcie";
>>> 		reg =<0x80003000 0x00000800   /* PADS registers */
>>> 		       0x80003800 0x00000200   /* AFI registers */
>>> 		       0x80004000 0x00100000   /* configuration space */
>>> 		       0x80104000 0x00100000   /* extended configuration space */
>>> 		       0x80400000 0x00010000   /* downstream I/O */
>>> 		       0x90000000 0x10000000   /* non-prefetchable memory */
>>> 		       0xa0000000 0x10000000>; /* prefetchable memory */
>>> 		interrupts =<0 98 0x04   /* controller interrupt */
>>> 		              0 99 0x04>; /* MSI interrupt */
>>> 		status = "disabled";
>>>
>>> 		ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
>>> 			  0x80004000 0x80004000 0x00100000   /* configuration space */
>>> 			  0x80104000 0x80104000 0x00100000   /* extended configuration space */
>>> 			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
>>> 			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
>>> 			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
>>>
>>> 		#address-cells =<1>;
>>> 		#size-cells =<1>;
>>>
>>> 		port at 80000000 {
>>> 			reg =<0x80000000 0x00001000>;
>>> 			status = "disabled";
>>> 		};
>>>
>>> 		port at 80001000 {
>>> 			reg =<0x80001000 0x00001000>;
>>> 			status = "disabled";
>>> 		};
>>> 	};
>>>
>>> The "ranges" property can probably be cleaned up a bit, but the most
>>> interesting part is the port@ children, which can simply be enabled in board
>>> DTS files by setting the status property to "okay". I find that somewhat more
>>> intuitive to the variant with an "enable-ports" property.
>>>
>>> What do you think of this?
>>
>> The problem is that children of a PCI-ish bus have specific expectations
>> about the parent address format - the standard 3-address-cell PCI
>> addressing.  So making a PCI bus node - even if it is PCIe - with 1
>> address cell is a problem.
>
> Couldn't you put the #address-cells=<3>  underneath each port node, and
> put any PCIe devices there rather than under the main PCIe controller
> node? I'm not sure how the interrupt mapping table etc. would work in
> that case, but that seems to solve the addressing issue.

Yes, that would work just fine, and in fact would be preferable, if a 
"root port" is essentially an independent PCI bus.  The parent of those 
root ports should not be named "pci", though, as it is not in itself a 
PCI bus.  It could be called "pcis".

>
>

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-12 17:20               ` Thierry Reding
@ 2012-06-12 20:15                 ` Stephen Warren
  -1 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-12 20:15 UTC (permalink / raw)
  To: Thierry Reding
  Cc: linux-tegra, Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson

On 06/12/2012 11:20 AM, Thierry Reding wrote:
...
> I came up with the following alternative:
> 
> 	pci {
> 		compatible = "nvidia,tegra20-pcie";
> 		reg = <0x80003000 0x00000800   /* PADS registers */
> 		       0x80003800 0x00000200   /* AFI registers */
> 		       0x80004000 0x00100000   /* configuration space */
> 		       0x80104000 0x00100000   /* extended configuration space */
> 		       0x80400000 0x00010000   /* downstream I/O */
> 		       0x90000000 0x10000000   /* non-prefetchable memory */
> 		       0xa0000000 0x10000000>; /* prefetchable memory */
> 		interrupts = <0 98 0x04   /* controller interrupt */
> 		              0 99 0x04>; /* MSI interrupt */
> 		status = "disabled";
> 
> 		ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */
> 			  0x80004000 0x80004000 0x00100000   /* configuration space */
> 			  0x80104000 0x80104000 0x00100000   /* extended configuration space */
> 			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
> 			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
> 			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
> 
> 		#address-cells = <1>;
> 		#size-cells = <1>;
> 
> 		port@80000000 {
> 			reg = <0x80000000 0x00001000>;
> 			status = "disabled";
> 		};
> 
> 		port@80001000 {
> 			reg = <0x80001000 0x00001000>;
> 			status = "disabled";
> 		};
> 	};
> 
> The "ranges" property can probably be cleaned up a bit, but the most
> interesting part is the port@ children, which can simply be enabled in board
> DTS files by setting the status property to "okay". I find that somewhat more
> intuitive to the variant with an "enable-ports" property.
> 
> What do you think of this?

As a general concept, this kind of design seems OK to me.

The "port" child nodes I think should be named "pci@..." given Mitch's
comments, I think.

The port nodes probably need two entries in reg, given the following in
our downstream driver:

>         int rp_offset = 0;
>         int ctrl_offset = AFI_PEX0_CTRL;
...
>         for (port = 0; port < MAX_PCIE_SUPPORTED_PORTS; port++) {
>                 ctrl_offset += (port * 8);
>                 rp_offset = (rp_offset + 0x1000) * port;
>                 if (tegra_pcie.plat_data->port_status[port])
>                         tegra_pcie_add_port(port, rp_offset, ctrl_offset);
>         }

(which actually looks likely to be horribly buggy for port>1 and only
accidentally correct for port==1, but anyway...)

But instead, I'd be tempted to make the top-level node say:

	#address-cells = <1>;
	#size-cells = <0>;

... so that the child nodes' reg is just the port ID. The parent node
can calculate the addresses/offsets of the per-port registers within the
PCIe controller's register space based on the ID using code roughly like
what I quoted above:

	pci@0 {
		reg = <0>;
		status = "disabled";
	};

	pci@1 {
		reg = <0>;
		status = "disabled";
	};

That would save having to put 2 entries in the reg, and perhaps remove
the need for any ranges property.

I think you also need a property to specify the exact port layout; the
Tegra20 controller supports:

1 x4 port
2 x2 ports (you can choose to use only 1 of these I assume)

So just because only 1 of the ports is enabled, doesn't imply it's x4;
it could still be x2.

Tegra30 has more options.

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-12 20:15                 ` Stephen Warren
  0 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-12 20:15 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/12/2012 11:20 AM, Thierry Reding wrote:
...
> I came up with the following alternative:
> 
> 	pci {
> 		compatible = "nvidia,tegra20-pcie";
> 		reg = <0x80003000 0x00000800   /* PADS registers */
> 		       0x80003800 0x00000200   /* AFI registers */
> 		       0x80004000 0x00100000   /* configuration space */
> 		       0x80104000 0x00100000   /* extended configuration space */
> 		       0x80400000 0x00010000   /* downstream I/O */
> 		       0x90000000 0x10000000   /* non-prefetchable memory */
> 		       0xa0000000 0x10000000>; /* prefetchable memory */
> 		interrupts = <0 98 0x04   /* controller interrupt */
> 		              0 99 0x04>; /* MSI interrupt */
> 		status = "disabled";
> 
> 		ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */
> 			  0x80004000 0x80004000 0x00100000   /* configuration space */
> 			  0x80104000 0x80104000 0x00100000   /* extended configuration space */
> 			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
> 			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
> 			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
> 
> 		#address-cells = <1>;
> 		#size-cells = <1>;
> 
> 		port at 80000000 {
> 			reg = <0x80000000 0x00001000>;
> 			status = "disabled";
> 		};
> 
> 		port at 80001000 {
> 			reg = <0x80001000 0x00001000>;
> 			status = "disabled";
> 		};
> 	};
> 
> The "ranges" property can probably be cleaned up a bit, but the most
> interesting part is the port@ children, which can simply be enabled in board
> DTS files by setting the status property to "okay". I find that somewhat more
> intuitive to the variant with an "enable-ports" property.
> 
> What do you think of this?

As a general concept, this kind of design seems OK to me.

The "port" child nodes I think should be named "pci at ..." given Mitch's
comments, I think.

The port nodes probably need two entries in reg, given the following in
our downstream driver:

>         int rp_offset = 0;
>         int ctrl_offset = AFI_PEX0_CTRL;
...
>         for (port = 0; port < MAX_PCIE_SUPPORTED_PORTS; port++) {
>                 ctrl_offset += (port * 8);
>                 rp_offset = (rp_offset + 0x1000) * port;
>                 if (tegra_pcie.plat_data->port_status[port])
>                         tegra_pcie_add_port(port, rp_offset, ctrl_offset);
>         }

(which actually looks likely to be horribly buggy for port>1 and only
accidentally correct for port==1, but anyway...)

But instead, I'd be tempted to make the top-level node say:

	#address-cells = <1>;
	#size-cells = <0>;

... so that the child nodes' reg is just the port ID. The parent node
can calculate the addresses/offsets of the per-port registers within the
PCIe controller's register space based on the ID using code roughly like
what I quoted above:

	pci at 0 {
		reg = <0>;
		status = "disabled";
	};

	pci at 1 {
		reg = <0>;
		status = "disabled";
	};

That would save having to put 2 entries in the reg, and perhaps remove
the need for any ranges property.

I think you also need a property to specify the exact port layout; the
Tegra20 controller supports:

1 x4 port
2 x2 ports (you can choose to use only 1 of these I assume)

So just because only 1 of the ports is enabled, doesn't imply it's x4;
it could still be x2.

Tegra30 has more options.

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-12 20:15                 ` Stephen Warren
@ 2012-06-12 21:11                   ` Mitch Bradley
  -1 siblings, 0 replies; 249+ messages in thread
From: Mitch Bradley @ 2012-06-12 21:11 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Thierry Reding, Russell King, linux-pci, devicetree-discuss,
	Rob Herring, Jesse Barnes, Colin Cross, linux-tegra,
	linux-arm-kernel

On 6/12/2012 10:15 AM, Stephen Warren wrote:
> On 06/12/2012 11:20 AM, Thierry Reding wrote:
> ...
>> I came up with the following alternative:
>>
>> 	pci {
>> 		compatible = "nvidia,tegra20-pcie";
>> 		reg =<0x80003000 0x00000800   /* PADS registers */
>> 		       0x80003800 0x00000200   /* AFI registers */
>> 		       0x80004000 0x00100000   /* configuration space */
>> 		       0x80104000 0x00100000   /* extended configuration space */
>> 		       0x80400000 0x00010000   /* downstream I/O */
>> 		       0x90000000 0x10000000   /* non-prefetchable memory */
>> 		       0xa0000000 0x10000000>; /* prefetchable memory */
>> 		interrupts =<0 98 0x04   /* controller interrupt */
>> 		              0 99 0x04>; /* MSI interrupt */
>> 		status = "disabled";
>>
>> 		ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
>> 			  0x80004000 0x80004000 0x00100000   /* configuration space */
>> 			  0x80104000 0x80104000 0x00100000   /* extended configuration space */
>> 			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
>> 			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
>> 			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
>>
>> 		#address-cells =<1>;
>> 		#size-cells =<1>;
>>
>> 		port@80000000 {
>> 			reg =<0x80000000 0x00001000>;
>> 			status = "disabled";
>> 		};
>>
>> 		port@80001000 {
>> 			reg =<0x80001000 0x00001000>;
>> 			status = "disabled";
>> 		};
>> 	};
>>
>> The "ranges" property can probably be cleaned up a bit, but the most
>> interesting part is the port@ children, which can simply be enabled in board
>> DTS files by setting the status property to "okay". I find that somewhat more
>> intuitive to the variant with an "enable-ports" property.
>>
>> What do you think of this?
>
> As a general concept, this kind of design seems OK to me.
>
> The "port" child nodes I think should be named "pci@..." given Mitch's
> comments, I think.
>
> The port nodes probably need two entries in reg, given the following in
> our downstream driver:
>
>>          int rp_offset = 0;
>>          int ctrl_offset = AFI_PEX0_CTRL;
> ...
>>          for (port = 0; port<  MAX_PCIE_SUPPORTED_PORTS; port++) {
>>                  ctrl_offset += (port * 8);
>>                  rp_offset = (rp_offset + 0x1000) * port;
>>                  if (tegra_pcie.plat_data->port_status[port])
>>                          tegra_pcie_add_port(port, rp_offset, ctrl_offset);
>>          }
>
> (which actually looks likely to be horribly buggy for port>1 and only
> accidentally correct for port==1, but anyway...)
>
> But instead, I'd be tempted to make the top-level node say:
>
> 	#address-cells =<1>;
> 	#size-cells =<0>;
>
> ... so that the child nodes' reg is just the port ID. The parent node
> can calculate the addresses/offsets of the per-port registers within the
> PCIe controller's register space based on the ID using code roughly like
> what I quoted above:
>
> 	pci@0 {
> 		reg =<0>;
> 		status = "disabled";
> 	};
>
> 	pci@1 {
> 		reg =<0>;
> 		status = "disabled";
> 	};
reg = <1> ?

>
>
> That would save having to put 2 entries in the reg, and perhaps remove
> the need for any ranges property.

ISTM that having two reg entries, specifying the rp and ctrl registers, 
is preferable to having code to calculate the addresses.  That makes the 
code simpler and the device tree more directly descriptive of the 
hardware layout.  The less "magic" (in this case, the register address 
calculation), the better.

>
>
> I think you also need a property to specify the exact port layout; the
> Tegra20 controller supports:
>
> 1 x4 port
> 2 x2 ports (you can choose to use only 1 of these I assume)
>
> So just because only 1 of the ports is enabled, doesn't imply it's x4;
> it could still be x2.
>
> Tegra30 has more options.
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss
>

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-12 21:11                   ` Mitch Bradley
  0 siblings, 0 replies; 249+ messages in thread
From: Mitch Bradley @ 2012-06-12 21:11 UTC (permalink / raw)
  To: linux-arm-kernel

On 6/12/2012 10:15 AM, Stephen Warren wrote:
> On 06/12/2012 11:20 AM, Thierry Reding wrote:
> ...
>> I came up with the following alternative:
>>
>> 	pci {
>> 		compatible = "nvidia,tegra20-pcie";
>> 		reg =<0x80003000 0x00000800   /* PADS registers */
>> 		       0x80003800 0x00000200   /* AFI registers */
>> 		       0x80004000 0x00100000   /* configuration space */
>> 		       0x80104000 0x00100000   /* extended configuration space */
>> 		       0x80400000 0x00010000   /* downstream I/O */
>> 		       0x90000000 0x10000000   /* non-prefetchable memory */
>> 		       0xa0000000 0x10000000>; /* prefetchable memory */
>> 		interrupts =<0 98 0x04   /* controller interrupt */
>> 		              0 99 0x04>; /* MSI interrupt */
>> 		status = "disabled";
>>
>> 		ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
>> 			  0x80004000 0x80004000 0x00100000   /* configuration space */
>> 			  0x80104000 0x80104000 0x00100000   /* extended configuration space */
>> 			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
>> 			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
>> 			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
>>
>> 		#address-cells =<1>;
>> 		#size-cells =<1>;
>>
>> 		port at 80000000 {
>> 			reg =<0x80000000 0x00001000>;
>> 			status = "disabled";
>> 		};
>>
>> 		port at 80001000 {
>> 			reg =<0x80001000 0x00001000>;
>> 			status = "disabled";
>> 		};
>> 	};
>>
>> The "ranges" property can probably be cleaned up a bit, but the most
>> interesting part is the port@ children, which can simply be enabled in board
>> DTS files by setting the status property to "okay". I find that somewhat more
>> intuitive to the variant with an "enable-ports" property.
>>
>> What do you think of this?
>
> As a general concept, this kind of design seems OK to me.
>
> The "port" child nodes I think should be named "pci at ..." given Mitch's
> comments, I think.
>
> The port nodes probably need two entries in reg, given the following in
> our downstream driver:
>
>>          int rp_offset = 0;
>>          int ctrl_offset = AFI_PEX0_CTRL;
> ...
>>          for (port = 0; port<  MAX_PCIE_SUPPORTED_PORTS; port++) {
>>                  ctrl_offset += (port * 8);
>>                  rp_offset = (rp_offset + 0x1000) * port;
>>                  if (tegra_pcie.plat_data->port_status[port])
>>                          tegra_pcie_add_port(port, rp_offset, ctrl_offset);
>>          }
>
> (which actually looks likely to be horribly buggy for port>1 and only
> accidentally correct for port==1, but anyway...)
>
> But instead, I'd be tempted to make the top-level node say:
>
> 	#address-cells =<1>;
> 	#size-cells =<0>;
>
> ... so that the child nodes' reg is just the port ID. The parent node
> can calculate the addresses/offsets of the per-port registers within the
> PCIe controller's register space based on the ID using code roughly like
> what I quoted above:
>
> 	pci at 0 {
> 		reg =<0>;
> 		status = "disabled";
> 	};
>
> 	pci at 1 {
> 		reg =<0>;
> 		status = "disabled";
> 	};
reg = <1> ?

>
>
> That would save having to put 2 entries in the reg, and perhaps remove
> the need for any ranges property.

ISTM that having two reg entries, specifying the rp and ctrl registers, 
is preferable to having code to calculate the addresses.  That makes the 
code simpler and the device tree more directly descriptive of the 
hardware layout.  The less "magic" (in this case, the register address 
calculation), the better.

>
>
> I think you also need a property to specify the exact port layout; the
> Tegra20 controller supports:
>
> 1 x4 port
> 2 x2 ports (you can choose to use only 1 of these I assume)
>
> So just because only 1 of the ports is enabled, doesn't imply it's x4;
> it could still be x2.
>
> Tegra30 has more options.
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss at lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss
>

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-12 19:52                         ` Mitch Bradley
  (?)
@ 2012-06-13  5:54                             ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-13  5:54 UTC (permalink / raw)
  To: Mitch Bradley
  Cc: Stephen Warren, Russell King, linux-pci-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Jesse Barnes, Colin Cross, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

[-- Attachment #1: Type: text/plain, Size: 3054 bytes --]

* Mitch Bradley wrote:
> On 6/12/2012 9:46 AM, Stephen Warren wrote:
> >On 06/12/2012 01:10 PM, Mitch Bradley wrote:
> >>On 6/12/2012 7:20 AM, Thierry Reding wrote:
> >...
> >>>I came up with the following alternative:
> >>>
> >>>	pci {
> >>>		compatible = "nvidia,tegra20-pcie";
> >>>		reg =<0x80003000 0x00000800   /* PADS registers */
> >>>		       0x80003800 0x00000200   /* AFI registers */
> >>>		       0x80004000 0x00100000   /* configuration space */
> >>>		       0x80104000 0x00100000   /* extended configuration space */
> >>>		       0x80400000 0x00010000   /* downstream I/O */
> >>>		       0x90000000 0x10000000   /* non-prefetchable memory */
> >>>		       0xa0000000 0x10000000>; /* prefetchable memory */
> >>>		interrupts =<0 98 0x04   /* controller interrupt */
> >>>		              0 99 0x04>; /* MSI interrupt */
> >>>		status = "disabled";
> >>>
> >>>		ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
> >>>			  0x80004000 0x80004000 0x00100000   /* configuration space */
> >>>			  0x80104000 0x80104000 0x00100000   /* extended configuration space */
> >>>			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
> >>>			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
> >>>			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
> >>>
> >>>		#address-cells =<1>;
> >>>		#size-cells =<1>;
> >>>
> >>>		port@80000000 {
> >>>			reg =<0x80000000 0x00001000>;
> >>>			status = "disabled";
> >>>		};
> >>>
> >>>		port@80001000 {
> >>>			reg =<0x80001000 0x00001000>;
> >>>			status = "disabled";
> >>>		};
> >>>	};
> >>>
> >>>The "ranges" property can probably be cleaned up a bit, but the most
> >>>interesting part is the port@ children, which can simply be enabled in board
> >>>DTS files by setting the status property to "okay". I find that somewhat more
> >>>intuitive to the variant with an "enable-ports" property.
> >>>
> >>>What do you think of this?
> >>
> >>The problem is that children of a PCI-ish bus have specific expectations
> >>about the parent address format - the standard 3-address-cell PCI
> >>addressing.  So making a PCI bus node - even if it is PCIe - with 1
> >>address cell is a problem.
> >
> >Couldn't you put the #address-cells=<3>  underneath each port node, and
> >put any PCIe devices there rather than under the main PCIe controller
> >node? I'm not sure how the interrupt mapping table etc. would work in
> >that case, but that seems to solve the addressing issue.
> 
> Yes, that would work just fine, and in fact would be preferable, if
> a "root port" is essentially an independent PCI bus.  The parent of
> those root ports should not be named "pci", though, as it is not in
> itself a PCI bus.  It could be called "pcis".

Yes, on Tegra each of the ports provides a separate PCI bus. How about naming
the parent "pcie-controller"? IMO that reflects the nature of the device
better, whereas "pcis" would seem more like a "virtual" node for collecting
similar children.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-13  5:54                             ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-13  5:54 UTC (permalink / raw)
  To: Mitch Bradley
  Cc: Stephen Warren, Russell King, linux-pci, devicetree-discuss,
	Rob Herring, Jesse Barnes, Colin Cross, linux-tegra,
	linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 3054 bytes --]

* Mitch Bradley wrote:
> On 6/12/2012 9:46 AM, Stephen Warren wrote:
> >On 06/12/2012 01:10 PM, Mitch Bradley wrote:
> >>On 6/12/2012 7:20 AM, Thierry Reding wrote:
> >...
> >>>I came up with the following alternative:
> >>>
> >>>	pci {
> >>>		compatible = "nvidia,tegra20-pcie";
> >>>		reg =<0x80003000 0x00000800   /* PADS registers */
> >>>		       0x80003800 0x00000200   /* AFI registers */
> >>>		       0x80004000 0x00100000   /* configuration space */
> >>>		       0x80104000 0x00100000   /* extended configuration space */
> >>>		       0x80400000 0x00010000   /* downstream I/O */
> >>>		       0x90000000 0x10000000   /* non-prefetchable memory */
> >>>		       0xa0000000 0x10000000>; /* prefetchable memory */
> >>>		interrupts =<0 98 0x04   /* controller interrupt */
> >>>		              0 99 0x04>; /* MSI interrupt */
> >>>		status = "disabled";
> >>>
> >>>		ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
> >>>			  0x80004000 0x80004000 0x00100000   /* configuration space */
> >>>			  0x80104000 0x80104000 0x00100000   /* extended configuration space */
> >>>			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
> >>>			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
> >>>			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
> >>>
> >>>		#address-cells =<1>;
> >>>		#size-cells =<1>;
> >>>
> >>>		port@80000000 {
> >>>			reg =<0x80000000 0x00001000>;
> >>>			status = "disabled";
> >>>		};
> >>>
> >>>		port@80001000 {
> >>>			reg =<0x80001000 0x00001000>;
> >>>			status = "disabled";
> >>>		};
> >>>	};
> >>>
> >>>The "ranges" property can probably be cleaned up a bit, but the most
> >>>interesting part is the port@ children, which can simply be enabled in board
> >>>DTS files by setting the status property to "okay". I find that somewhat more
> >>>intuitive to the variant with an "enable-ports" property.
> >>>
> >>>What do you think of this?
> >>
> >>The problem is that children of a PCI-ish bus have specific expectations
> >>about the parent address format - the standard 3-address-cell PCI
> >>addressing.  So making a PCI bus node - even if it is PCIe - with 1
> >>address cell is a problem.
> >
> >Couldn't you put the #address-cells=<3>  underneath each port node, and
> >put any PCIe devices there rather than under the main PCIe controller
> >node? I'm not sure how the interrupt mapping table etc. would work in
> >that case, but that seems to solve the addressing issue.
> 
> Yes, that would work just fine, and in fact would be preferable, if
> a "root port" is essentially an independent PCI bus.  The parent of
> those root ports should not be named "pci", though, as it is not in
> itself a PCI bus.  It could be called "pcis".

Yes, on Tegra each of the ports provides a separate PCI bus. How about naming
the parent "pcie-controller"? IMO that reflects the nature of the device
better, whereas "pcis" would seem more like a "virtual" node for collecting
similar children.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-13  5:54                             ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-13  5:54 UTC (permalink / raw)
  To: linux-arm-kernel

* Mitch Bradley wrote:
> On 6/12/2012 9:46 AM, Stephen Warren wrote:
> >On 06/12/2012 01:10 PM, Mitch Bradley wrote:
> >>On 6/12/2012 7:20 AM, Thierry Reding wrote:
> >...
> >>>I came up with the following alternative:
> >>>
> >>>	pci {
> >>>		compatible = "nvidia,tegra20-pcie";
> >>>		reg =<0x80003000 0x00000800   /* PADS registers */
> >>>		       0x80003800 0x00000200   /* AFI registers */
> >>>		       0x80004000 0x00100000   /* configuration space */
> >>>		       0x80104000 0x00100000   /* extended configuration space */
> >>>		       0x80400000 0x00010000   /* downstream I/O */
> >>>		       0x90000000 0x10000000   /* non-prefetchable memory */
> >>>		       0xa0000000 0x10000000>; /* prefetchable memory */
> >>>		interrupts =<0 98 0x04   /* controller interrupt */
> >>>		              0 99 0x04>; /* MSI interrupt */
> >>>		status = "disabled";
> >>>
> >>>		ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
> >>>			  0x80004000 0x80004000 0x00100000   /* configuration space */
> >>>			  0x80104000 0x80104000 0x00100000   /* extended configuration space */
> >>>			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
> >>>			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
> >>>			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
> >>>
> >>>		#address-cells =<1>;
> >>>		#size-cells =<1>;
> >>>
> >>>		port at 80000000 {
> >>>			reg =<0x80000000 0x00001000>;
> >>>			status = "disabled";
> >>>		};
> >>>
> >>>		port at 80001000 {
> >>>			reg =<0x80001000 0x00001000>;
> >>>			status = "disabled";
> >>>		};
> >>>	};
> >>>
> >>>The "ranges" property can probably be cleaned up a bit, but the most
> >>>interesting part is the port@ children, which can simply be enabled in board
> >>>DTS files by setting the status property to "okay". I find that somewhat more
> >>>intuitive to the variant with an "enable-ports" property.
> >>>
> >>>What do you think of this?
> >>
> >>The problem is that children of a PCI-ish bus have specific expectations
> >>about the parent address format - the standard 3-address-cell PCI
> >>addressing.  So making a PCI bus node - even if it is PCIe - with 1
> >>address cell is a problem.
> >
> >Couldn't you put the #address-cells=<3>  underneath each port node, and
> >put any PCIe devices there rather than under the main PCIe controller
> >node? I'm not sure how the interrupt mapping table etc. would work in
> >that case, but that seems to solve the addressing issue.
> 
> Yes, that would work just fine, and in fact would be preferable, if
> a "root port" is essentially an independent PCI bus.  The parent of
> those root ports should not be named "pci", though, as it is not in
> itself a PCI bus.  It could be called "pcis".

Yes, on Tegra each of the ports provides a separate PCI bus. How about naming
the parent "pcie-controller"? IMO that reflects the nature of the device
better, whereas "pcis" would seem more like a "virtual" node for collecting
similar children.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120613/e7746e30/attachment-0001.sig>

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-12 20:15                 ` Stephen Warren
  (?)
@ 2012-06-13  6:34                     ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-13  6:34 UTC (permalink / raw)
  To: Stephen Warren
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jesse Barnes,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, Grant Likely, Rob Herring,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Russell King,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Colin Cross,
	Olof Johansson

[-- Attachment #1: Type: text/plain, Size: 5024 bytes --]

* Stephen Warren wrote:
> On 06/12/2012 11:20 AM, Thierry Reding wrote:
> ...
> > I came up with the following alternative:
> > 
> > 	pci {
> > 		compatible = "nvidia,tegra20-pcie";
> > 		reg = <0x80003000 0x00000800   /* PADS registers */
> > 		       0x80003800 0x00000200   /* AFI registers */
> > 		       0x80004000 0x00100000   /* configuration space */
> > 		       0x80104000 0x00100000   /* extended configuration space */
> > 		       0x80400000 0x00010000   /* downstream I/O */
> > 		       0x90000000 0x10000000   /* non-prefetchable memory */
> > 		       0xa0000000 0x10000000>; /* prefetchable memory */
> > 		interrupts = <0 98 0x04   /* controller interrupt */
> > 		              0 99 0x04>; /* MSI interrupt */
> > 		status = "disabled";
> > 
> > 		ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */
> > 			  0x80004000 0x80004000 0x00100000   /* configuration space */
> > 			  0x80104000 0x80104000 0x00100000   /* extended configuration space */
> > 			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
> > 			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
> > 			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
> > 
> > 		#address-cells = <1>;
> > 		#size-cells = <1>;
> > 
> > 		port@80000000 {
> > 			reg = <0x80000000 0x00001000>;
> > 			status = "disabled";
> > 		};
> > 
> > 		port@80001000 {
> > 			reg = <0x80001000 0x00001000>;
> > 			status = "disabled";
> > 		};
> > 	};
> > 
> > The "ranges" property can probably be cleaned up a bit, but the most
> > interesting part is the port@ children, which can simply be enabled in board
> > DTS files by setting the status property to "okay". I find that somewhat more
> > intuitive to the variant with an "enable-ports" property.
> > 
> > What do you think of this?
> 
> As a general concept, this kind of design seems OK to me.
> 
> The "port" child nodes I think should be named "pci@..." given Mitch's
> comments, I think.
> 
> The port nodes probably need two entries in reg, given the following in
> our downstream driver:
> 
> >         int rp_offset = 0;
> >         int ctrl_offset = AFI_PEX0_CTRL;
> ...
> >         for (port = 0; port < MAX_PCIE_SUPPORTED_PORTS; port++) {
> >                 ctrl_offset += (port * 8);
> >                 rp_offset = (rp_offset + 0x1000) * port;
> >                 if (tegra_pcie.plat_data->port_status[port])
> >                         tegra_pcie_add_port(port, rp_offset, ctrl_offset);
> >         }
> 
> (which actually looks likely to be horribly buggy for port>1 and only
> accidentally correct for port==1, but anyway...)

Yeah, I currently have code that gets the port index and the reset register
offset (ctrl_offset above) from the port address. It feels rather hackish,
though.

> But instead, I'd be tempted to make the top-level node say:
> 
> 	#address-cells = <1>;
> 	#size-cells = <0>;
> 
> ... so that the child nodes' reg is just the port ID. The parent node
> can calculate the addresses/offsets of the per-port registers within the
> PCIe controller's register space based on the ID using code roughly like
> what I quoted above:
> 
> 	pci@0 {
> 		reg = <0>;
> 		status = "disabled";
> 	};
> 
> 	pci@1 {
> 		reg = <0>;
> 		status = "disabled";
> 	};
> 
> That would save having to put 2 entries in the reg, and perhaps remove
> the need for any ranges property.
> 
> I think you also need a property to specify the exact port layout; the
> Tegra20 controller supports:
> 
> 1 x4 port
> 2 x2 ports (you can choose to use only 1 of these I assume)
> 
> So just because only 1 of the ports is enabled, doesn't imply it's x4;
> it could still be x2.
> 
> Tegra30 has more options.

Both the upstream and downstream drivers currently hard-code this to dual and
411 (I assume that means 1x4, 2x1?) configurations for Tegra20 and Tegra30
respectively. Unfortunately the register AFI_PCIE_CONFIG isn't documented on
Tegra20 at all and for Tegra30 lists only the valid configurations (see
28.4.1.5 PCIe CONFIG) but not the corresponding encodings.

Maybe a good name for the new property would be "num-lanes". I also wonder if
this property would be better off in the parent node, which would make it
easier to check for valid configurations. Otherwise the code would have to
collect the settings of all the ports and check if the combination is valid.
Then again, having num-lanes in the parent with one cell for each controller
isn't very nice if each controller can be individually disabled.

One other thing: in addition to the device tree binding, this will all have to
be represented in the platform data as well to support the legacy board
definitions currently in the tree. But instead of adding all of these changes
to the patch that converts the code to a driver, I'm thinking it might be
better to split these additions off into one or more separate patches. Do you
have any objections?

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-13  6:34                     ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-13  6:34 UTC (permalink / raw)
  To: Stephen Warren
  Cc: linux-tegra, Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson

[-- Attachment #1: Type: text/plain, Size: 5024 bytes --]

* Stephen Warren wrote:
> On 06/12/2012 11:20 AM, Thierry Reding wrote:
> ...
> > I came up with the following alternative:
> > 
> > 	pci {
> > 		compatible = "nvidia,tegra20-pcie";
> > 		reg = <0x80003000 0x00000800   /* PADS registers */
> > 		       0x80003800 0x00000200   /* AFI registers */
> > 		       0x80004000 0x00100000   /* configuration space */
> > 		       0x80104000 0x00100000   /* extended configuration space */
> > 		       0x80400000 0x00010000   /* downstream I/O */
> > 		       0x90000000 0x10000000   /* non-prefetchable memory */
> > 		       0xa0000000 0x10000000>; /* prefetchable memory */
> > 		interrupts = <0 98 0x04   /* controller interrupt */
> > 		              0 99 0x04>; /* MSI interrupt */
> > 		status = "disabled";
> > 
> > 		ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */
> > 			  0x80004000 0x80004000 0x00100000   /* configuration space */
> > 			  0x80104000 0x80104000 0x00100000   /* extended configuration space */
> > 			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
> > 			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
> > 			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
> > 
> > 		#address-cells = <1>;
> > 		#size-cells = <1>;
> > 
> > 		port@80000000 {
> > 			reg = <0x80000000 0x00001000>;
> > 			status = "disabled";
> > 		};
> > 
> > 		port@80001000 {
> > 			reg = <0x80001000 0x00001000>;
> > 			status = "disabled";
> > 		};
> > 	};
> > 
> > The "ranges" property can probably be cleaned up a bit, but the most
> > interesting part is the port@ children, which can simply be enabled in board
> > DTS files by setting the status property to "okay". I find that somewhat more
> > intuitive to the variant with an "enable-ports" property.
> > 
> > What do you think of this?
> 
> As a general concept, this kind of design seems OK to me.
> 
> The "port" child nodes I think should be named "pci@..." given Mitch's
> comments, I think.
> 
> The port nodes probably need two entries in reg, given the following in
> our downstream driver:
> 
> >         int rp_offset = 0;
> >         int ctrl_offset = AFI_PEX0_CTRL;
> ...
> >         for (port = 0; port < MAX_PCIE_SUPPORTED_PORTS; port++) {
> >                 ctrl_offset += (port * 8);
> >                 rp_offset = (rp_offset + 0x1000) * port;
> >                 if (tegra_pcie.plat_data->port_status[port])
> >                         tegra_pcie_add_port(port, rp_offset, ctrl_offset);
> >         }
> 
> (which actually looks likely to be horribly buggy for port>1 and only
> accidentally correct for port==1, but anyway...)

Yeah, I currently have code that gets the port index and the reset register
offset (ctrl_offset above) from the port address. It feels rather hackish,
though.

> But instead, I'd be tempted to make the top-level node say:
> 
> 	#address-cells = <1>;
> 	#size-cells = <0>;
> 
> ... so that the child nodes' reg is just the port ID. The parent node
> can calculate the addresses/offsets of the per-port registers within the
> PCIe controller's register space based on the ID using code roughly like
> what I quoted above:
> 
> 	pci@0 {
> 		reg = <0>;
> 		status = "disabled";
> 	};
> 
> 	pci@1 {
> 		reg = <0>;
> 		status = "disabled";
> 	};
> 
> That would save having to put 2 entries in the reg, and perhaps remove
> the need for any ranges property.
> 
> I think you also need a property to specify the exact port layout; the
> Tegra20 controller supports:
> 
> 1 x4 port
> 2 x2 ports (you can choose to use only 1 of these I assume)
> 
> So just because only 1 of the ports is enabled, doesn't imply it's x4;
> it could still be x2.
> 
> Tegra30 has more options.

Both the upstream and downstream drivers currently hard-code this to dual and
411 (I assume that means 1x4, 2x1?) configurations for Tegra20 and Tegra30
respectively. Unfortunately the register AFI_PCIE_CONFIG isn't documented on
Tegra20 at all and for Tegra30 lists only the valid configurations (see
28.4.1.5 PCIe CONFIG) but not the corresponding encodings.

Maybe a good name for the new property would be "num-lanes". I also wonder if
this property would be better off in the parent node, which would make it
easier to check for valid configurations. Otherwise the code would have to
collect the settings of all the ports and check if the combination is valid.
Then again, having num-lanes in the parent with one cell for each controller
isn't very nice if each controller can be individually disabled.

One other thing: in addition to the device tree binding, this will all have to
be represented in the platform data as well to support the legacy board
definitions currently in the tree. But instead of adding all of these changes
to the patch that converts the code to a driver, I'm thinking it might be
better to split these additions off into one or more separate patches. Do you
have any objections?

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-13  6:34                     ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-13  6:34 UTC (permalink / raw)
  To: linux-arm-kernel

* Stephen Warren wrote:
> On 06/12/2012 11:20 AM, Thierry Reding wrote:
> ...
> > I came up with the following alternative:
> > 
> > 	pci {
> > 		compatible = "nvidia,tegra20-pcie";
> > 		reg = <0x80003000 0x00000800   /* PADS registers */
> > 		       0x80003800 0x00000200   /* AFI registers */
> > 		       0x80004000 0x00100000   /* configuration space */
> > 		       0x80104000 0x00100000   /* extended configuration space */
> > 		       0x80400000 0x00010000   /* downstream I/O */
> > 		       0x90000000 0x10000000   /* non-prefetchable memory */
> > 		       0xa0000000 0x10000000>; /* prefetchable memory */
> > 		interrupts = <0 98 0x04   /* controller interrupt */
> > 		              0 99 0x04>; /* MSI interrupt */
> > 		status = "disabled";
> > 
> > 		ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */
> > 			  0x80004000 0x80004000 0x00100000   /* configuration space */
> > 			  0x80104000 0x80104000 0x00100000   /* extended configuration space */
> > 			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
> > 			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
> > 			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
> > 
> > 		#address-cells = <1>;
> > 		#size-cells = <1>;
> > 
> > 		port at 80000000 {
> > 			reg = <0x80000000 0x00001000>;
> > 			status = "disabled";
> > 		};
> > 
> > 		port at 80001000 {
> > 			reg = <0x80001000 0x00001000>;
> > 			status = "disabled";
> > 		};
> > 	};
> > 
> > The "ranges" property can probably be cleaned up a bit, but the most
> > interesting part is the port@ children, which can simply be enabled in board
> > DTS files by setting the status property to "okay". I find that somewhat more
> > intuitive to the variant with an "enable-ports" property.
> > 
> > What do you think of this?
> 
> As a general concept, this kind of design seems OK to me.
> 
> The "port" child nodes I think should be named "pci at ..." given Mitch's
> comments, I think.
> 
> The port nodes probably need two entries in reg, given the following in
> our downstream driver:
> 
> >         int rp_offset = 0;
> >         int ctrl_offset = AFI_PEX0_CTRL;
> ...
> >         for (port = 0; port < MAX_PCIE_SUPPORTED_PORTS; port++) {
> >                 ctrl_offset += (port * 8);
> >                 rp_offset = (rp_offset + 0x1000) * port;
> >                 if (tegra_pcie.plat_data->port_status[port])
> >                         tegra_pcie_add_port(port, rp_offset, ctrl_offset);
> >         }
> 
> (which actually looks likely to be horribly buggy for port>1 and only
> accidentally correct for port==1, but anyway...)

Yeah, I currently have code that gets the port index and the reset register
offset (ctrl_offset above) from the port address. It feels rather hackish,
though.

> But instead, I'd be tempted to make the top-level node say:
> 
> 	#address-cells = <1>;
> 	#size-cells = <0>;
> 
> ... so that the child nodes' reg is just the port ID. The parent node
> can calculate the addresses/offsets of the per-port registers within the
> PCIe controller's register space based on the ID using code roughly like
> what I quoted above:
> 
> 	pci at 0 {
> 		reg = <0>;
> 		status = "disabled";
> 	};
> 
> 	pci at 1 {
> 		reg = <0>;
> 		status = "disabled";
> 	};
> 
> That would save having to put 2 entries in the reg, and perhaps remove
> the need for any ranges property.
> 
> I think you also need a property to specify the exact port layout; the
> Tegra20 controller supports:
> 
> 1 x4 port
> 2 x2 ports (you can choose to use only 1 of these I assume)
> 
> So just because only 1 of the ports is enabled, doesn't imply it's x4;
> it could still be x2.
> 
> Tegra30 has more options.

Both the upstream and downstream drivers currently hard-code this to dual and
411 (I assume that means 1x4, 2x1?) configurations for Tegra20 and Tegra30
respectively. Unfortunately the register AFI_PCIE_CONFIG isn't documented on
Tegra20 at all and for Tegra30 lists only the valid configurations (see
28.4.1.5 PCIe CONFIG) but not the corresponding encodings.

Maybe a good name for the new property would be "num-lanes". I also wonder if
this property would be better off in the parent node, which would make it
easier to check for valid configurations. Otherwise the code would have to
collect the settings of all the ports and check if the combination is valid.
Then again, having num-lanes in the parent with one cell for each controller
isn't very nice if each controller can be individually disabled.

One other thing: in addition to the device tree binding, this will all have to
be represented in the platform data as well to support the legacy board
definitions currently in the tree. But instead of adding all of these changes
to the patch that converts the code to a driver, I'm thinking it might be
better to split these additions off into one or more separate patches. Do you
have any objections?

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120613/aee9fdd4/attachment-0001.sig>

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-12 21:11                   ` Mitch Bradley
@ 2012-06-13  6:45                     ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-13  6:45 UTC (permalink / raw)
  To: Mitch Bradley
  Cc: Stephen Warren, Russell King, linux-pci, devicetree-discuss,
	Rob Herring, Jesse Barnes, Colin Cross, linux-tegra,
	linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 4234 bytes --]

* Mitch Bradley wrote:
> On 6/12/2012 10:15 AM, Stephen Warren wrote:
> >On 06/12/2012 11:20 AM, Thierry Reding wrote:
> >...
> >>I came up with the following alternative:
> >>
> >>	pci {
> >>		compatible = "nvidia,tegra20-pcie";
> >>		reg =<0x80003000 0x00000800   /* PADS registers */
> >>		       0x80003800 0x00000200   /* AFI registers */
> >>		       0x80004000 0x00100000   /* configuration space */
> >>		       0x80104000 0x00100000   /* extended configuration space */
> >>		       0x80400000 0x00010000   /* downstream I/O */
> >>		       0x90000000 0x10000000   /* non-prefetchable memory */
> >>		       0xa0000000 0x10000000>; /* prefetchable memory */
> >>		interrupts =<0 98 0x04   /* controller interrupt */
> >>		              0 99 0x04>; /* MSI interrupt */
> >>		status = "disabled";
> >>
> >>		ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
> >>			  0x80004000 0x80004000 0x00100000   /* configuration space */
> >>			  0x80104000 0x80104000 0x00100000   /* extended configuration space */
> >>			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
> >>			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
> >>			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
> >>
> >>		#address-cells =<1>;
> >>		#size-cells =<1>;
> >>
> >>		port@80000000 {
> >>			reg =<0x80000000 0x00001000>;
> >>			status = "disabled";
> >>		};
> >>
> >>		port@80001000 {
> >>			reg =<0x80001000 0x00001000>;
> >>			status = "disabled";
> >>		};
> >>	};
> >>
> >>The "ranges" property can probably be cleaned up a bit, but the most
> >>interesting part is the port@ children, which can simply be enabled in board
> >>DTS files by setting the status property to "okay". I find that somewhat more
> >>intuitive to the variant with an "enable-ports" property.
> >>
> >>What do you think of this?
> >
> >As a general concept, this kind of design seems OK to me.
> >
> >The "port" child nodes I think should be named "pci@..." given Mitch's
> >comments, I think.
> >
> >The port nodes probably need two entries in reg, given the following in
> >our downstream driver:
> >
> >>         int rp_offset = 0;
> >>         int ctrl_offset = AFI_PEX0_CTRL;
> >...
> >>         for (port = 0; port<  MAX_PCIE_SUPPORTED_PORTS; port++) {
> >>                 ctrl_offset += (port * 8);
> >>                 rp_offset = (rp_offset + 0x1000) * port;
> >>                 if (tegra_pcie.plat_data->port_status[port])
> >>                         tegra_pcie_add_port(port, rp_offset, ctrl_offset);
> >>         }
> >
> >(which actually looks likely to be horribly buggy for port>1 and only
> >accidentally correct for port==1, but anyway...)
> >
> >But instead, I'd be tempted to make the top-level node say:
> >
> >	#address-cells =<1>;
> >	#size-cells =<0>;
> >
> >... so that the child nodes' reg is just the port ID. The parent node
> >can calculate the addresses/offsets of the per-port registers within the
> >PCIe controller's register space based on the ID using code roughly like
> >what I quoted above:
> >
> >	pci@0 {
> >		reg =<0>;
> >		status = "disabled";
> >	};
> >
> >	pci@1 {
> >		reg =<0>;
> >		status = "disabled";
> >	};
> reg = <1> ?
> 
> >
> >
> >That would save having to put 2 entries in the reg, and perhaps remove
> >the need for any ranges property.
> 
> ISTM that having two reg entries, specifying the rp and ctrl
> registers, is preferable to having code to calculate the addresses.
> That makes the code simpler and the device tree more directly
> descriptive of the hardware layout.  The less "magic" (in this case,
> the register address calculation), the better.

The problem with this approach is that since the control registers are
within the AFI register range, both the reg and ranges properties of the
parent would have to include these holes. Furthermore it means that the
controller driver would have to remap the AFI registers in chunks, for the
sole reason of splitting out the controle registers.

Would it be acceptable to make an exception in this case and use the port's
second reg entry as an offset into the AFI register range instead?

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-13  6:45                     ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-13  6:45 UTC (permalink / raw)
  To: linux-arm-kernel

* Mitch Bradley wrote:
> On 6/12/2012 10:15 AM, Stephen Warren wrote:
> >On 06/12/2012 11:20 AM, Thierry Reding wrote:
> >...
> >>I came up with the following alternative:
> >>
> >>	pci {
> >>		compatible = "nvidia,tegra20-pcie";
> >>		reg =<0x80003000 0x00000800   /* PADS registers */
> >>		       0x80003800 0x00000200   /* AFI registers */
> >>		       0x80004000 0x00100000   /* configuration space */
> >>		       0x80104000 0x00100000   /* extended configuration space */
> >>		       0x80400000 0x00010000   /* downstream I/O */
> >>		       0x90000000 0x10000000   /* non-prefetchable memory */
> >>		       0xa0000000 0x10000000>; /* prefetchable memory */
> >>		interrupts =<0 98 0x04   /* controller interrupt */
> >>		              0 99 0x04>; /* MSI interrupt */
> >>		status = "disabled";
> >>
> >>		ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
> >>			  0x80004000 0x80004000 0x00100000   /* configuration space */
> >>			  0x80104000 0x80104000 0x00100000   /* extended configuration space */
> >>			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
> >>			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
> >>			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
> >>
> >>		#address-cells =<1>;
> >>		#size-cells =<1>;
> >>
> >>		port at 80000000 {
> >>			reg =<0x80000000 0x00001000>;
> >>			status = "disabled";
> >>		};
> >>
> >>		port at 80001000 {
> >>			reg =<0x80001000 0x00001000>;
> >>			status = "disabled";
> >>		};
> >>	};
> >>
> >>The "ranges" property can probably be cleaned up a bit, but the most
> >>interesting part is the port@ children, which can simply be enabled in board
> >>DTS files by setting the status property to "okay". I find that somewhat more
> >>intuitive to the variant with an "enable-ports" property.
> >>
> >>What do you think of this?
> >
> >As a general concept, this kind of design seems OK to me.
> >
> >The "port" child nodes I think should be named "pci at ..." given Mitch's
> >comments, I think.
> >
> >The port nodes probably need two entries in reg, given the following in
> >our downstream driver:
> >
> >>         int rp_offset = 0;
> >>         int ctrl_offset = AFI_PEX0_CTRL;
> >...
> >>         for (port = 0; port<  MAX_PCIE_SUPPORTED_PORTS; port++) {
> >>                 ctrl_offset += (port * 8);
> >>                 rp_offset = (rp_offset + 0x1000) * port;
> >>                 if (tegra_pcie.plat_data->port_status[port])
> >>                         tegra_pcie_add_port(port, rp_offset, ctrl_offset);
> >>         }
> >
> >(which actually looks likely to be horribly buggy for port>1 and only
> >accidentally correct for port==1, but anyway...)
> >
> >But instead, I'd be tempted to make the top-level node say:
> >
> >	#address-cells =<1>;
> >	#size-cells =<0>;
> >
> >... so that the child nodes' reg is just the port ID. The parent node
> >can calculate the addresses/offsets of the per-port registers within the
> >PCIe controller's register space based on the ID using code roughly like
> >what I quoted above:
> >
> >	pci at 0 {
> >		reg =<0>;
> >		status = "disabled";
> >	};
> >
> >	pci at 1 {
> >		reg =<0>;
> >		status = "disabled";
> >	};
> reg = <1> ?
> 
> >
> >
> >That would save having to put 2 entries in the reg, and perhaps remove
> >the need for any ranges property.
> 
> ISTM that having two reg entries, specifying the rp and ctrl
> registers, is preferable to having code to calculate the addresses.
> That makes the code simpler and the device tree more directly
> descriptive of the hardware layout.  The less "magic" (in this case,
> the register address calculation), the better.

The problem with this approach is that since the control registers are
within the AFI register range, both the reg and ranges properties of the
parent would have to include these holes. Furthermore it means that the
controller driver would have to remap the AFI registers in chunks, for the
sole reason of splitting out the controle registers.

Would it be acceptable to make an exception in this case and use the port's
second reg entry as an offset into the AFI register range instead?

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120613/5cf617b5/attachment.sig>

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-13  5:54                             ` Thierry Reding
@ 2012-06-13  7:04                               ` Mitch Bradley
  -1 siblings, 0 replies; 249+ messages in thread
From: Mitch Bradley @ 2012-06-13  7:04 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Stephen Warren, Russell King, linux-pci, devicetree-discuss,
	Rob Herring, Jesse Barnes, Colin Cross, linux-tegra,
	linux-arm-kernel

On 6/12/2012 7:54 PM, Thierry Reding wrote:
> * Mitch Bradley wrote:
>> On 6/12/2012 9:46 AM, Stephen Warren wrote:
>>> On 06/12/2012 01:10 PM, Mitch Bradley wrote:
>>>> On 6/12/2012 7:20 AM, Thierry Reding wrote:
>>> ...
>>>>> I came up with the following alternative:
>>>>>
>>>>> 	pci {
>>>>> 		compatible = "nvidia,tegra20-pcie";
>>>>> 		reg =<0x80003000 0x00000800   /* PADS registers */
>>>>> 		       0x80003800 0x00000200   /* AFI registers */
>>>>> 		       0x80004000 0x00100000   /* configuration space */
>>>>> 		       0x80104000 0x00100000   /* extended configuration space */
>>>>> 		       0x80400000 0x00010000   /* downstream I/O */
>>>>> 		       0x90000000 0x10000000   /* non-prefetchable memory */
>>>>> 		       0xa0000000 0x10000000>; /* prefetchable memory */
>>>>> 		interrupts =<0 98 0x04   /* controller interrupt */
>>>>> 		              0 99 0x04>; /* MSI interrupt */
>>>>> 		status = "disabled";
>>>>>
>>>>> 		ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
>>>>> 			  0x80004000 0x80004000 0x00100000   /* configuration space */
>>>>> 			  0x80104000 0x80104000 0x00100000   /* extended configuration space */
>>>>> 			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
>>>>> 			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
>>>>> 			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
>>>>>
>>>>> 		#address-cells =<1>;
>>>>> 		#size-cells =<1>;
>>>>>
>>>>> 		port@80000000 {
>>>>> 			reg =<0x80000000 0x00001000>;
>>>>> 			status = "disabled";
>>>>> 		};
>>>>>
>>>>> 		port@80001000 {
>>>>> 			reg =<0x80001000 0x00001000>;
>>>>> 			status = "disabled";
>>>>> 		};
>>>>> 	};
>>>>>
>>>>> The "ranges" property can probably be cleaned up a bit, but the most
>>>>> interesting part is the port@ children, which can simply be enabled in board
>>>>> DTS files by setting the status property to "okay". I find that somewhat more
>>>>> intuitive to the variant with an "enable-ports" property.
>>>>>
>>>>> What do you think of this?
>>>>
>>>> The problem is that children of a PCI-ish bus have specific expectations
>>>> about the parent address format - the standard 3-address-cell PCI
>>>> addressing.  So making a PCI bus node - even if it is PCIe - with 1
>>>> address cell is a problem.
>>>
>>> Couldn't you put the #address-cells=<3>   underneath each port node, and
>>> put any PCIe devices there rather than under the main PCIe controller
>>> node? I'm not sure how the interrupt mapping table etc. would work in
>>> that case, but that seems to solve the addressing issue.
>>
>> Yes, that would work just fine, and in fact would be preferable, if
>> a "root port" is essentially an independent PCI bus.  The parent of
>> those root ports should not be named "pci", though, as it is not in
>> itself a PCI bus.  It could be called "pcis".
>
> Yes, on Tegra each of the ports provides a separate PCI bus. How about naming
> the parent "pcie-controller"?

That seems like a fine name.

> IMO that reflects the nature of the device
> better, whereas "pcis" would seem more like a "virtual" node for collecting
> similar children.
>
> Thierry

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-13  7:04                               ` Mitch Bradley
  0 siblings, 0 replies; 249+ messages in thread
From: Mitch Bradley @ 2012-06-13  7:04 UTC (permalink / raw)
  To: linux-arm-kernel

On 6/12/2012 7:54 PM, Thierry Reding wrote:
> * Mitch Bradley wrote:
>> On 6/12/2012 9:46 AM, Stephen Warren wrote:
>>> On 06/12/2012 01:10 PM, Mitch Bradley wrote:
>>>> On 6/12/2012 7:20 AM, Thierry Reding wrote:
>>> ...
>>>>> I came up with the following alternative:
>>>>>
>>>>> 	pci {
>>>>> 		compatible = "nvidia,tegra20-pcie";
>>>>> 		reg =<0x80003000 0x00000800   /* PADS registers */
>>>>> 		       0x80003800 0x00000200   /* AFI registers */
>>>>> 		       0x80004000 0x00100000   /* configuration space */
>>>>> 		       0x80104000 0x00100000   /* extended configuration space */
>>>>> 		       0x80400000 0x00010000   /* downstream I/O */
>>>>> 		       0x90000000 0x10000000   /* non-prefetchable memory */
>>>>> 		       0xa0000000 0x10000000>; /* prefetchable memory */
>>>>> 		interrupts =<0 98 0x04   /* controller interrupt */
>>>>> 		              0 99 0x04>; /* MSI interrupt */
>>>>> 		status = "disabled";
>>>>>
>>>>> 		ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
>>>>> 			  0x80004000 0x80004000 0x00100000   /* configuration space */
>>>>> 			  0x80104000 0x80104000 0x00100000   /* extended configuration space */
>>>>> 			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
>>>>> 			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
>>>>> 			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
>>>>>
>>>>> 		#address-cells =<1>;
>>>>> 		#size-cells =<1>;
>>>>>
>>>>> 		port at 80000000 {
>>>>> 			reg =<0x80000000 0x00001000>;
>>>>> 			status = "disabled";
>>>>> 		};
>>>>>
>>>>> 		port at 80001000 {
>>>>> 			reg =<0x80001000 0x00001000>;
>>>>> 			status = "disabled";
>>>>> 		};
>>>>> 	};
>>>>>
>>>>> The "ranges" property can probably be cleaned up a bit, but the most
>>>>> interesting part is the port@ children, which can simply be enabled in board
>>>>> DTS files by setting the status property to "okay". I find that somewhat more
>>>>> intuitive to the variant with an "enable-ports" property.
>>>>>
>>>>> What do you think of this?
>>>>
>>>> The problem is that children of a PCI-ish bus have specific expectations
>>>> about the parent address format - the standard 3-address-cell PCI
>>>> addressing.  So making a PCI bus node - even if it is PCIe - with 1
>>>> address cell is a problem.
>>>
>>> Couldn't you put the #address-cells=<3>   underneath each port node, and
>>> put any PCIe devices there rather than under the main PCIe controller
>>> node? I'm not sure how the interrupt mapping table etc. would work in
>>> that case, but that seems to solve the addressing issue.
>>
>> Yes, that would work just fine, and in fact would be preferable, if
>> a "root port" is essentially an independent PCI bus.  The parent of
>> those root ports should not be named "pci", though, as it is not in
>> itself a PCI bus.  It could be called "pcis".
>
> Yes, on Tegra each of the ports provides a separate PCI bus. How about naming
> the parent "pcie-controller"?

That seems like a fine name.

> IMO that reflects the nature of the device
> better, whereas "pcis" would seem more like a "virtual" node for collecting
> similar children.
>
> Thierry

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-13  6:45                     ` Thierry Reding
  (?)
@ 2012-06-13  7:28                         ` Mitch Bradley
  -1 siblings, 0 replies; 249+ messages in thread
From: Mitch Bradley @ 2012-06-13  7:28 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Russell King, linux-pci-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Jesse Barnes,
	Rob Herring, Colin Cross, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On 6/12/2012 8:45 PM, Thierry Reding wrote:
> * Mitch Bradley wrote:
>> On 6/12/2012 10:15 AM, Stephen Warren wrote:
>>> On 06/12/2012 11:20 AM, Thierry Reding wrote:
>>> ...
>>>> I came up with the following alternative:
>>>>
>>>> 	pci {
>>>> 		compatible = "nvidia,tegra20-pcie";
>>>> 		reg =<0x80003000 0x00000800   /* PADS registers */
>>>> 		       0x80003800 0x00000200   /* AFI registers */
>>>> 		       0x80004000 0x00100000   /* configuration space */
>>>> 		       0x80104000 0x00100000   /* extended configuration space */
>>>> 		       0x80400000 0x00010000   /* downstream I/O */
>>>> 		       0x90000000 0x10000000   /* non-prefetchable memory */
>>>> 		       0xa0000000 0x10000000>; /* prefetchable memory */
>>>> 		interrupts =<0 98 0x04   /* controller interrupt */
>>>> 		              0 99 0x04>; /* MSI interrupt */
>>>> 		status = "disabled";
>>>>
>>>> 		ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
>>>> 			  0x80004000 0x80004000 0x00100000   /* configuration space */
>>>> 			  0x80104000 0x80104000 0x00100000   /* extended configuration space */
>>>> 			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
>>>> 			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
>>>> 			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
>>>>
>>>> 		#address-cells =<1>;
>>>> 		#size-cells =<1>;
>>>>
>>>> 		port@80000000 {
>>>> 			reg =<0x80000000 0x00001000>;
>>>> 			status = "disabled";
>>>> 		};
>>>>
>>>> 		port@80001000 {
>>>> 			reg =<0x80001000 0x00001000>;
>>>> 			status = "disabled";
>>>> 		};
>>>> 	};
>>>>
>>>> The "ranges" property can probably be cleaned up a bit, but the most
>>>> interesting part is the port@ children, which can simply be enabled in board
>>>> DTS files by setting the status property to "okay". I find that somewhat more
>>>> intuitive to the variant with an "enable-ports" property.
>>>>
>>>> What do you think of this?
>>>
>>> As a general concept, this kind of design seems OK to me.
>>>
>>> The "port" child nodes I think should be named "pci@..." given Mitch's
>>> comments, I think.
>>>
>>> The port nodes probably need two entries in reg, given the following in
>>> our downstream driver:
>>>
>>>>          int rp_offset = 0;
>>>>          int ctrl_offset = AFI_PEX0_CTRL;
>>> ...
>>>>          for (port = 0; port<   MAX_PCIE_SUPPORTED_PORTS; port++) {
>>>>                  ctrl_offset += (port * 8);
>>>>                  rp_offset = (rp_offset + 0x1000) * port;
>>>>                  if (tegra_pcie.plat_data->port_status[port])
>>>>                          tegra_pcie_add_port(port, rp_offset, ctrl_offset);
>>>>          }
>>>
>>> (which actually looks likely to be horribly buggy for port>1 and only
>>> accidentally correct for port==1, but anyway...)
>>>
>>> But instead, I'd be tempted to make the top-level node say:
>>>
>>> 	#address-cells =<1>;
>>> 	#size-cells =<0>;
>>>
>>> ... so that the child nodes' reg is just the port ID. The parent node
>>> can calculate the addresses/offsets of the per-port registers within the
>>> PCIe controller's register space based on the ID using code roughly like
>>> what I quoted above:
>>>
>>> 	pci@0 {
>>> 		reg =<0>;
>>> 		status = "disabled";
>>> 	};
>>>
>>> 	pci@1 {
>>> 		reg =<0>;
>>> 		status = "disabled";
>>> 	};
>> reg =<1>  ?
>>
>>>
>>>
>>> That would save having to put 2 entries in the reg, and perhaps remove
>>> the need for any ranges property.
>>
>> ISTM that having two reg entries, specifying the rp and ctrl
>> registers, is preferable to having code to calculate the addresses.
>> That makes the code simpler and the device tree more directly
>> descriptive of the hardware layout.  The less "magic" (in this case,
>> the register address calculation), the better.
>
> The problem with this approach is that since the control registers are
> within the AFI register range, both the reg and ranges properties of the
> parent would have to include these holes. Furthermore it means that the
> controller driver would have to remap the AFI registers in chunks, for the
> sole reason of splitting out the controle registers.
>
> Would it be acceptable to make an exception in this case and use the port's
> second reg entry as an offset into the AFI register range instead?

How about this:

     pcie-controller {
         compatible = "nvidia,tegra20-pcie";
         reg =<0x80003000 0x00000800   /* PADS registers */
               0x80003800 0x00000200>   /* AFI registers */
         interrupts =<0 98 0x04   /* controller interrupt */
                      0 99 0x04>; /* MSI interrupt */
         status = "disabled";

         ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
               0x80004000 0x80004000 0x00100000   /* configuration space */
               0x80104000 0x80104000 0x00100000   /* extended 
configuration space */
               0x80400000 0x80400000 0x00010000   /* downstream I/O */
               0x90000000 0x90000000 0x10000000   /* non-prefetchable 
memory */
               0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */

         #address-cells =<1>;
         #size-cells =<1>;

         pci@80000000 {
             reg =<0x80000000 0x00001000>;
             ctrl-offset =<0x0>;
             status = "disabled";
             #address-cells = <3>;  /* Standard for PCI */
             #size-cells =<2>;      /* Standard for PCI */
             ranges =</* Map from standard PCI child address spaces to 
linear spaces above */>;
         };

         pci@80001000 {
             reg =<0x80001000 0x00001000>;
             ctrl-offset =<0x8>;
             status = "disabled";
             #address-cells = <3>;  /* Standard for PCI */
             #size-cells =<2>;      /* Standard for PCI */
             ranges =</* Map from standard PCI child address spaces to 
linear spaces above */>;
         };
     };

Using ctrl-offset instead of reg avoids any violation of the usual reg 
semantics.

Note that the pci subnodes need the full complement of PCI bus node 
properties.

>
>
> Thierry

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-13  7:28                         ` Mitch Bradley
  0 siblings, 0 replies; 249+ messages in thread
From: Mitch Bradley @ 2012-06-13  7:28 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Stephen Warren, Russell King, linux-pci, devicetree-discuss,
	Rob Herring, Jesse Barnes, Colin Cross, linux-tegra,
	linux-arm-kernel

On 6/12/2012 8:45 PM, Thierry Reding wrote:
> * Mitch Bradley wrote:
>> On 6/12/2012 10:15 AM, Stephen Warren wrote:
>>> On 06/12/2012 11:20 AM, Thierry Reding wrote:
>>> ...
>>>> I came up with the following alternative:
>>>>
>>>> 	pci {
>>>> 		compatible = "nvidia,tegra20-pcie";
>>>> 		reg =<0x80003000 0x00000800   /* PADS registers */
>>>> 		       0x80003800 0x00000200   /* AFI registers */
>>>> 		       0x80004000 0x00100000   /* configuration space */
>>>> 		       0x80104000 0x00100000   /* extended configuration space */
>>>> 		       0x80400000 0x00010000   /* downstream I/O */
>>>> 		       0x90000000 0x10000000   /* non-prefetchable memory */
>>>> 		       0xa0000000 0x10000000>; /* prefetchable memory */
>>>> 		interrupts =<0 98 0x04   /* controller interrupt */
>>>> 		              0 99 0x04>; /* MSI interrupt */
>>>> 		status = "disabled";
>>>>
>>>> 		ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
>>>> 			  0x80004000 0x80004000 0x00100000   /* configuration space */
>>>> 			  0x80104000 0x80104000 0x00100000   /* extended configuration space */
>>>> 			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
>>>> 			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
>>>> 			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
>>>>
>>>> 		#address-cells =<1>;
>>>> 		#size-cells =<1>;
>>>>
>>>> 		port@80000000 {
>>>> 			reg =<0x80000000 0x00001000>;
>>>> 			status = "disabled";
>>>> 		};
>>>>
>>>> 		port@80001000 {
>>>> 			reg =<0x80001000 0x00001000>;
>>>> 			status = "disabled";
>>>> 		};
>>>> 	};
>>>>
>>>> The "ranges" property can probably be cleaned up a bit, but the most
>>>> interesting part is the port@ children, which can simply be enabled in board
>>>> DTS files by setting the status property to "okay". I find that somewhat more
>>>> intuitive to the variant with an "enable-ports" property.
>>>>
>>>> What do you think of this?
>>>
>>> As a general concept, this kind of design seems OK to me.
>>>
>>> The "port" child nodes I think should be named "pci@..." given Mitch's
>>> comments, I think.
>>>
>>> The port nodes probably need two entries in reg, given the following in
>>> our downstream driver:
>>>
>>>>          int rp_offset = 0;
>>>>          int ctrl_offset = AFI_PEX0_CTRL;
>>> ...
>>>>          for (port = 0; port<   MAX_PCIE_SUPPORTED_PORTS; port++) {
>>>>                  ctrl_offset += (port * 8);
>>>>                  rp_offset = (rp_offset + 0x1000) * port;
>>>>                  if (tegra_pcie.plat_data->port_status[port])
>>>>                          tegra_pcie_add_port(port, rp_offset, ctrl_offset);
>>>>          }
>>>
>>> (which actually looks likely to be horribly buggy for port>1 and only
>>> accidentally correct for port==1, but anyway...)
>>>
>>> But instead, I'd be tempted to make the top-level node say:
>>>
>>> 	#address-cells =<1>;
>>> 	#size-cells =<0>;
>>>
>>> ... so that the child nodes' reg is just the port ID. The parent node
>>> can calculate the addresses/offsets of the per-port registers within the
>>> PCIe controller's register space based on the ID using code roughly like
>>> what I quoted above:
>>>
>>> 	pci@0 {
>>> 		reg =<0>;
>>> 		status = "disabled";
>>> 	};
>>>
>>> 	pci@1 {
>>> 		reg =<0>;
>>> 		status = "disabled";
>>> 	};
>> reg =<1>  ?
>>
>>>
>>>
>>> That would save having to put 2 entries in the reg, and perhaps remove
>>> the need for any ranges property.
>>
>> ISTM that having two reg entries, specifying the rp and ctrl
>> registers, is preferable to having code to calculate the addresses.
>> That makes the code simpler and the device tree more directly
>> descriptive of the hardware layout.  The less "magic" (in this case,
>> the register address calculation), the better.
>
> The problem with this approach is that since the control registers are
> within the AFI register range, both the reg and ranges properties of the
> parent would have to include these holes. Furthermore it means that the
> controller driver would have to remap the AFI registers in chunks, for the
> sole reason of splitting out the controle registers.
>
> Would it be acceptable to make an exception in this case and use the port's
> second reg entry as an offset into the AFI register range instead?

How about this:

     pcie-controller {
         compatible = "nvidia,tegra20-pcie";
         reg =<0x80003000 0x00000800   /* PADS registers */
               0x80003800 0x00000200>   /* AFI registers */
         interrupts =<0 98 0x04   /* controller interrupt */
                      0 99 0x04>; /* MSI interrupt */
         status = "disabled";

         ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
               0x80004000 0x80004000 0x00100000   /* configuration space */
               0x80104000 0x80104000 0x00100000   /* extended 
configuration space */
               0x80400000 0x80400000 0x00010000   /* downstream I/O */
               0x90000000 0x90000000 0x10000000   /* non-prefetchable 
memory */
               0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */

         #address-cells =<1>;
         #size-cells =<1>;

         pci@80000000 {
             reg =<0x80000000 0x00001000>;
             ctrl-offset =<0x0>;
             status = "disabled";
             #address-cells = <3>;  /* Standard for PCI */
             #size-cells =<2>;      /* Standard for PCI */
             ranges =</* Map from standard PCI child address spaces to 
linear spaces above */>;
         };

         pci@80001000 {
             reg =<0x80001000 0x00001000>;
             ctrl-offset =<0x8>;
             status = "disabled";
             #address-cells = <3>;  /* Standard for PCI */
             #size-cells =<2>;      /* Standard for PCI */
             ranges =</* Map from standard PCI child address spaces to 
linear spaces above */>;
         };
     };

Using ctrl-offset instead of reg avoids any violation of the usual reg 
semantics.

Note that the pci subnodes need the full complement of PCI bus node 
properties.

>
>
> Thierry

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-13  7:28                         ` Mitch Bradley
  0 siblings, 0 replies; 249+ messages in thread
From: Mitch Bradley @ 2012-06-13  7:28 UTC (permalink / raw)
  To: linux-arm-kernel

On 6/12/2012 8:45 PM, Thierry Reding wrote:
> * Mitch Bradley wrote:
>> On 6/12/2012 10:15 AM, Stephen Warren wrote:
>>> On 06/12/2012 11:20 AM, Thierry Reding wrote:
>>> ...
>>>> I came up with the following alternative:
>>>>
>>>> 	pci {
>>>> 		compatible = "nvidia,tegra20-pcie";
>>>> 		reg =<0x80003000 0x00000800   /* PADS registers */
>>>> 		       0x80003800 0x00000200   /* AFI registers */
>>>> 		       0x80004000 0x00100000   /* configuration space */
>>>> 		       0x80104000 0x00100000   /* extended configuration space */
>>>> 		       0x80400000 0x00010000   /* downstream I/O */
>>>> 		       0x90000000 0x10000000   /* non-prefetchable memory */
>>>> 		       0xa0000000 0x10000000>; /* prefetchable memory */
>>>> 		interrupts =<0 98 0x04   /* controller interrupt */
>>>> 		              0 99 0x04>; /* MSI interrupt */
>>>> 		status = "disabled";
>>>>
>>>> 		ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
>>>> 			  0x80004000 0x80004000 0x00100000   /* configuration space */
>>>> 			  0x80104000 0x80104000 0x00100000   /* extended configuration space */
>>>> 			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
>>>> 			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
>>>> 			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
>>>>
>>>> 		#address-cells =<1>;
>>>> 		#size-cells =<1>;
>>>>
>>>> 		port at 80000000 {
>>>> 			reg =<0x80000000 0x00001000>;
>>>> 			status = "disabled";
>>>> 		};
>>>>
>>>> 		port at 80001000 {
>>>> 			reg =<0x80001000 0x00001000>;
>>>> 			status = "disabled";
>>>> 		};
>>>> 	};
>>>>
>>>> The "ranges" property can probably be cleaned up a bit, but the most
>>>> interesting part is the port@ children, which can simply be enabled in board
>>>> DTS files by setting the status property to "okay". I find that somewhat more
>>>> intuitive to the variant with an "enable-ports" property.
>>>>
>>>> What do you think of this?
>>>
>>> As a general concept, this kind of design seems OK to me.
>>>
>>> The "port" child nodes I think should be named "pci at ..." given Mitch's
>>> comments, I think.
>>>
>>> The port nodes probably need two entries in reg, given the following in
>>> our downstream driver:
>>>
>>>>          int rp_offset = 0;
>>>>          int ctrl_offset = AFI_PEX0_CTRL;
>>> ...
>>>>          for (port = 0; port<   MAX_PCIE_SUPPORTED_PORTS; port++) {
>>>>                  ctrl_offset += (port * 8);
>>>>                  rp_offset = (rp_offset + 0x1000) * port;
>>>>                  if (tegra_pcie.plat_data->port_status[port])
>>>>                          tegra_pcie_add_port(port, rp_offset, ctrl_offset);
>>>>          }
>>>
>>> (which actually looks likely to be horribly buggy for port>1 and only
>>> accidentally correct for port==1, but anyway...)
>>>
>>> But instead, I'd be tempted to make the top-level node say:
>>>
>>> 	#address-cells =<1>;
>>> 	#size-cells =<0>;
>>>
>>> ... so that the child nodes' reg is just the port ID. The parent node
>>> can calculate the addresses/offsets of the per-port registers within the
>>> PCIe controller's register space based on the ID using code roughly like
>>> what I quoted above:
>>>
>>> 	pci at 0 {
>>> 		reg =<0>;
>>> 		status = "disabled";
>>> 	};
>>>
>>> 	pci at 1 {
>>> 		reg =<0>;
>>> 		status = "disabled";
>>> 	};
>> reg =<1>  ?
>>
>>>
>>>
>>> That would save having to put 2 entries in the reg, and perhaps remove
>>> the need for any ranges property.
>>
>> ISTM that having two reg entries, specifying the rp and ctrl
>> registers, is preferable to having code to calculate the addresses.
>> That makes the code simpler and the device tree more directly
>> descriptive of the hardware layout.  The less "magic" (in this case,
>> the register address calculation), the better.
>
> The problem with this approach is that since the control registers are
> within the AFI register range, both the reg and ranges properties of the
> parent would have to include these holes. Furthermore it means that the
> controller driver would have to remap the AFI registers in chunks, for the
> sole reason of splitting out the controle registers.
>
> Would it be acceptable to make an exception in this case and use the port's
> second reg entry as an offset into the AFI register range instead?

How about this:

     pcie-controller {
         compatible = "nvidia,tegra20-pcie";
         reg =<0x80003000 0x00000800   /* PADS registers */
               0x80003800 0x00000200>   /* AFI registers */
         interrupts =<0 98 0x04   /* controller interrupt */
                      0 99 0x04>; /* MSI interrupt */
         status = "disabled";

         ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
               0x80004000 0x80004000 0x00100000   /* configuration space */
               0x80104000 0x80104000 0x00100000   /* extended 
configuration space */
               0x80400000 0x80400000 0x00010000   /* downstream I/O */
               0x90000000 0x90000000 0x10000000   /* non-prefetchable 
memory */
               0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */

         #address-cells =<1>;
         #size-cells =<1>;

         pci at 80000000 {
             reg =<0x80000000 0x00001000>;
             ctrl-offset =<0x0>;
             status = "disabled";
             #address-cells = <3>;  /* Standard for PCI */
             #size-cells =<2>;      /* Standard for PCI */
             ranges =</* Map from standard PCI child address spaces to 
linear spaces above */>;
         };

         pci at 80001000 {
             reg =<0x80001000 0x00001000>;
             ctrl-offset =<0x8>;
             status = "disabled";
             #address-cells = <3>;  /* Standard for PCI */
             #size-cells =<2>;      /* Standard for PCI */
             ranges =</* Map from standard PCI child address spaces to 
linear spaces above */>;
         };
     };

Using ctrl-offset instead of reg avoids any violation of the usual reg 
semantics.

Note that the pci subnodes need the full complement of PCI bus node 
properties.

>
>
> Thierry

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-13  7:28                         ` Mitch Bradley
  (?)
@ 2012-06-13  7:52                             ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-13  7:52 UTC (permalink / raw)
  To: Mitch Bradley
  Cc: Stephen Warren, Russell King, linux-pci-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Jesse Barnes, Colin Cross, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

[-- Attachment #1: Type: text/plain, Size: 8915 bytes --]

On Tue, Jun 12, 2012 at 09:28:51PM -1000, Mitch Bradley wrote:
> On 6/12/2012 8:45 PM, Thierry Reding wrote:
> >* Mitch Bradley wrote:
> >>On 6/12/2012 10:15 AM, Stephen Warren wrote:
> >>>On 06/12/2012 11:20 AM, Thierry Reding wrote:
> >>>...
> >>>>I came up with the following alternative:
> >>>>
> >>>>	pci {
> >>>>		compatible = "nvidia,tegra20-pcie";
> >>>>		reg =<0x80003000 0x00000800   /* PADS registers */
> >>>>		       0x80003800 0x00000200   /* AFI registers */
> >>>>		       0x80004000 0x00100000   /* configuration space */
> >>>>		       0x80104000 0x00100000   /* extended configuration space */
> >>>>		       0x80400000 0x00010000   /* downstream I/O */
> >>>>		       0x90000000 0x10000000   /* non-prefetchable memory */
> >>>>		       0xa0000000 0x10000000>; /* prefetchable memory */
> >>>>		interrupts =<0 98 0x04   /* controller interrupt */
> >>>>		              0 99 0x04>; /* MSI interrupt */
> >>>>		status = "disabled";
> >>>>
> >>>>		ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
> >>>>			  0x80004000 0x80004000 0x00100000   /* configuration space */
> >>>>			  0x80104000 0x80104000 0x00100000   /* extended configuration space */
> >>>>			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
> >>>>			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
> >>>>			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
> >>>>
> >>>>		#address-cells =<1>;
> >>>>		#size-cells =<1>;
> >>>>
> >>>>		port@80000000 {
> >>>>			reg =<0x80000000 0x00001000>;
> >>>>			status = "disabled";
> >>>>		};
> >>>>
> >>>>		port@80001000 {
> >>>>			reg =<0x80001000 0x00001000>;
> >>>>			status = "disabled";
> >>>>		};
> >>>>	};
> >>>>
> >>>>The "ranges" property can probably be cleaned up a bit, but the most
> >>>>interesting part is the port@ children, which can simply be enabled in board
> >>>>DTS files by setting the status property to "okay". I find that somewhat more
> >>>>intuitive to the variant with an "enable-ports" property.
> >>>>
> >>>>What do you think of this?
> >>>
> >>>As a general concept, this kind of design seems OK to me.
> >>>
> >>>The "port" child nodes I think should be named "pci@..." given Mitch's
> >>>comments, I think.
> >>>
> >>>The port nodes probably need two entries in reg, given the following in
> >>>our downstream driver:
> >>>
> >>>>         int rp_offset = 0;
> >>>>         int ctrl_offset = AFI_PEX0_CTRL;
> >>>...
> >>>>         for (port = 0; port<   MAX_PCIE_SUPPORTED_PORTS; port++) {
> >>>>                 ctrl_offset += (port * 8);
> >>>>                 rp_offset = (rp_offset + 0x1000) * port;
> >>>>                 if (tegra_pcie.plat_data->port_status[port])
> >>>>                         tegra_pcie_add_port(port, rp_offset, ctrl_offset);
> >>>>         }
> >>>
> >>>(which actually looks likely to be horribly buggy for port>1 and only
> >>>accidentally correct for port==1, but anyway...)
> >>>
> >>>But instead, I'd be tempted to make the top-level node say:
> >>>
> >>>	#address-cells =<1>;
> >>>	#size-cells =<0>;
> >>>
> >>>... so that the child nodes' reg is just the port ID. The parent node
> >>>can calculate the addresses/offsets of the per-port registers within the
> >>>PCIe controller's register space based on the ID using code roughly like
> >>>what I quoted above:
> >>>
> >>>	pci@0 {
> >>>		reg =<0>;
> >>>		status = "disabled";
> >>>	};
> >>>
> >>>	pci@1 {
> >>>		reg =<0>;
> >>>		status = "disabled";
> >>>	};
> >>reg =<1>  ?
> >>
> >>>
> >>>
> >>>That would save having to put 2 entries in the reg, and perhaps remove
> >>>the need for any ranges property.
> >>
> >>ISTM that having two reg entries, specifying the rp and ctrl
> >>registers, is preferable to having code to calculate the addresses.
> >>That makes the code simpler and the device tree more directly
> >>descriptive of the hardware layout.  The less "magic" (in this case,
> >>the register address calculation), the better.
> >
> >The problem with this approach is that since the control registers are
> >within the AFI register range, both the reg and ranges properties of the
> >parent would have to include these holes. Furthermore it means that the
> >controller driver would have to remap the AFI registers in chunks, for the
> >sole reason of splitting out the controle registers.
> >
> >Would it be acceptable to make an exception in this case and use the port's
> >second reg entry as an offset into the AFI register range instead?
> 
> How about this:
> 
>     pcie-controller {
>         compatible = "nvidia,tegra20-pcie";
>         reg =<0x80003000 0x00000800   /* PADS registers */
>               0x80003800 0x00000200>   /* AFI registers */
>         interrupts =<0 98 0x04   /* controller interrupt */
>                      0 99 0x04>; /* MSI interrupt */
>         status = "disabled";
> 
>         ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
>               0x80004000 0x80004000 0x00100000   /* configuration space */
>               0x80104000 0x80104000 0x00100000   /* extended
> configuration space */
>               0x80400000 0x80400000 0x00010000   /* downstream I/O */
>               0x90000000 0x90000000 0x10000000   /* non-prefetchable
> memory */
>               0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */

I think the configuration spaces and downstream I/O ranges need to be in the
pcie-controller's reg property because they are remapped and used by the
controller driver, not by the individual ports.

That's probably not really necessary but rather a result of how the driver
was written. Perhaps the driver should handle them differently instead,
listing the regions in the ranges property of the parent and listing the
corresponding partitions in the ranges properties of the pci child nodes.

Like in the following, where the ranges property of the ports partition the
ranges passed from the parent evenly:

	pcie-controller {
		compatible = "nvidia,tegra20-pcie";
		reg = <0x80003000 0x00000800   /* PADS registers */
		       0x80003800 0x00000200>; /* AFI registers */
		interrupts = <0 98 0x04   /* controller interrupt */
			      0 99 0x04>; /* MSI interrupt */
		status = "disabled";

		ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */
			  0x80004000 0x80004000 0x00100000   /* configuration space */
			  0x80104000 0x80100000 0x00100000   /* extended configuration space */
			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */

		#address-cells = <1>;
		#size-cells = <1>;

		pci@80000000 {
			reg = <0x80000000 0x00001000>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;

			ranges = <0x80400000 0x80400000 0x00008000   /* I/O */
				  0x90000000 0x90000000 0x08000000   /* non-prefetchable memory */
				  0xa0000000 0xa0000000 0x08000000>; /* prefetchable memory */

			nvidia,ctrl-offset = <0x0>;
			nvidia,num-lanes = <2>;
		};

		pci@80001000 {
			reg = <0x80001000 0x00001000>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;

			ranges = <0x80408000 0x80408000 0x00008000   /* I/O */
				  0x98000000 0x98000000 0x08000000   /* non-prefetchable memory */
				  0xa8000000 0xa8000000 0x08000000>; /* prefetchable memory */

			nvidia,ctrl-offset = <0x8>;
			nvidia,num-lanes = <2>;
		};
	};

I've also added the new num-lanes property that describes the physical
connections of the port. Also the ctrl-offset and num-lanes property are
pretty specific to the Tegra PCIe controller, so I've prefixed them with
"nvidia,".

> 
>         #address-cells =<1>;
>         #size-cells =<1>;
> 
>         pci@80000000 {
>             reg =<0x80000000 0x00001000>;
>             ctrl-offset =<0x0>;
>             status = "disabled";
>             #address-cells = <3>;  /* Standard for PCI */
>             #size-cells =<2>;      /* Standard for PCI */
>             ranges =</* Map from standard PCI child address spaces
> to linear spaces above */>;
>         };
> 
>         pci@80001000 {
>             reg =<0x80001000 0x00001000>;
>             ctrl-offset =<0x8>;
>             status = "disabled";
>             #address-cells = <3>;  /* Standard for PCI */
>             #size-cells =<2>;      /* Standard for PCI */
>             ranges =</* Map from standard PCI child address spaces
> to linear spaces above */>;
>         };
>     };
> 
> Using ctrl-offset instead of reg avoids any violation of the usual
> reg semantics.

Yes, that sounds better.

> 
> Note that the pci subnodes need the full complement of PCI bus node
> properties.
> 
> >
> >
> >Thierry
> 

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-13  7:52                             ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-13  7:52 UTC (permalink / raw)
  To: Mitch Bradley
  Cc: Stephen Warren, Russell King, linux-pci, devicetree-discuss,
	Rob Herring, Jesse Barnes, Colin Cross, linux-tegra,
	linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 8915 bytes --]

On Tue, Jun 12, 2012 at 09:28:51PM -1000, Mitch Bradley wrote:
> On 6/12/2012 8:45 PM, Thierry Reding wrote:
> >* Mitch Bradley wrote:
> >>On 6/12/2012 10:15 AM, Stephen Warren wrote:
> >>>On 06/12/2012 11:20 AM, Thierry Reding wrote:
> >>>...
> >>>>I came up with the following alternative:
> >>>>
> >>>>	pci {
> >>>>		compatible = "nvidia,tegra20-pcie";
> >>>>		reg =<0x80003000 0x00000800   /* PADS registers */
> >>>>		       0x80003800 0x00000200   /* AFI registers */
> >>>>		       0x80004000 0x00100000   /* configuration space */
> >>>>		       0x80104000 0x00100000   /* extended configuration space */
> >>>>		       0x80400000 0x00010000   /* downstream I/O */
> >>>>		       0x90000000 0x10000000   /* non-prefetchable memory */
> >>>>		       0xa0000000 0x10000000>; /* prefetchable memory */
> >>>>		interrupts =<0 98 0x04   /* controller interrupt */
> >>>>		              0 99 0x04>; /* MSI interrupt */
> >>>>		status = "disabled";
> >>>>
> >>>>		ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
> >>>>			  0x80004000 0x80004000 0x00100000   /* configuration space */
> >>>>			  0x80104000 0x80104000 0x00100000   /* extended configuration space */
> >>>>			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
> >>>>			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
> >>>>			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
> >>>>
> >>>>		#address-cells =<1>;
> >>>>		#size-cells =<1>;
> >>>>
> >>>>		port@80000000 {
> >>>>			reg =<0x80000000 0x00001000>;
> >>>>			status = "disabled";
> >>>>		};
> >>>>
> >>>>		port@80001000 {
> >>>>			reg =<0x80001000 0x00001000>;
> >>>>			status = "disabled";
> >>>>		};
> >>>>	};
> >>>>
> >>>>The "ranges" property can probably be cleaned up a bit, but the most
> >>>>interesting part is the port@ children, which can simply be enabled in board
> >>>>DTS files by setting the status property to "okay". I find that somewhat more
> >>>>intuitive to the variant with an "enable-ports" property.
> >>>>
> >>>>What do you think of this?
> >>>
> >>>As a general concept, this kind of design seems OK to me.
> >>>
> >>>The "port" child nodes I think should be named "pci@..." given Mitch's
> >>>comments, I think.
> >>>
> >>>The port nodes probably need two entries in reg, given the following in
> >>>our downstream driver:
> >>>
> >>>>         int rp_offset = 0;
> >>>>         int ctrl_offset = AFI_PEX0_CTRL;
> >>>...
> >>>>         for (port = 0; port<   MAX_PCIE_SUPPORTED_PORTS; port++) {
> >>>>                 ctrl_offset += (port * 8);
> >>>>                 rp_offset = (rp_offset + 0x1000) * port;
> >>>>                 if (tegra_pcie.plat_data->port_status[port])
> >>>>                         tegra_pcie_add_port(port, rp_offset, ctrl_offset);
> >>>>         }
> >>>
> >>>(which actually looks likely to be horribly buggy for port>1 and only
> >>>accidentally correct for port==1, but anyway...)
> >>>
> >>>But instead, I'd be tempted to make the top-level node say:
> >>>
> >>>	#address-cells =<1>;
> >>>	#size-cells =<0>;
> >>>
> >>>... so that the child nodes' reg is just the port ID. The parent node
> >>>can calculate the addresses/offsets of the per-port registers within the
> >>>PCIe controller's register space based on the ID using code roughly like
> >>>what I quoted above:
> >>>
> >>>	pci@0 {
> >>>		reg =<0>;
> >>>		status = "disabled";
> >>>	};
> >>>
> >>>	pci@1 {
> >>>		reg =<0>;
> >>>		status = "disabled";
> >>>	};
> >>reg =<1>  ?
> >>
> >>>
> >>>
> >>>That would save having to put 2 entries in the reg, and perhaps remove
> >>>the need for any ranges property.
> >>
> >>ISTM that having two reg entries, specifying the rp and ctrl
> >>registers, is preferable to having code to calculate the addresses.
> >>That makes the code simpler and the device tree more directly
> >>descriptive of the hardware layout.  The less "magic" (in this case,
> >>the register address calculation), the better.
> >
> >The problem with this approach is that since the control registers are
> >within the AFI register range, both the reg and ranges properties of the
> >parent would have to include these holes. Furthermore it means that the
> >controller driver would have to remap the AFI registers in chunks, for the
> >sole reason of splitting out the controle registers.
> >
> >Would it be acceptable to make an exception in this case and use the port's
> >second reg entry as an offset into the AFI register range instead?
> 
> How about this:
> 
>     pcie-controller {
>         compatible = "nvidia,tegra20-pcie";
>         reg =<0x80003000 0x00000800   /* PADS registers */
>               0x80003800 0x00000200>   /* AFI registers */
>         interrupts =<0 98 0x04   /* controller interrupt */
>                      0 99 0x04>; /* MSI interrupt */
>         status = "disabled";
> 
>         ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
>               0x80004000 0x80004000 0x00100000   /* configuration space */
>               0x80104000 0x80104000 0x00100000   /* extended
> configuration space */
>               0x80400000 0x80400000 0x00010000   /* downstream I/O */
>               0x90000000 0x90000000 0x10000000   /* non-prefetchable
> memory */
>               0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */

I think the configuration spaces and downstream I/O ranges need to be in the
pcie-controller's reg property because they are remapped and used by the
controller driver, not by the individual ports.

That's probably not really necessary but rather a result of how the driver
was written. Perhaps the driver should handle them differently instead,
listing the regions in the ranges property of the parent and listing the
corresponding partitions in the ranges properties of the pci child nodes.

Like in the following, where the ranges property of the ports partition the
ranges passed from the parent evenly:

	pcie-controller {
		compatible = "nvidia,tegra20-pcie";
		reg = <0x80003000 0x00000800   /* PADS registers */
		       0x80003800 0x00000200>; /* AFI registers */
		interrupts = <0 98 0x04   /* controller interrupt */
			      0 99 0x04>; /* MSI interrupt */
		status = "disabled";

		ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */
			  0x80004000 0x80004000 0x00100000   /* configuration space */
			  0x80104000 0x80100000 0x00100000   /* extended configuration space */
			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */

		#address-cells = <1>;
		#size-cells = <1>;

		pci@80000000 {
			reg = <0x80000000 0x00001000>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;

			ranges = <0x80400000 0x80400000 0x00008000   /* I/O */
				  0x90000000 0x90000000 0x08000000   /* non-prefetchable memory */
				  0xa0000000 0xa0000000 0x08000000>; /* prefetchable memory */

			nvidia,ctrl-offset = <0x0>;
			nvidia,num-lanes = <2>;
		};

		pci@80001000 {
			reg = <0x80001000 0x00001000>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;

			ranges = <0x80408000 0x80408000 0x00008000   /* I/O */
				  0x98000000 0x98000000 0x08000000   /* non-prefetchable memory */
				  0xa8000000 0xa8000000 0x08000000>; /* prefetchable memory */

			nvidia,ctrl-offset = <0x8>;
			nvidia,num-lanes = <2>;
		};
	};

I've also added the new num-lanes property that describes the physical
connections of the port. Also the ctrl-offset and num-lanes property are
pretty specific to the Tegra PCIe controller, so I've prefixed them with
"nvidia,".

> 
>         #address-cells =<1>;
>         #size-cells =<1>;
> 
>         pci@80000000 {
>             reg =<0x80000000 0x00001000>;
>             ctrl-offset =<0x0>;
>             status = "disabled";
>             #address-cells = <3>;  /* Standard for PCI */
>             #size-cells =<2>;      /* Standard for PCI */
>             ranges =</* Map from standard PCI child address spaces
> to linear spaces above */>;
>         };
> 
>         pci@80001000 {
>             reg =<0x80001000 0x00001000>;
>             ctrl-offset =<0x8>;
>             status = "disabled";
>             #address-cells = <3>;  /* Standard for PCI */
>             #size-cells =<2>;      /* Standard for PCI */
>             ranges =</* Map from standard PCI child address spaces
> to linear spaces above */>;
>         };
>     };
> 
> Using ctrl-offset instead of reg avoids any violation of the usual
> reg semantics.

Yes, that sounds better.

> 
> Note that the pci subnodes need the full complement of PCI bus node
> properties.
> 
> >
> >
> >Thierry
> 

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-13  7:52                             ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-13  7:52 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jun 12, 2012 at 09:28:51PM -1000, Mitch Bradley wrote:
> On 6/12/2012 8:45 PM, Thierry Reding wrote:
> >* Mitch Bradley wrote:
> >>On 6/12/2012 10:15 AM, Stephen Warren wrote:
> >>>On 06/12/2012 11:20 AM, Thierry Reding wrote:
> >>>...
> >>>>I came up with the following alternative:
> >>>>
> >>>>	pci {
> >>>>		compatible = "nvidia,tegra20-pcie";
> >>>>		reg =<0x80003000 0x00000800   /* PADS registers */
> >>>>		       0x80003800 0x00000200   /* AFI registers */
> >>>>		       0x80004000 0x00100000   /* configuration space */
> >>>>		       0x80104000 0x00100000   /* extended configuration space */
> >>>>		       0x80400000 0x00010000   /* downstream I/O */
> >>>>		       0x90000000 0x10000000   /* non-prefetchable memory */
> >>>>		       0xa0000000 0x10000000>; /* prefetchable memory */
> >>>>		interrupts =<0 98 0x04   /* controller interrupt */
> >>>>		              0 99 0x04>; /* MSI interrupt */
> >>>>		status = "disabled";
> >>>>
> >>>>		ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
> >>>>			  0x80004000 0x80004000 0x00100000   /* configuration space */
> >>>>			  0x80104000 0x80104000 0x00100000   /* extended configuration space */
> >>>>			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
> >>>>			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
> >>>>			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
> >>>>
> >>>>		#address-cells =<1>;
> >>>>		#size-cells =<1>;
> >>>>
> >>>>		port at 80000000 {
> >>>>			reg =<0x80000000 0x00001000>;
> >>>>			status = "disabled";
> >>>>		};
> >>>>
> >>>>		port at 80001000 {
> >>>>			reg =<0x80001000 0x00001000>;
> >>>>			status = "disabled";
> >>>>		};
> >>>>	};
> >>>>
> >>>>The "ranges" property can probably be cleaned up a bit, but the most
> >>>>interesting part is the port@ children, which can simply be enabled in board
> >>>>DTS files by setting the status property to "okay". I find that somewhat more
> >>>>intuitive to the variant with an "enable-ports" property.
> >>>>
> >>>>What do you think of this?
> >>>
> >>>As a general concept, this kind of design seems OK to me.
> >>>
> >>>The "port" child nodes I think should be named "pci at ..." given Mitch's
> >>>comments, I think.
> >>>
> >>>The port nodes probably need two entries in reg, given the following in
> >>>our downstream driver:
> >>>
> >>>>         int rp_offset = 0;
> >>>>         int ctrl_offset = AFI_PEX0_CTRL;
> >>>...
> >>>>         for (port = 0; port<   MAX_PCIE_SUPPORTED_PORTS; port++) {
> >>>>                 ctrl_offset += (port * 8);
> >>>>                 rp_offset = (rp_offset + 0x1000) * port;
> >>>>                 if (tegra_pcie.plat_data->port_status[port])
> >>>>                         tegra_pcie_add_port(port, rp_offset, ctrl_offset);
> >>>>         }
> >>>
> >>>(which actually looks likely to be horribly buggy for port>1 and only
> >>>accidentally correct for port==1, but anyway...)
> >>>
> >>>But instead, I'd be tempted to make the top-level node say:
> >>>
> >>>	#address-cells =<1>;
> >>>	#size-cells =<0>;
> >>>
> >>>... so that the child nodes' reg is just the port ID. The parent node
> >>>can calculate the addresses/offsets of the per-port registers within the
> >>>PCIe controller's register space based on the ID using code roughly like
> >>>what I quoted above:
> >>>
> >>>	pci at 0 {
> >>>		reg =<0>;
> >>>		status = "disabled";
> >>>	};
> >>>
> >>>	pci at 1 {
> >>>		reg =<0>;
> >>>		status = "disabled";
> >>>	};
> >>reg =<1>  ?
> >>
> >>>
> >>>
> >>>That would save having to put 2 entries in the reg, and perhaps remove
> >>>the need for any ranges property.
> >>
> >>ISTM that having two reg entries, specifying the rp and ctrl
> >>registers, is preferable to having code to calculate the addresses.
> >>That makes the code simpler and the device tree more directly
> >>descriptive of the hardware layout.  The less "magic" (in this case,
> >>the register address calculation), the better.
> >
> >The problem with this approach is that since the control registers are
> >within the AFI register range, both the reg and ranges properties of the
> >parent would have to include these holes. Furthermore it means that the
> >controller driver would have to remap the AFI registers in chunks, for the
> >sole reason of splitting out the controle registers.
> >
> >Would it be acceptable to make an exception in this case and use the port's
> >second reg entry as an offset into the AFI register range instead?
> 
> How about this:
> 
>     pcie-controller {
>         compatible = "nvidia,tegra20-pcie";
>         reg =<0x80003000 0x00000800   /* PADS registers */
>               0x80003800 0x00000200>   /* AFI registers */
>         interrupts =<0 98 0x04   /* controller interrupt */
>                      0 99 0x04>; /* MSI interrupt */
>         status = "disabled";
> 
>         ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
>               0x80004000 0x80004000 0x00100000   /* configuration space */
>               0x80104000 0x80104000 0x00100000   /* extended
> configuration space */
>               0x80400000 0x80400000 0x00010000   /* downstream I/O */
>               0x90000000 0x90000000 0x10000000   /* non-prefetchable
> memory */
>               0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */

I think the configuration spaces and downstream I/O ranges need to be in the
pcie-controller's reg property because they are remapped and used by the
controller driver, not by the individual ports.

That's probably not really necessary but rather a result of how the driver
was written. Perhaps the driver should handle them differently instead,
listing the regions in the ranges property of the parent and listing the
corresponding partitions in the ranges properties of the pci child nodes.

Like in the following, where the ranges property of the ports partition the
ranges passed from the parent evenly:

	pcie-controller {
		compatible = "nvidia,tegra20-pcie";
		reg = <0x80003000 0x00000800   /* PADS registers */
		       0x80003800 0x00000200>; /* AFI registers */
		interrupts = <0 98 0x04   /* controller interrupt */
			      0 99 0x04>; /* MSI interrupt */
		status = "disabled";

		ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */
			  0x80004000 0x80004000 0x00100000   /* configuration space */
			  0x80104000 0x80100000 0x00100000   /* extended configuration space */
			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */

		#address-cells = <1>;
		#size-cells = <1>;

		pci at 80000000 {
			reg = <0x80000000 0x00001000>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;

			ranges = <0x80400000 0x80400000 0x00008000   /* I/O */
				  0x90000000 0x90000000 0x08000000   /* non-prefetchable memory */
				  0xa0000000 0xa0000000 0x08000000>; /* prefetchable memory */

			nvidia,ctrl-offset = <0x0>;
			nvidia,num-lanes = <2>;
		};

		pci at 80001000 {
			reg = <0x80001000 0x00001000>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;

			ranges = <0x80408000 0x80408000 0x00008000   /* I/O */
				  0x98000000 0x98000000 0x08000000   /* non-prefetchable memory */
				  0xa8000000 0xa8000000 0x08000000>; /* prefetchable memory */

			nvidia,ctrl-offset = <0x8>;
			nvidia,num-lanes = <2>;
		};
	};

I've also added the new num-lanes property that describes the physical
connections of the port. Also the ctrl-offset and num-lanes property are
pretty specific to the Tegra PCIe controller, so I've prefixed them with
"nvidia,".

> 
>         #address-cells =<1>;
>         #size-cells =<1>;
> 
>         pci at 80000000 {
>             reg =<0x80000000 0x00001000>;
>             ctrl-offset =<0x0>;
>             status = "disabled";
>             #address-cells = <3>;  /* Standard for PCI */
>             #size-cells =<2>;      /* Standard for PCI */
>             ranges =</* Map from standard PCI child address spaces
> to linear spaces above */>;
>         };
> 
>         pci at 80001000 {
>             reg =<0x80001000 0x00001000>;
>             ctrl-offset =<0x8>;
>             status = "disabled";
>             #address-cells = <3>;  /* Standard for PCI */
>             #size-cells =<2>;      /* Standard for PCI */
>             ranges =</* Map from standard PCI child address spaces
> to linear spaces above */>;
>         };
>     };
> 
> Using ctrl-offset instead of reg avoids any violation of the usual
> reg semantics.

Yes, that sounds better.

> 
> Note that the pci subnodes need the full complement of PCI bus node
> properties.
> 
> >
> >
> >Thierry
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120613/f40d07c2/attachment.sig>

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-13  7:52                             ` Thierry Reding
  (?)
@ 2012-06-13  8:05                                 ` Mitch Bradley
  -1 siblings, 0 replies; 249+ messages in thread
From: Mitch Bradley @ 2012-06-13  8:05 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Russell King, linux-pci-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Jesse Barnes,
	Rob Herring, Colin Cross, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On 6/12/2012 9:52 PM, Thierry Reding wrote:
> On Tue, Jun 12, 2012 at 09:28:51PM -1000, Mitch Bradley wrote:
>> On 6/12/2012 8:45 PM, Thierry Reding wrote:
>>> * Mitch Bradley wrote:
>>>> On 6/12/2012 10:15 AM, Stephen Warren wrote:
>>>>> On 06/12/2012 11:20 AM, Thierry Reding wrote:
>>>>> ...
>>>>>> I came up with the following alternative:
>>>>>>
>>>>>> 	pci {
>>>>>> 		compatible = "nvidia,tegra20-pcie";
>>>>>> 		reg =<0x80003000 0x00000800   /* PADS registers */
>>>>>> 		       0x80003800 0x00000200   /* AFI registers */
>>>>>> 		       0x80004000 0x00100000   /* configuration space */
>>>>>> 		       0x80104000 0x00100000   /* extended configuration space */
>>>>>> 		       0x80400000 0x00010000   /* downstream I/O */
>>>>>> 		       0x90000000 0x10000000   /* non-prefetchable memory */
>>>>>> 		       0xa0000000 0x10000000>; /* prefetchable memory */
>>>>>> 		interrupts =<0 98 0x04   /* controller interrupt */
>>>>>> 		              0 99 0x04>; /* MSI interrupt */
>>>>>> 		status = "disabled";
>>>>>>
>>>>>> 		ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
>>>>>> 			  0x80004000 0x80004000 0x00100000   /* configuration space */
>>>>>> 			  0x80104000 0x80104000 0x00100000   /* extended configuration space */
>>>>>> 			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
>>>>>> 			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
>>>>>> 			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
>>>>>>
>>>>>> 		#address-cells =<1>;
>>>>>> 		#size-cells =<1>;
>>>>>>
>>>>>> 		port@80000000 {
>>>>>> 			reg =<0x80000000 0x00001000>;
>>>>>> 			status = "disabled";
>>>>>> 		};
>>>>>>
>>>>>> 		port@80001000 {
>>>>>> 			reg =<0x80001000 0x00001000>;
>>>>>> 			status = "disabled";
>>>>>> 		};
>>>>>> 	};
>>>>>>
>>>>>> The "ranges" property can probably be cleaned up a bit, but the most
>>>>>> interesting part is the port@ children, which can simply be enabled in board
>>>>>> DTS files by setting the status property to "okay". I find that somewhat more
>>>>>> intuitive to the variant with an "enable-ports" property.
>>>>>>
>>>>>> What do you think of this?
>>>>>
>>>>> As a general concept, this kind of design seems OK to me.
>>>>>
>>>>> The "port" child nodes I think should be named "pci@..." given Mitch's
>>>>> comments, I think.
>>>>>
>>>>> The port nodes probably need two entries in reg, given the following in
>>>>> our downstream driver:
>>>>>
>>>>>>          int rp_offset = 0;
>>>>>>          int ctrl_offset = AFI_PEX0_CTRL;
>>>>> ...
>>>>>>          for (port = 0; port<    MAX_PCIE_SUPPORTED_PORTS; port++) {
>>>>>>                  ctrl_offset += (port * 8);
>>>>>>                  rp_offset = (rp_offset + 0x1000) * port;
>>>>>>                  if (tegra_pcie.plat_data->port_status[port])
>>>>>>                          tegra_pcie_add_port(port, rp_offset, ctrl_offset);
>>>>>>          }
>>>>>
>>>>> (which actually looks likely to be horribly buggy for port>1 and only
>>>>> accidentally correct for port==1, but anyway...)
>>>>>
>>>>> But instead, I'd be tempted to make the top-level node say:
>>>>>
>>>>> 	#address-cells =<1>;
>>>>> 	#size-cells =<0>;
>>>>>
>>>>> ... so that the child nodes' reg is just the port ID. The parent node
>>>>> can calculate the addresses/offsets of the per-port registers within the
>>>>> PCIe controller's register space based on the ID using code roughly like
>>>>> what I quoted above:
>>>>>
>>>>> 	pci@0 {
>>>>> 		reg =<0>;
>>>>> 		status = "disabled";
>>>>> 	};
>>>>>
>>>>> 	pci@1 {
>>>>> 		reg =<0>;
>>>>> 		status = "disabled";
>>>>> 	};
>>>> reg =<1>   ?
>>>>
>>>>>
>>>>>
>>>>> That would save having to put 2 entries in the reg, and perhaps remove
>>>>> the need for any ranges property.
>>>>
>>>> ISTM that having two reg entries, specifying the rp and ctrl
>>>> registers, is preferable to having code to calculate the addresses.
>>>> That makes the code simpler and the device tree more directly
>>>> descriptive of the hardware layout.  The less "magic" (in this case,
>>>> the register address calculation), the better.
>>>
>>> The problem with this approach is that since the control registers are
>>> within the AFI register range, both the reg and ranges properties of the
>>> parent would have to include these holes. Furthermore it means that the
>>> controller driver would have to remap the AFI registers in chunks, for the
>>> sole reason of splitting out the controle registers.
>>>
>>> Would it be acceptable to make an exception in this case and use the port's
>>> second reg entry as an offset into the AFI register range instead?
>>
>> How about this:
>>
>>      pcie-controller {
>>          compatible = "nvidia,tegra20-pcie";
>>          reg =<0x80003000 0x00000800   /* PADS registers */
>>                0x80003800 0x00000200>    /* AFI registers */
>>          interrupts =<0 98 0x04   /* controller interrupt */
>>                       0 99 0x04>; /* MSI interrupt */
>>          status = "disabled";
>>
>>          ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
>>                0x80004000 0x80004000 0x00100000   /* configuration space */
>>                0x80104000 0x80104000 0x00100000   /* extended
>> configuration space */
>>                0x80400000 0x80400000 0x00010000   /* downstream I/O */
>>                0x90000000 0x90000000 0x10000000   /* non-prefetchable
>> memory */
>>                0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
>
> I think the configuration spaces and downstream I/O ranges need to be in the
> pcie-controller's reg property because they are remapped and used by the
> controller driver, not by the individual ports.
>
> That's probably not really necessary but rather a result of how the driver
> was written. Perhaps the driver should handle them differently instead,
> listing the regions in the ranges property of the parent and listing the
> corresponding partitions in the ranges properties of the pci child nodes.
>
> Like in the following, where the ranges property of the ports partition the
> ranges passed from the parent evenly:
>
> 	pcie-controller {
> 		compatible = "nvidia,tegra20-pcie";
> 		reg =<0x80003000 0x00000800   /* PADS registers */
> 		       0x80003800 0x00000200>; /* AFI registers */
> 		interrupts =<0 98 0x04   /* controller interrupt */
> 			      0 99 0x04>; /* MSI interrupt */
> 		status = "disabled";
>
> 		ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
> 			  0x80004000 0x80004000 0x00100000   /* configuration space */
> 			  0x80104000 0x80100000 0x00100000   /* extended configuration space */
> 			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
> 			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
> 			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
>
> 		#address-cells =<1>;
> 		#size-cells =<1>;
>
> 		pci@80000000 {
> 			reg =<0x80000000 0x00001000>;
> 			status = "disabled";
>
> 			#address-cells =<3>;
> 			#size-cells =<2>;
>
> 			ranges =<0x80400000 0x80400000 0x00008000   /* I/O */
> 				  0x90000000 0x90000000 0x08000000   /* non-prefetchable memory */
> 				  0xa0000000 0xa0000000 0x08000000>; /* prefetchable memory */

You are on the right track here, but the format of the child-address 
portion of the above ranges property is incorrect.  Since the child 
address space is the PCI address space, the child-address portion needs 
to be 3 cells.  It's not a linear address but rather a triple.  The 
first cell identifies the address type (config, I/O, memory..) and the 
second and third cells are offsets within that subspace.  The second and 
third cells will typically be 0.  The PCI binding has details.

>
>
> 			nvidia,ctrl-offset =<0x0>;
> 			nvidia,num-lanes =<2>;
> 		};
>
> 		pci@80001000 {
> 			reg =<0x80001000 0x00001000>;
> 			status = "disabled";
>
> 			#address-cells =<3>;
> 			#size-cells =<2>;
>
> 			ranges =<0x80408000 0x80408000 0x00008000   /* I/O */
> 				  0x98000000 0x98000000 0x08000000   /* non-prefetchable memory */
> 				  0xa8000000 0xa8000000 0x08000000>; /* prefetchable memory */
>
> 			nvidia,ctrl-offset =<0x8>;
> 			nvidia,num-lanes =<2>;
> 		};
> 	};
>
> I've also added the new num-lanes property that describes the physical
> connections of the port. Also the ctrl-offset and num-lanes property are
> pretty specific to the Tegra PCIe controller, so I've prefixed them with
> "nvidia,".
>
>>
>>          #address-cells =<1>;
>>          #size-cells =<1>;
>>
>>          pci@80000000 {
>>              reg =<0x80000000 0x00001000>;
>>              ctrl-offset =<0x0>;
>>              status = "disabled";
>>              #address-cells =<3>;  /* Standard for PCI */
>>              #size-cells =<2>;      /* Standard for PCI */
>>              ranges =</* Map from standard PCI child address spaces
>> to linear spaces above */>;
>>          };
>>
>>          pci@80001000 {
>>              reg =<0x80001000 0x00001000>;
>>              ctrl-offset =<0x8>;
>>              status = "disabled";
>>              #address-cells =<3>;  /* Standard for PCI */
>>              #size-cells =<2>;      /* Standard for PCI */
>>              ranges =</* Map from standard PCI child address spaces
>> to linear spaces above */>;
>>          };
>>      };
>>
>> Using ctrl-offset instead of reg avoids any violation of the usual
>> reg semantics.
>
> Yes, that sounds better.
>
>>
>> Note that the pci subnodes need the full complement of PCI bus node
>> properties.
>>
>>>
>>>
>>> Thierry
>>

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-13  8:05                                 ` Mitch Bradley
  0 siblings, 0 replies; 249+ messages in thread
From: Mitch Bradley @ 2012-06-13  8:05 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Stephen Warren, Russell King, linux-pci, devicetree-discuss,
	Rob Herring, Jesse Barnes, Colin Cross, linux-tegra,
	linux-arm-kernel

On 6/12/2012 9:52 PM, Thierry Reding wrote:
> On Tue, Jun 12, 2012 at 09:28:51PM -1000, Mitch Bradley wrote:
>> On 6/12/2012 8:45 PM, Thierry Reding wrote:
>>> * Mitch Bradley wrote:
>>>> On 6/12/2012 10:15 AM, Stephen Warren wrote:
>>>>> On 06/12/2012 11:20 AM, Thierry Reding wrote:
>>>>> ...
>>>>>> I came up with the following alternative:
>>>>>>
>>>>>> 	pci {
>>>>>> 		compatible = "nvidia,tegra20-pcie";
>>>>>> 		reg =<0x80003000 0x00000800   /* PADS registers */
>>>>>> 		       0x80003800 0x00000200   /* AFI registers */
>>>>>> 		       0x80004000 0x00100000   /* configuration space */
>>>>>> 		       0x80104000 0x00100000   /* extended configuration space */
>>>>>> 		       0x80400000 0x00010000   /* downstream I/O */
>>>>>> 		       0x90000000 0x10000000   /* non-prefetchable memory */
>>>>>> 		       0xa0000000 0x10000000>; /* prefetchable memory */
>>>>>> 		interrupts =<0 98 0x04   /* controller interrupt */
>>>>>> 		              0 99 0x04>; /* MSI interrupt */
>>>>>> 		status = "disabled";
>>>>>>
>>>>>> 		ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
>>>>>> 			  0x80004000 0x80004000 0x00100000   /* configuration space */
>>>>>> 			  0x80104000 0x80104000 0x00100000   /* extended configuration space */
>>>>>> 			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
>>>>>> 			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
>>>>>> 			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
>>>>>>
>>>>>> 		#address-cells =<1>;
>>>>>> 		#size-cells =<1>;
>>>>>>
>>>>>> 		port@80000000 {
>>>>>> 			reg =<0x80000000 0x00001000>;
>>>>>> 			status = "disabled";
>>>>>> 		};
>>>>>>
>>>>>> 		port@80001000 {
>>>>>> 			reg =<0x80001000 0x00001000>;
>>>>>> 			status = "disabled";
>>>>>> 		};
>>>>>> 	};
>>>>>>
>>>>>> The "ranges" property can probably be cleaned up a bit, but the most
>>>>>> interesting part is the port@ children, which can simply be enabled in board
>>>>>> DTS files by setting the status property to "okay". I find that somewhat more
>>>>>> intuitive to the variant with an "enable-ports" property.
>>>>>>
>>>>>> What do you think of this?
>>>>>
>>>>> As a general concept, this kind of design seems OK to me.
>>>>>
>>>>> The "port" child nodes I think should be named "pci@..." given Mitch's
>>>>> comments, I think.
>>>>>
>>>>> The port nodes probably need two entries in reg, given the following in
>>>>> our downstream driver:
>>>>>
>>>>>>          int rp_offset = 0;
>>>>>>          int ctrl_offset = AFI_PEX0_CTRL;
>>>>> ...
>>>>>>          for (port = 0; port<    MAX_PCIE_SUPPORTED_PORTS; port++) {
>>>>>>                  ctrl_offset += (port * 8);
>>>>>>                  rp_offset = (rp_offset + 0x1000) * port;
>>>>>>                  if (tegra_pcie.plat_data->port_status[port])
>>>>>>                          tegra_pcie_add_port(port, rp_offset, ctrl_offset);
>>>>>>          }
>>>>>
>>>>> (which actually looks likely to be horribly buggy for port>1 and only
>>>>> accidentally correct for port==1, but anyway...)
>>>>>
>>>>> But instead, I'd be tempted to make the top-level node say:
>>>>>
>>>>> 	#address-cells =<1>;
>>>>> 	#size-cells =<0>;
>>>>>
>>>>> ... so that the child nodes' reg is just the port ID. The parent node
>>>>> can calculate the addresses/offsets of the per-port registers within the
>>>>> PCIe controller's register space based on the ID using code roughly like
>>>>> what I quoted above:
>>>>>
>>>>> 	pci@0 {
>>>>> 		reg =<0>;
>>>>> 		status = "disabled";
>>>>> 	};
>>>>>
>>>>> 	pci@1 {
>>>>> 		reg =<0>;
>>>>> 		status = "disabled";
>>>>> 	};
>>>> reg =<1>   ?
>>>>
>>>>>
>>>>>
>>>>> That would save having to put 2 entries in the reg, and perhaps remove
>>>>> the need for any ranges property.
>>>>
>>>> ISTM that having two reg entries, specifying the rp and ctrl
>>>> registers, is preferable to having code to calculate the addresses.
>>>> That makes the code simpler and the device tree more directly
>>>> descriptive of the hardware layout.  The less "magic" (in this case,
>>>> the register address calculation), the better.
>>>
>>> The problem with this approach is that since the control registers are
>>> within the AFI register range, both the reg and ranges properties of the
>>> parent would have to include these holes. Furthermore it means that the
>>> controller driver would have to remap the AFI registers in chunks, for the
>>> sole reason of splitting out the controle registers.
>>>
>>> Would it be acceptable to make an exception in this case and use the port's
>>> second reg entry as an offset into the AFI register range instead?
>>
>> How about this:
>>
>>      pcie-controller {
>>          compatible = "nvidia,tegra20-pcie";
>>          reg =<0x80003000 0x00000800   /* PADS registers */
>>                0x80003800 0x00000200>    /* AFI registers */
>>          interrupts =<0 98 0x04   /* controller interrupt */
>>                       0 99 0x04>; /* MSI interrupt */
>>          status = "disabled";
>>
>>          ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
>>                0x80004000 0x80004000 0x00100000   /* configuration space */
>>                0x80104000 0x80104000 0x00100000   /* extended
>> configuration space */
>>                0x80400000 0x80400000 0x00010000   /* downstream I/O */
>>                0x90000000 0x90000000 0x10000000   /* non-prefetchable
>> memory */
>>                0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
>
> I think the configuration spaces and downstream I/O ranges need to be in the
> pcie-controller's reg property because they are remapped and used by the
> controller driver, not by the individual ports.
>
> That's probably not really necessary but rather a result of how the driver
> was written. Perhaps the driver should handle them differently instead,
> listing the regions in the ranges property of the parent and listing the
> corresponding partitions in the ranges properties of the pci child nodes.
>
> Like in the following, where the ranges property of the ports partition the
> ranges passed from the parent evenly:
>
> 	pcie-controller {
> 		compatible = "nvidia,tegra20-pcie";
> 		reg =<0x80003000 0x00000800   /* PADS registers */
> 		       0x80003800 0x00000200>; /* AFI registers */
> 		interrupts =<0 98 0x04   /* controller interrupt */
> 			      0 99 0x04>; /* MSI interrupt */
> 		status = "disabled";
>
> 		ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
> 			  0x80004000 0x80004000 0x00100000   /* configuration space */
> 			  0x80104000 0x80100000 0x00100000   /* extended configuration space */
> 			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
> 			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
> 			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
>
> 		#address-cells =<1>;
> 		#size-cells =<1>;
>
> 		pci@80000000 {
> 			reg =<0x80000000 0x00001000>;
> 			status = "disabled";
>
> 			#address-cells =<3>;
> 			#size-cells =<2>;
>
> 			ranges =<0x80400000 0x80400000 0x00008000   /* I/O */
> 				  0x90000000 0x90000000 0x08000000   /* non-prefetchable memory */
> 				  0xa0000000 0xa0000000 0x08000000>; /* prefetchable memory */

You are on the right track here, but the format of the child-address 
portion of the above ranges property is incorrect.  Since the child 
address space is the PCI address space, the child-address portion needs 
to be 3 cells.  It's not a linear address but rather a triple.  The 
first cell identifies the address type (config, I/O, memory..) and the 
second and third cells are offsets within that subspace.  The second and 
third cells will typically be 0.  The PCI binding has details.

>
>
> 			nvidia,ctrl-offset =<0x0>;
> 			nvidia,num-lanes =<2>;
> 		};
>
> 		pci@80001000 {
> 			reg =<0x80001000 0x00001000>;
> 			status = "disabled";
>
> 			#address-cells =<3>;
> 			#size-cells =<2>;
>
> 			ranges =<0x80408000 0x80408000 0x00008000   /* I/O */
> 				  0x98000000 0x98000000 0x08000000   /* non-prefetchable memory */
> 				  0xa8000000 0xa8000000 0x08000000>; /* prefetchable memory */
>
> 			nvidia,ctrl-offset =<0x8>;
> 			nvidia,num-lanes =<2>;
> 		};
> 	};
>
> I've also added the new num-lanes property that describes the physical
> connections of the port. Also the ctrl-offset and num-lanes property are
> pretty specific to the Tegra PCIe controller, so I've prefixed them with
> "nvidia,".
>
>>
>>          #address-cells =<1>;
>>          #size-cells =<1>;
>>
>>          pci@80000000 {
>>              reg =<0x80000000 0x00001000>;
>>              ctrl-offset =<0x0>;
>>              status = "disabled";
>>              #address-cells =<3>;  /* Standard for PCI */
>>              #size-cells =<2>;      /* Standard for PCI */
>>              ranges =</* Map from standard PCI child address spaces
>> to linear spaces above */>;
>>          };
>>
>>          pci@80001000 {
>>              reg =<0x80001000 0x00001000>;
>>              ctrl-offset =<0x8>;
>>              status = "disabled";
>>              #address-cells =<3>;  /* Standard for PCI */
>>              #size-cells =<2>;      /* Standard for PCI */
>>              ranges =</* Map from standard PCI child address spaces
>> to linear spaces above */>;
>>          };
>>      };
>>
>> Using ctrl-offset instead of reg avoids any violation of the usual
>> reg semantics.
>
> Yes, that sounds better.
>
>>
>> Note that the pci subnodes need the full complement of PCI bus node
>> properties.
>>
>>>
>>>
>>> Thierry
>>

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-13  8:05                                 ` Mitch Bradley
  0 siblings, 0 replies; 249+ messages in thread
From: Mitch Bradley @ 2012-06-13  8:05 UTC (permalink / raw)
  To: linux-arm-kernel

On 6/12/2012 9:52 PM, Thierry Reding wrote:
> On Tue, Jun 12, 2012 at 09:28:51PM -1000, Mitch Bradley wrote:
>> On 6/12/2012 8:45 PM, Thierry Reding wrote:
>>> * Mitch Bradley wrote:
>>>> On 6/12/2012 10:15 AM, Stephen Warren wrote:
>>>>> On 06/12/2012 11:20 AM, Thierry Reding wrote:
>>>>> ...
>>>>>> I came up with the following alternative:
>>>>>>
>>>>>> 	pci {
>>>>>> 		compatible = "nvidia,tegra20-pcie";
>>>>>> 		reg =<0x80003000 0x00000800   /* PADS registers */
>>>>>> 		       0x80003800 0x00000200   /* AFI registers */
>>>>>> 		       0x80004000 0x00100000   /* configuration space */
>>>>>> 		       0x80104000 0x00100000   /* extended configuration space */
>>>>>> 		       0x80400000 0x00010000   /* downstream I/O */
>>>>>> 		       0x90000000 0x10000000   /* non-prefetchable memory */
>>>>>> 		       0xa0000000 0x10000000>; /* prefetchable memory */
>>>>>> 		interrupts =<0 98 0x04   /* controller interrupt */
>>>>>> 		              0 99 0x04>; /* MSI interrupt */
>>>>>> 		status = "disabled";
>>>>>>
>>>>>> 		ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
>>>>>> 			  0x80004000 0x80004000 0x00100000   /* configuration space */
>>>>>> 			  0x80104000 0x80104000 0x00100000   /* extended configuration space */
>>>>>> 			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
>>>>>> 			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
>>>>>> 			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
>>>>>>
>>>>>> 		#address-cells =<1>;
>>>>>> 		#size-cells =<1>;
>>>>>>
>>>>>> 		port at 80000000 {
>>>>>> 			reg =<0x80000000 0x00001000>;
>>>>>> 			status = "disabled";
>>>>>> 		};
>>>>>>
>>>>>> 		port at 80001000 {
>>>>>> 			reg =<0x80001000 0x00001000>;
>>>>>> 			status = "disabled";
>>>>>> 		};
>>>>>> 	};
>>>>>>
>>>>>> The "ranges" property can probably be cleaned up a bit, but the most
>>>>>> interesting part is the port@ children, which can simply be enabled in board
>>>>>> DTS files by setting the status property to "okay". I find that somewhat more
>>>>>> intuitive to the variant with an "enable-ports" property.
>>>>>>
>>>>>> What do you think of this?
>>>>>
>>>>> As a general concept, this kind of design seems OK to me.
>>>>>
>>>>> The "port" child nodes I think should be named "pci at ..." given Mitch's
>>>>> comments, I think.
>>>>>
>>>>> The port nodes probably need two entries in reg, given the following in
>>>>> our downstream driver:
>>>>>
>>>>>>          int rp_offset = 0;
>>>>>>          int ctrl_offset = AFI_PEX0_CTRL;
>>>>> ...
>>>>>>          for (port = 0; port<    MAX_PCIE_SUPPORTED_PORTS; port++) {
>>>>>>                  ctrl_offset += (port * 8);
>>>>>>                  rp_offset = (rp_offset + 0x1000) * port;
>>>>>>                  if (tegra_pcie.plat_data->port_status[port])
>>>>>>                          tegra_pcie_add_port(port, rp_offset, ctrl_offset);
>>>>>>          }
>>>>>
>>>>> (which actually looks likely to be horribly buggy for port>1 and only
>>>>> accidentally correct for port==1, but anyway...)
>>>>>
>>>>> But instead, I'd be tempted to make the top-level node say:
>>>>>
>>>>> 	#address-cells =<1>;
>>>>> 	#size-cells =<0>;
>>>>>
>>>>> ... so that the child nodes' reg is just the port ID. The parent node
>>>>> can calculate the addresses/offsets of the per-port registers within the
>>>>> PCIe controller's register space based on the ID using code roughly like
>>>>> what I quoted above:
>>>>>
>>>>> 	pci at 0 {
>>>>> 		reg =<0>;
>>>>> 		status = "disabled";
>>>>> 	};
>>>>>
>>>>> 	pci at 1 {
>>>>> 		reg =<0>;
>>>>> 		status = "disabled";
>>>>> 	};
>>>> reg =<1>   ?
>>>>
>>>>>
>>>>>
>>>>> That would save having to put 2 entries in the reg, and perhaps remove
>>>>> the need for any ranges property.
>>>>
>>>> ISTM that having two reg entries, specifying the rp and ctrl
>>>> registers, is preferable to having code to calculate the addresses.
>>>> That makes the code simpler and the device tree more directly
>>>> descriptive of the hardware layout.  The less "magic" (in this case,
>>>> the register address calculation), the better.
>>>
>>> The problem with this approach is that since the control registers are
>>> within the AFI register range, both the reg and ranges properties of the
>>> parent would have to include these holes. Furthermore it means that the
>>> controller driver would have to remap the AFI registers in chunks, for the
>>> sole reason of splitting out the controle registers.
>>>
>>> Would it be acceptable to make an exception in this case and use the port's
>>> second reg entry as an offset into the AFI register range instead?
>>
>> How about this:
>>
>>      pcie-controller {
>>          compatible = "nvidia,tegra20-pcie";
>>          reg =<0x80003000 0x00000800   /* PADS registers */
>>                0x80003800 0x00000200>    /* AFI registers */
>>          interrupts =<0 98 0x04   /* controller interrupt */
>>                       0 99 0x04>; /* MSI interrupt */
>>          status = "disabled";
>>
>>          ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
>>                0x80004000 0x80004000 0x00100000   /* configuration space */
>>                0x80104000 0x80104000 0x00100000   /* extended
>> configuration space */
>>                0x80400000 0x80400000 0x00010000   /* downstream I/O */
>>                0x90000000 0x90000000 0x10000000   /* non-prefetchable
>> memory */
>>                0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
>
> I think the configuration spaces and downstream I/O ranges need to be in the
> pcie-controller's reg property because they are remapped and used by the
> controller driver, not by the individual ports.
>
> That's probably not really necessary but rather a result of how the driver
> was written. Perhaps the driver should handle them differently instead,
> listing the regions in the ranges property of the parent and listing the
> corresponding partitions in the ranges properties of the pci child nodes.
>
> Like in the following, where the ranges property of the ports partition the
> ranges passed from the parent evenly:
>
> 	pcie-controller {
> 		compatible = "nvidia,tegra20-pcie";
> 		reg =<0x80003000 0x00000800   /* PADS registers */
> 		       0x80003800 0x00000200>; /* AFI registers */
> 		interrupts =<0 98 0x04   /* controller interrupt */
> 			      0 99 0x04>; /* MSI interrupt */
> 		status = "disabled";
>
> 		ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
> 			  0x80004000 0x80004000 0x00100000   /* configuration space */
> 			  0x80104000 0x80100000 0x00100000   /* extended configuration space */
> 			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
> 			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
> 			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
>
> 		#address-cells =<1>;
> 		#size-cells =<1>;
>
> 		pci at 80000000 {
> 			reg =<0x80000000 0x00001000>;
> 			status = "disabled";
>
> 			#address-cells =<3>;
> 			#size-cells =<2>;
>
> 			ranges =<0x80400000 0x80400000 0x00008000   /* I/O */
> 				  0x90000000 0x90000000 0x08000000   /* non-prefetchable memory */
> 				  0xa0000000 0xa0000000 0x08000000>; /* prefetchable memory */

You are on the right track here, but the format of the child-address 
portion of the above ranges property is incorrect.  Since the child 
address space is the PCI address space, the child-address portion needs 
to be 3 cells.  It's not a linear address but rather a triple.  The 
first cell identifies the address type (config, I/O, memory..) and the 
second and third cells are offsets within that subspace.  The second and 
third cells will typically be 0.  The PCI binding has details.

>
>
> 			nvidia,ctrl-offset =<0x0>;
> 			nvidia,num-lanes =<2>;
> 		};
>
> 		pci at 80001000 {
> 			reg =<0x80001000 0x00001000>;
> 			status = "disabled";
>
> 			#address-cells =<3>;
> 			#size-cells =<2>;
>
> 			ranges =<0x80408000 0x80408000 0x00008000   /* I/O */
> 				  0x98000000 0x98000000 0x08000000   /* non-prefetchable memory */
> 				  0xa8000000 0xa8000000 0x08000000>; /* prefetchable memory */
>
> 			nvidia,ctrl-offset =<0x8>;
> 			nvidia,num-lanes =<2>;
> 		};
> 	};
>
> I've also added the new num-lanes property that describes the physical
> connections of the port. Also the ctrl-offset and num-lanes property are
> pretty specific to the Tegra PCIe controller, so I've prefixed them with
> "nvidia,".
>
>>
>>          #address-cells =<1>;
>>          #size-cells =<1>;
>>
>>          pci at 80000000 {
>>              reg =<0x80000000 0x00001000>;
>>              ctrl-offset =<0x0>;
>>              status = "disabled";
>>              #address-cells =<3>;  /* Standard for PCI */
>>              #size-cells =<2>;      /* Standard for PCI */
>>              ranges =</* Map from standard PCI child address spaces
>> to linear spaces above */>;
>>          };
>>
>>          pci at 80001000 {
>>              reg =<0x80001000 0x00001000>;
>>              ctrl-offset =<0x8>;
>>              status = "disabled";
>>              #address-cells =<3>;  /* Standard for PCI */
>>              #size-cells =<2>;      /* Standard for PCI */
>>              ranges =</* Map from standard PCI child address spaces
>> to linear spaces above */>;
>>          };
>>      };
>>
>> Using ctrl-offset instead of reg avoids any violation of the usual
>> reg semantics.
>
> Yes, that sounds better.
>
>>
>> Note that the pci subnodes need the full complement of PCI bus node
>> properties.
>>
>>>
>>>
>>> Thierry
>>

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

* Re: [PATCH v2 05/10] ARM: tegra: Rewrite PCIe support as a driver
  2012-06-12 16:00               ` Stephen Warren
@ 2012-06-13  8:12                 ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-13  8:12 UTC (permalink / raw)
  To: Stephen Warren
  Cc: linux-tegra, Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson

[-- Attachment #1: Type: text/plain, Size: 4427 bytes --]

On Tue, Jun 12, 2012 at 10:00:26AM -0600, Stephen Warren wrote:
> On 06/12/2012 01:24 AM, Thierry Reding wrote:
> > * Thierry Reding wrote:
> >> AFAICT the even partitioning of the non-prefetchable and 
> >> prefetchable memory regions is arbitrary and it could
> >> potentially be useful to make it configurable via the DT.
> > 
> > So it turns out that this isn't true. But apart from the comments 
> > in the driver I couldn't find any reference to how the prefetch
> > and non-prefetch ranges are partitioned. Judging by the code for
> > Tegra2 this is evenly partitioned among ports 0 and 1 but it would
> > be interesting to know this is done on Tegra3. Is there any way
> > you can find out?
> > 
> > It'd also be nice if some better documentation for the PCIe 
> > controller could be made available. The Tegra2 TRM doesn't contain 
> > any of the AFI or PADS registers and while the Tegra3 TRM
> > documents more registers, their offsets are completely missing.
> 
> I've filed a bug to request better documentation.
> 
> Looking at our downstream driver, the quoted comment below implies
> that the address space layout is pretty arbitrary and programmable at
> least for Tegra30. The code in function
> tegra_pcie_setup_translations() appears to support this (and is
> executed for both Tegra20 and Tegra30, even though the comment for
> Tegra20 doesn't mention any programmability).
> 
> Tegra20:
> 
> > /*
> >  * Tegra2 defines 1GB in the AXI address map for PCIe.
> >  *
> >  * That address space is split into different regions, with sizes and
> >  * offsets as follows:
> >  *
> >  * 0x80000000 - 0x80003fff - PCI controller registers
> >  * 0x80004000 - 0x80103fff - PCI configuration space
> >  * 0x80104000 - 0x80203fff - PCI extended configuration space
> >  * 0x80203fff - 0x803fffff - unused
> >  * 0x80400000 - 0x8040ffff - downstream IO
> >  * 0x80410000 - 0x8fffffff - unused
> >  * 0x90000000 - 0x9fffffff - non-prefetchable memory
> >  * 0xa0000000 - 0xbfffffff - prefetchable memory
> >  */
> 
> (I guess by "is split", it means the driver sets it up that way, not
> that the HW is fixed that way)
> 
> Tegra30:
> 
> > /*
> >  * AXI address map for the PCIe aperture , defines 1GB in the AXI
> >  *  address map for PCIe.
> >  *
> >  *  That address space is split into different regions, with sizes and
> >  *  offsets as follows. Exepct for the Register space, SW is free to slice the
> >  *  regions as it chooces.
> >  *
> >  *  The split below seems to work fine for now.
> >  *
> >  *  0x0000_0000 to 0x00ff_ffff - Register space          16MB.
> >  *  0x0100_0000 to 0x01ff_ffff - Config space            16MB.
> >  *  0x0200_0000 to 0x02ff_ffff - Extended config space   16MB.
> >  *  0x0300_0000 to 0x03ff_ffff - Downstream IO space
> >  *   ... Will be filled with other BARS like MSI/upstream IO etc.
> >  *  0x1000_0000 to 0x1fff_ffff - non-prefetchable memory aperture
> >  *  0x2000_0000 to 0x3fff_ffff - Prefetchable memory aperture
> >  *
> >  *  Config and Extended config sizes are choosen to support
> >  *  maximum of 256 devices,
> >  *  which is good enough for all the current use cases.
> >  *
> >  */
> 
> From
> http://nv-tegra.nvidia.com/gitweb/?p=linux-2.6.git;a=blob;f=arch/arm/mach-tegra/pcie.c;h=b98d4892b5ee46120a9777a969e820a0b5cbb68a;hb=android-tegra-nv-3.1

While it is apparently true that each region can be split arbitrarily this
doesn't seem to be true for the partitioning of each region between the
individual ports.

For instance, while non-prefetchable memory could possibly be mapped either
to 0x90000000 or to 0xa0000000 with an arbitrary size, the subregion that is
assigned to port 0 or 1 seems to be fixed. Judging by the code this currently
seems to be evenly distributed, but it's not so clear how this behaves when
port 1 for example is disabled, or how it is distributed on Tegra30 with all
three ports enabled (split into 3 equally-sized partitions?).

While the upstream driver currently still initializes the I/O and memory
resources for each port (splitting them into equally-sized partitions), the
latest downstream driver no longer seems to do so, but instead just
initializes a global resource for each resource type (tegra_pcie_preinit()).

I hope the improved documentation that you already requested will shed some
light on this.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* [PATCH v2 05/10] ARM: tegra: Rewrite PCIe support as a driver
@ 2012-06-13  8:12                 ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-13  8:12 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jun 12, 2012 at 10:00:26AM -0600, Stephen Warren wrote:
> On 06/12/2012 01:24 AM, Thierry Reding wrote:
> > * Thierry Reding wrote:
> >> AFAICT the even partitioning of the non-prefetchable and 
> >> prefetchable memory regions is arbitrary and it could
> >> potentially be useful to make it configurable via the DT.
> > 
> > So it turns out that this isn't true. But apart from the comments 
> > in the driver I couldn't find any reference to how the prefetch
> > and non-prefetch ranges are partitioned. Judging by the code for
> > Tegra2 this is evenly partitioned among ports 0 and 1 but it would
> > be interesting to know this is done on Tegra3. Is there any way
> > you can find out?
> > 
> > It'd also be nice if some better documentation for the PCIe 
> > controller could be made available. The Tegra2 TRM doesn't contain 
> > any of the AFI or PADS registers and while the Tegra3 TRM
> > documents more registers, their offsets are completely missing.
> 
> I've filed a bug to request better documentation.
> 
> Looking at our downstream driver, the quoted comment below implies
> that the address space layout is pretty arbitrary and programmable at
> least for Tegra30. The code in function
> tegra_pcie_setup_translations() appears to support this (and is
> executed for both Tegra20 and Tegra30, even though the comment for
> Tegra20 doesn't mention any programmability).
> 
> Tegra20:
> 
> > /*
> >  * Tegra2 defines 1GB in the AXI address map for PCIe.
> >  *
> >  * That address space is split into different regions, with sizes and
> >  * offsets as follows:
> >  *
> >  * 0x80000000 - 0x80003fff - PCI controller registers
> >  * 0x80004000 - 0x80103fff - PCI configuration space
> >  * 0x80104000 - 0x80203fff - PCI extended configuration space
> >  * 0x80203fff - 0x803fffff - unused
> >  * 0x80400000 - 0x8040ffff - downstream IO
> >  * 0x80410000 - 0x8fffffff - unused
> >  * 0x90000000 - 0x9fffffff - non-prefetchable memory
> >  * 0xa0000000 - 0xbfffffff - prefetchable memory
> >  */
> 
> (I guess by "is split", it means the driver sets it up that way, not
> that the HW is fixed that way)
> 
> Tegra30:
> 
> > /*
> >  * AXI address map for the PCIe aperture , defines 1GB in the AXI
> >  *  address map for PCIe.
> >  *
> >  *  That address space is split into different regions, with sizes and
> >  *  offsets as follows. Exepct for the Register space, SW is free to slice the
> >  *  regions as it chooces.
> >  *
> >  *  The split below seems to work fine for now.
> >  *
> >  *  0x0000_0000 to 0x00ff_ffff - Register space          16MB.
> >  *  0x0100_0000 to 0x01ff_ffff - Config space            16MB.
> >  *  0x0200_0000 to 0x02ff_ffff - Extended config space   16MB.
> >  *  0x0300_0000 to 0x03ff_ffff - Downstream IO space
> >  *   ... Will be filled with other BARS like MSI/upstream IO etc.
> >  *  0x1000_0000 to 0x1fff_ffff - non-prefetchable memory aperture
> >  *  0x2000_0000 to 0x3fff_ffff - Prefetchable memory aperture
> >  *
> >  *  Config and Extended config sizes are choosen to support
> >  *  maximum of 256 devices,
> >  *  which is good enough for all the current use cases.
> >  *
> >  */
> 
> From
> http://nv-tegra.nvidia.com/gitweb/?p=linux-2.6.git;a=blob;f=arch/arm/mach-tegra/pcie.c;h=b98d4892b5ee46120a9777a969e820a0b5cbb68a;hb=android-tegra-nv-3.1

While it is apparently true that each region can be split arbitrarily this
doesn't seem to be true for the partitioning of each region between the
individual ports.

For instance, while non-prefetchable memory could possibly be mapped either
to 0x90000000 or to 0xa0000000 with an arbitrary size, the subregion that is
assigned to port 0 or 1 seems to be fixed. Judging by the code this currently
seems to be evenly distributed, but it's not so clear how this behaves when
port 1 for example is disabled, or how it is distributed on Tegra30 with all
three ports enabled (split into 3 equally-sized partitions?).

While the upstream driver currently still initializes the I/O and memory
resources for each port (splitting them into equally-sized partitions), the
latest downstream driver no longer seems to do so, but instead just
initializes a global resource for each resource type (tegra_pcie_preinit()).

I hope the improved documentation that you already requested will shed some
light on this.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120613/7c3d998c/attachment.sig>

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-13  8:05                                 ` Mitch Bradley
  (?)
@ 2012-06-13  8:19                                     ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-13  8:19 UTC (permalink / raw)
  To: Mitch Bradley
  Cc: Stephen Warren, Russell King, linux-pci-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Jesse Barnes, Colin Cross, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

[-- Attachment #1: Type: text/plain, Size: 2497 bytes --]

On Tue, Jun 12, 2012 at 10:05:35PM -1000, Mitch Bradley wrote:
> On 6/12/2012 9:52 PM, Thierry Reding wrote:
> >I think the configuration spaces and downstream I/O ranges need to be in the
> >pcie-controller's reg property because they are remapped and used by the
> >controller driver, not by the individual ports.
> >
> >That's probably not really necessary but rather a result of how the driver
> >was written. Perhaps the driver should handle them differently instead,
> >listing the regions in the ranges property of the parent and listing the
> >corresponding partitions in the ranges properties of the pci child nodes.
> >
> >Like in the following, where the ranges property of the ports partition the
> >ranges passed from the parent evenly:
> >
> >	pcie-controller {
> >		compatible = "nvidia,tegra20-pcie";
> >		reg =<0x80003000 0x00000800   /* PADS registers */
> >		       0x80003800 0x00000200>; /* AFI registers */
> >		interrupts =<0 98 0x04   /* controller interrupt */
> >			      0 99 0x04>; /* MSI interrupt */
> >		status = "disabled";
> >
> >		ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
> >			  0x80004000 0x80004000 0x00100000   /* configuration space */
> >			  0x80104000 0x80100000 0x00100000   /* extended configuration space */
> >			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
> >			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
> >			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
> >
> >		#address-cells =<1>;
> >		#size-cells =<1>;
> >
> >		pci@80000000 {
> >			reg =<0x80000000 0x00001000>;
> >			status = "disabled";
> >
> >			#address-cells =<3>;
> >			#size-cells =<2>;
> >
> >			ranges =<0x80400000 0x80400000 0x00008000   /* I/O */
> >				  0x90000000 0x90000000 0x08000000   /* non-prefetchable memory */
> >				  0xa0000000 0xa0000000 0x08000000>; /* prefetchable memory */
> 
> You are on the right track here, but the format of the child-address
> portion of the above ranges property is incorrect.  Since the child
> address space is the PCI address space, the child-address portion
> needs to be 3 cells.  It's not a linear address but rather a triple.
> The first cell identifies the address type (config, I/O, memory..)
> and the second and third cells are offsets within that subspace.
> The second and third cells will typically be 0.  The PCI binding has
> details.

Okay, I'll need to read up some more.

Thanks,
Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-13  8:19                                     ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-13  8:19 UTC (permalink / raw)
  To: Mitch Bradley
  Cc: Stephen Warren, Russell King, linux-pci, devicetree-discuss,
	Rob Herring, Jesse Barnes, Colin Cross, linux-tegra,
	linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 2497 bytes --]

On Tue, Jun 12, 2012 at 10:05:35PM -1000, Mitch Bradley wrote:
> On 6/12/2012 9:52 PM, Thierry Reding wrote:
> >I think the configuration spaces and downstream I/O ranges need to be in the
> >pcie-controller's reg property because they are remapped and used by the
> >controller driver, not by the individual ports.
> >
> >That's probably not really necessary but rather a result of how the driver
> >was written. Perhaps the driver should handle them differently instead,
> >listing the regions in the ranges property of the parent and listing the
> >corresponding partitions in the ranges properties of the pci child nodes.
> >
> >Like in the following, where the ranges property of the ports partition the
> >ranges passed from the parent evenly:
> >
> >	pcie-controller {
> >		compatible = "nvidia,tegra20-pcie";
> >		reg =<0x80003000 0x00000800   /* PADS registers */
> >		       0x80003800 0x00000200>; /* AFI registers */
> >		interrupts =<0 98 0x04   /* controller interrupt */
> >			      0 99 0x04>; /* MSI interrupt */
> >		status = "disabled";
> >
> >		ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
> >			  0x80004000 0x80004000 0x00100000   /* configuration space */
> >			  0x80104000 0x80100000 0x00100000   /* extended configuration space */
> >			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
> >			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
> >			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
> >
> >		#address-cells =<1>;
> >		#size-cells =<1>;
> >
> >		pci@80000000 {
> >			reg =<0x80000000 0x00001000>;
> >			status = "disabled";
> >
> >			#address-cells =<3>;
> >			#size-cells =<2>;
> >
> >			ranges =<0x80400000 0x80400000 0x00008000   /* I/O */
> >				  0x90000000 0x90000000 0x08000000   /* non-prefetchable memory */
> >				  0xa0000000 0xa0000000 0x08000000>; /* prefetchable memory */
> 
> You are on the right track here, but the format of the child-address
> portion of the above ranges property is incorrect.  Since the child
> address space is the PCI address space, the child-address portion
> needs to be 3 cells.  It's not a linear address but rather a triple.
> The first cell identifies the address type (config, I/O, memory..)
> and the second and third cells are offsets within that subspace.
> The second and third cells will typically be 0.  The PCI binding has
> details.

Okay, I'll need to read up some more.

Thanks,
Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-13  8:19                                     ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-13  8:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jun 12, 2012 at 10:05:35PM -1000, Mitch Bradley wrote:
> On 6/12/2012 9:52 PM, Thierry Reding wrote:
> >I think the configuration spaces and downstream I/O ranges need to be in the
> >pcie-controller's reg property because they are remapped and used by the
> >controller driver, not by the individual ports.
> >
> >That's probably not really necessary but rather a result of how the driver
> >was written. Perhaps the driver should handle them differently instead,
> >listing the regions in the ranges property of the parent and listing the
> >corresponding partitions in the ranges properties of the pci child nodes.
> >
> >Like in the following, where the ranges property of the ports partition the
> >ranges passed from the parent evenly:
> >
> >	pcie-controller {
> >		compatible = "nvidia,tegra20-pcie";
> >		reg =<0x80003000 0x00000800   /* PADS registers */
> >		       0x80003800 0x00000200>; /* AFI registers */
> >		interrupts =<0 98 0x04   /* controller interrupt */
> >			      0 99 0x04>; /* MSI interrupt */
> >		status = "disabled";
> >
> >		ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
> >			  0x80004000 0x80004000 0x00100000   /* configuration space */
> >			  0x80104000 0x80100000 0x00100000   /* extended configuration space */
> >			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
> >			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
> >			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
> >
> >		#address-cells =<1>;
> >		#size-cells =<1>;
> >
> >		pci at 80000000 {
> >			reg =<0x80000000 0x00001000>;
> >			status = "disabled";
> >
> >			#address-cells =<3>;
> >			#size-cells =<2>;
> >
> >			ranges =<0x80400000 0x80400000 0x00008000   /* I/O */
> >				  0x90000000 0x90000000 0x08000000   /* non-prefetchable memory */
> >				  0xa0000000 0xa0000000 0x08000000>; /* prefetchable memory */
> 
> You are on the right track here, but the format of the child-address
> portion of the above ranges property is incorrect.  Since the child
> address space is the PCI address space, the child-address portion
> needs to be 3 cells.  It's not a linear address but rather a triple.
> The first cell identifies the address type (config, I/O, memory..)
> and the second and third cells are offsets within that subspace.
> The second and third cells will typically be 0.  The PCI binding has
> details.

Okay, I'll need to read up some more.

Thanks,
Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120613/5013e334/attachment-0001.sig>

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-13  8:19                                     ` Thierry Reding
  (?)
@ 2012-06-13  8:36                                         ` Mitch Bradley
  -1 siblings, 0 replies; 249+ messages in thread
From: Mitch Bradley @ 2012-06-13  8:36 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Stephen Warren, Russell King, linux-pci-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Jesse Barnes, Colin Cross, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On 6/12/2012 10:19 PM, Thierry Reding wrote:
> On Tue, Jun 12, 2012 at 10:05:35PM -1000, Mitch Bradley wrote:
>> On 6/12/2012 9:52 PM, Thierry Reding wrote:
>>> I think the configuration spaces and downstream I/O ranges need to be in the
>>> pcie-controller's reg property because they are remapped and used by the
>>> controller driver, not by the individual ports.
>>>
>>> That's probably not really necessary but rather a result of how the driver
>>> was written. Perhaps the driver should handle them differently instead,
>>> listing the regions in the ranges property of the parent and listing the
>>> corresponding partitions in the ranges properties of the pci child nodes.
>>>
>>> Like in the following, where the ranges property of the ports partition the
>>> ranges passed from the parent evenly:
>>>
>>> 	pcie-controller {
>>> 		compatible = "nvidia,tegra20-pcie";
>>> 		reg =<0x80003000 0x00000800   /* PADS registers */
>>> 		       0x80003800 0x00000200>; /* AFI registers */
>>> 		interrupts =<0 98 0x04   /* controller interrupt */
>>> 			      0 99 0x04>; /* MSI interrupt */
>>> 		status = "disabled";
>>>
>>> 		ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
>>> 			  0x80004000 0x80004000 0x00100000   /* configuration space */
>>> 			  0x80104000 0x80100000 0x00100000   /* extended configuration space */
>>> 			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
>>> 			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
>>> 			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
>>>
>>> 		#address-cells =<1>;
>>> 		#size-cells =<1>;
>>>
>>> 		pci@80000000 {
>>> 			reg =<0x80000000 0x00001000>;
>>> 			status = "disabled";
>>>
>>> 			#address-cells =<3>;
>>> 			#size-cells =<2>;
>>>
>>> 			ranges =<0x80400000 0x80400000 0x00008000   /* I/O */
>>> 				  0x90000000 0x90000000 0x08000000   /* non-prefetchable memory */
>>> 				  0xa0000000 0xa0000000 0x08000000>; /* prefetchable memory */
>>
>> You are on the right track here, but the format of the child-address
>> portion of the above ranges property is incorrect.  Since the child
>> address space is the PCI address space, the child-address portion
>> needs to be 3 cells.  It's not a linear address but rather a triple.
>> The first cell identifies the address type (config, I/O, memory..)
>> and the second and third cells are offsets within that subspace.
>> The second and third cells will typically be 0.  The PCI binding has
>> details.

Also, the size field in ranges is specified according to the child 
address space, so there must be 2 size cells in the ranges at this 
level.  Each ranges entry at this level is:

<child_address_space, child_address_high, child_address_low, 
parent_address, child_size_high, child_size_low>

The above should be:

			ranges =<0x81000000 0 0  0x80400000  0 0x00008000   /* I/O */
				 0x82000000 0 0  0x90000000  0 0x08000000   /* non-prefetchable memory */
				 0xc2000000 0 0  0xa0000000  0 0x08000000>; /* prefetchable memory */


>>
>
> Okay, I'll need to read up some more.
>
> Thanks,
> Thierry

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-13  8:36                                         ` Mitch Bradley
  0 siblings, 0 replies; 249+ messages in thread
From: Mitch Bradley @ 2012-06-13  8:36 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Stephen Warren, Russell King, linux-pci, devicetree-discuss,
	Rob Herring, Jesse Barnes, Colin Cross, linux-tegra,
	linux-arm-kernel

On 6/12/2012 10:19 PM, Thierry Reding wrote:
> On Tue, Jun 12, 2012 at 10:05:35PM -1000, Mitch Bradley wrote:
>> On 6/12/2012 9:52 PM, Thierry Reding wrote:
>>> I think the configuration spaces and downstream I/O ranges need to be in the
>>> pcie-controller's reg property because they are remapped and used by the
>>> controller driver, not by the individual ports.
>>>
>>> That's probably not really necessary but rather a result of how the driver
>>> was written. Perhaps the driver should handle them differently instead,
>>> listing the regions in the ranges property of the parent and listing the
>>> corresponding partitions in the ranges properties of the pci child nodes.
>>>
>>> Like in the following, where the ranges property of the ports partition the
>>> ranges passed from the parent evenly:
>>>
>>> 	pcie-controller {
>>> 		compatible = "nvidia,tegra20-pcie";
>>> 		reg =<0x80003000 0x00000800   /* PADS registers */
>>> 		       0x80003800 0x00000200>; /* AFI registers */
>>> 		interrupts =<0 98 0x04   /* controller interrupt */
>>> 			      0 99 0x04>; /* MSI interrupt */
>>> 		status = "disabled";
>>>
>>> 		ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
>>> 			  0x80004000 0x80004000 0x00100000   /* configuration space */
>>> 			  0x80104000 0x80100000 0x00100000   /* extended configuration space */
>>> 			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
>>> 			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
>>> 			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
>>>
>>> 		#address-cells =<1>;
>>> 		#size-cells =<1>;
>>>
>>> 		pci@80000000 {
>>> 			reg =<0x80000000 0x00001000>;
>>> 			status = "disabled";
>>>
>>> 			#address-cells =<3>;
>>> 			#size-cells =<2>;
>>>
>>> 			ranges =<0x80400000 0x80400000 0x00008000   /* I/O */
>>> 				  0x90000000 0x90000000 0x08000000   /* non-prefetchable memory */
>>> 				  0xa0000000 0xa0000000 0x08000000>; /* prefetchable memory */
>>
>> You are on the right track here, but the format of the child-address
>> portion of the above ranges property is incorrect.  Since the child
>> address space is the PCI address space, the child-address portion
>> needs to be 3 cells.  It's not a linear address but rather a triple.
>> The first cell identifies the address type (config, I/O, memory..)
>> and the second and third cells are offsets within that subspace.
>> The second and third cells will typically be 0.  The PCI binding has
>> details.

Also, the size field in ranges is specified according to the child 
address space, so there must be 2 size cells in the ranges at this 
level.  Each ranges entry at this level is:

<child_address_space, child_address_high, child_address_low, 
parent_address, child_size_high, child_size_low>

The above should be:

			ranges =<0x81000000 0 0  0x80400000  0 0x00008000   /* I/O */
				 0x82000000 0 0  0x90000000  0 0x08000000   /* non-prefetchable memory */
				 0xc2000000 0 0  0xa0000000  0 0x08000000>; /* prefetchable memory */


>>
>
> Okay, I'll need to read up some more.
>
> Thanks,
> Thierry

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-13  8:36                                         ` Mitch Bradley
  0 siblings, 0 replies; 249+ messages in thread
From: Mitch Bradley @ 2012-06-13  8:36 UTC (permalink / raw)
  To: linux-arm-kernel

On 6/12/2012 10:19 PM, Thierry Reding wrote:
> On Tue, Jun 12, 2012 at 10:05:35PM -1000, Mitch Bradley wrote:
>> On 6/12/2012 9:52 PM, Thierry Reding wrote:
>>> I think the configuration spaces and downstream I/O ranges need to be in the
>>> pcie-controller's reg property because they are remapped and used by the
>>> controller driver, not by the individual ports.
>>>
>>> That's probably not really necessary but rather a result of how the driver
>>> was written. Perhaps the driver should handle them differently instead,
>>> listing the regions in the ranges property of the parent and listing the
>>> corresponding partitions in the ranges properties of the pci child nodes.
>>>
>>> Like in the following, where the ranges property of the ports partition the
>>> ranges passed from the parent evenly:
>>>
>>> 	pcie-controller {
>>> 		compatible = "nvidia,tegra20-pcie";
>>> 		reg =<0x80003000 0x00000800   /* PADS registers */
>>> 		       0x80003800 0x00000200>; /* AFI registers */
>>> 		interrupts =<0 98 0x04   /* controller interrupt */
>>> 			      0 99 0x04>; /* MSI interrupt */
>>> 		status = "disabled";
>>>
>>> 		ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
>>> 			  0x80004000 0x80004000 0x00100000   /* configuration space */
>>> 			  0x80104000 0x80100000 0x00100000   /* extended configuration space */
>>> 			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
>>> 			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
>>> 			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
>>>
>>> 		#address-cells =<1>;
>>> 		#size-cells =<1>;
>>>
>>> 		pci at 80000000 {
>>> 			reg =<0x80000000 0x00001000>;
>>> 			status = "disabled";
>>>
>>> 			#address-cells =<3>;
>>> 			#size-cells =<2>;
>>>
>>> 			ranges =<0x80400000 0x80400000 0x00008000   /* I/O */
>>> 				  0x90000000 0x90000000 0x08000000   /* non-prefetchable memory */
>>> 				  0xa0000000 0xa0000000 0x08000000>; /* prefetchable memory */
>>
>> You are on the right track here, but the format of the child-address
>> portion of the above ranges property is incorrect.  Since the child
>> address space is the PCI address space, the child-address portion
>> needs to be 3 cells.  It's not a linear address but rather a triple.
>> The first cell identifies the address type (config, I/O, memory..)
>> and the second and third cells are offsets within that subspace.
>> The second and third cells will typically be 0.  The PCI binding has
>> details.

Also, the size field in ranges is specified according to the child 
address space, so there must be 2 size cells in the ranges at this 
level.  Each ranges entry at this level is:

<child_address_space, child_address_high, child_address_low, 
parent_address, child_size_high, child_size_low>

The above should be:

			ranges =<0x81000000 0 0  0x80400000  0 0x00008000   /* I/O */
				 0x82000000 0 0  0x90000000  0 0x08000000   /* non-prefetchable memory */
				 0xc2000000 0 0  0xa0000000  0 0x08000000>; /* prefetchable memory */


>>
>
> Okay, I'll need to read up some more.
>
> Thanks,
> Thierry

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-13  8:36                                         ` Mitch Bradley
@ 2012-06-13  8:42                                           ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-13  8:42 UTC (permalink / raw)
  To: Mitch Bradley
  Cc: Stephen Warren, Russell King, linux-pci, devicetree-discuss,
	Rob Herring, Jesse Barnes, Colin Cross, linux-tegra,
	linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 3285 bytes --]

On Tue, Jun 12, 2012 at 10:36:55PM -1000, Mitch Bradley wrote:
> On 6/12/2012 10:19 PM, Thierry Reding wrote:
> >On Tue, Jun 12, 2012 at 10:05:35PM -1000, Mitch Bradley wrote:
> >>On 6/12/2012 9:52 PM, Thierry Reding wrote:
> >>>I think the configuration spaces and downstream I/O ranges need to be in the
> >>>pcie-controller's reg property because they are remapped and used by the
> >>>controller driver, not by the individual ports.
> >>>
> >>>That's probably not really necessary but rather a result of how the driver
> >>>was written. Perhaps the driver should handle them differently instead,
> >>>listing the regions in the ranges property of the parent and listing the
> >>>corresponding partitions in the ranges properties of the pci child nodes.
> >>>
> >>>Like in the following, where the ranges property of the ports partition the
> >>>ranges passed from the parent evenly:
> >>>
> >>>	pcie-controller {
> >>>		compatible = "nvidia,tegra20-pcie";
> >>>		reg =<0x80003000 0x00000800   /* PADS registers */
> >>>		       0x80003800 0x00000200>; /* AFI registers */
> >>>		interrupts =<0 98 0x04   /* controller interrupt */
> >>>			      0 99 0x04>; /* MSI interrupt */
> >>>		status = "disabled";
> >>>
> >>>		ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
> >>>			  0x80004000 0x80004000 0x00100000   /* configuration space */
> >>>			  0x80104000 0x80100000 0x00100000   /* extended configuration space */
> >>>			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
> >>>			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
> >>>			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
> >>>
> >>>		#address-cells =<1>;
> >>>		#size-cells =<1>;
> >>>
> >>>		pci@80000000 {
> >>>			reg =<0x80000000 0x00001000>;
> >>>			status = "disabled";
> >>>
> >>>			#address-cells =<3>;
> >>>			#size-cells =<2>;
> >>>
> >>>			ranges =<0x80400000 0x80400000 0x00008000   /* I/O */
> >>>				  0x90000000 0x90000000 0x08000000   /* non-prefetchable memory */
> >>>				  0xa0000000 0xa0000000 0x08000000>; /* prefetchable memory */
> >>
> >>You are on the right track here, but the format of the child-address
> >>portion of the above ranges property is incorrect.  Since the child
> >>address space is the PCI address space, the child-address portion
> >>needs to be 3 cells.  It's not a linear address but rather a triple.
> >>The first cell identifies the address type (config, I/O, memory..)
> >>and the second and third cells are offsets within that subspace.
> >>The second and third cells will typically be 0.  The PCI binding has
> >>details.
> 
> Also, the size field in ranges is specified according to the child
> address space, so there must be 2 size cells in the ranges at this
> level.  Each ranges entry at this level is:
> 
> <child_address_space, child_address_high, child_address_low,
> parent_address, child_size_high, child_size_low>
> 
> The above should be:
> 
> 			ranges =<0x81000000 0 0  0x80400000  0 0x00008000   /* I/O */
> 				 0x82000000 0 0  0x90000000  0 0x08000000   /* non-prefetchable memory */
> 				 0xc2000000 0 0  0xa0000000  0 0x08000000>; /* prefetchable memory */

Okay, I think I'm beginning to understand. Thanks.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-13  8:42                                           ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-13  8:42 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jun 12, 2012 at 10:36:55PM -1000, Mitch Bradley wrote:
> On 6/12/2012 10:19 PM, Thierry Reding wrote:
> >On Tue, Jun 12, 2012 at 10:05:35PM -1000, Mitch Bradley wrote:
> >>On 6/12/2012 9:52 PM, Thierry Reding wrote:
> >>>I think the configuration spaces and downstream I/O ranges need to be in the
> >>>pcie-controller's reg property because they are remapped and used by the
> >>>controller driver, not by the individual ports.
> >>>
> >>>That's probably not really necessary but rather a result of how the driver
> >>>was written. Perhaps the driver should handle them differently instead,
> >>>listing the regions in the ranges property of the parent and listing the
> >>>corresponding partitions in the ranges properties of the pci child nodes.
> >>>
> >>>Like in the following, where the ranges property of the ports partition the
> >>>ranges passed from the parent evenly:
> >>>
> >>>	pcie-controller {
> >>>		compatible = "nvidia,tegra20-pcie";
> >>>		reg =<0x80003000 0x00000800   /* PADS registers */
> >>>		       0x80003800 0x00000200>; /* AFI registers */
> >>>		interrupts =<0 98 0x04   /* controller interrupt */
> >>>			      0 99 0x04>; /* MSI interrupt */
> >>>		status = "disabled";
> >>>
> >>>		ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
> >>>			  0x80004000 0x80004000 0x00100000   /* configuration space */
> >>>			  0x80104000 0x80100000 0x00100000   /* extended configuration space */
> >>>			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
> >>>			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
> >>>			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
> >>>
> >>>		#address-cells =<1>;
> >>>		#size-cells =<1>;
> >>>
> >>>		pci at 80000000 {
> >>>			reg =<0x80000000 0x00001000>;
> >>>			status = "disabled";
> >>>
> >>>			#address-cells =<3>;
> >>>			#size-cells =<2>;
> >>>
> >>>			ranges =<0x80400000 0x80400000 0x00008000   /* I/O */
> >>>				  0x90000000 0x90000000 0x08000000   /* non-prefetchable memory */
> >>>				  0xa0000000 0xa0000000 0x08000000>; /* prefetchable memory */
> >>
> >>You are on the right track here, but the format of the child-address
> >>portion of the above ranges property is incorrect.  Since the child
> >>address space is the PCI address space, the child-address portion
> >>needs to be 3 cells.  It's not a linear address but rather a triple.
> >>The first cell identifies the address type (config, I/O, memory..)
> >>and the second and third cells are offsets within that subspace.
> >>The second and third cells will typically be 0.  The PCI binding has
> >>details.
> 
> Also, the size field in ranges is specified according to the child
> address space, so there must be 2 size cells in the ranges at this
> level.  Each ranges entry at this level is:
> 
> <child_address_space, child_address_high, child_address_low,
> parent_address, child_size_high, child_size_low>
> 
> The above should be:
> 
> 			ranges =<0x81000000 0 0  0x80400000  0 0x00008000   /* I/O */
> 				 0x82000000 0 0  0x90000000  0 0x08000000   /* non-prefetchable memory */
> 				 0xc2000000 0 0  0xa0000000  0 0x08000000>; /* prefetchable memory */

Okay, I think I'm beginning to understand. Thanks.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120613/2a5d3c12/attachment.sig>

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-13  6:34                     ` Thierry Reding
  (?)
@ 2012-06-13 16:20                         ` Stephen Warren
  -1 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-13 16:20 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Russell King, linux-pci-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Jesse Barnes, Colin Cross, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On 06/13/2012 12:34 AM, Thierry Reding wrote:
> * Stephen Warren wrote:
...
>> I think you also need a property to specify the exact port
>> layout; the Tegra20 controller supports:
>> 
>> 1 x4 port 2 x2 ports (you can choose to use only 1 of these I
>> assume)
>> 
>> So just because only 1 of the ports is enabled, doesn't imply
>> it's x4; it could still be x2.
>> 
>> Tegra30 has more options.
> 
> Both the upstream and downstream drivers currently hard-code this
> to dual and 411 (I assume that means 1x4, 2x1?) configurations for
> Tegra20 and Tegra30 respectively. Unfortunately the register
> AFI_PCIE_CONFIG isn't documented on Tegra20 at all and for Tegra30
> lists only the valid configurations (see 28.4.1.5 PCIe CONFIG) but
> not the corresponding encodings.
> 
> Maybe a good name for the new property would be "num-lanes". I also
> wonder if this property would be better off in the parent node,
> which would make it easier to check for valid configurations.
> Otherwise the code would have to collect the settings of all the
> ports and check if the combination is valid. Then again, having
> num-lanes in the parent with one cell for each controller isn't
> very nice if each controller can be individually disabled.

Indeed, since the register that controls this is in the main register
set rather than the per-port register set, it does seem like a good
idea to put the property in the main node, not the per-port node.

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-13 16:20                         ` Stephen Warren
  0 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-13 16:20 UTC (permalink / raw)
  To: Thierry Reding
  Cc: linux-tegra, Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson

On 06/13/2012 12:34 AM, Thierry Reding wrote:
> * Stephen Warren wrote:
...
>> I think you also need a property to specify the exact port
>> layout; the Tegra20 controller supports:
>> 
>> 1 x4 port 2 x2 ports (you can choose to use only 1 of these I
>> assume)
>> 
>> So just because only 1 of the ports is enabled, doesn't imply
>> it's x4; it could still be x2.
>> 
>> Tegra30 has more options.
> 
> Both the upstream and downstream drivers currently hard-code this
> to dual and 411 (I assume that means 1x4, 2x1?) configurations for
> Tegra20 and Tegra30 respectively. Unfortunately the register
> AFI_PCIE_CONFIG isn't documented on Tegra20 at all and for Tegra30
> lists only the valid configurations (see 28.4.1.5 PCIe CONFIG) but
> not the corresponding encodings.
> 
> Maybe a good name for the new property would be "num-lanes". I also
> wonder if this property would be better off in the parent node,
> which would make it easier to check for valid configurations.
> Otherwise the code would have to collect the settings of all the
> ports and check if the combination is valid. Then again, having
> num-lanes in the parent with one cell for each controller isn't
> very nice if each controller can be individually disabled.

Indeed, since the register that controls this is in the main register
set rather than the per-port register set, it does seem like a good
idea to put the property in the main node, not the per-port node.

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-13 16:20                         ` Stephen Warren
  0 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-13 16:20 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/13/2012 12:34 AM, Thierry Reding wrote:
> * Stephen Warren wrote:
...
>> I think you also need a property to specify the exact port
>> layout; the Tegra20 controller supports:
>> 
>> 1 x4 port 2 x2 ports (you can choose to use only 1 of these I
>> assume)
>> 
>> So just because only 1 of the ports is enabled, doesn't imply
>> it's x4; it could still be x2.
>> 
>> Tegra30 has more options.
> 
> Both the upstream and downstream drivers currently hard-code this
> to dual and 411 (I assume that means 1x4, 2x1?) configurations for
> Tegra20 and Tegra30 respectively. Unfortunately the register
> AFI_PCIE_CONFIG isn't documented on Tegra20 at all and for Tegra30
> lists only the valid configurations (see 28.4.1.5 PCIe CONFIG) but
> not the corresponding encodings.
> 
> Maybe a good name for the new property would be "num-lanes". I also
> wonder if this property would be better off in the parent node,
> which would make it easier to check for valid configurations.
> Otherwise the code would have to collect the settings of all the
> ports and check if the combination is valid. Then again, having
> num-lanes in the parent with one cell for each controller isn't
> very nice if each controller can be individually disabled.

Indeed, since the register that controls this is in the main register
set rather than the per-port register set, it does seem like a good
idea to put the property in the main node, not the per-port node.

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-13  6:34                     ` Thierry Reding
@ 2012-06-13 17:03                       ` Stephen Warren
  -1 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-13 17:03 UTC (permalink / raw)
  To: Thierry Reding
  Cc: linux-tegra, Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson

On 06/13/2012 12:34 AM, Thierry Reding wrote:
...
> One other thing: in addition to the device tree binding, this will
> all have to be represented in the platform data as well to support
> the legacy board definitions currently in the tree. But instead of
> adding all of these changes to the patch that converts the code to
> a driver, I'm thinking it might be better to split these additions
> off into one or more separate patches. Do you have any objections?

So long as git bisect isn't broken for build- or run-time, that's just
fine.

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-13 17:03                       ` Stephen Warren
  0 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-13 17:03 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/13/2012 12:34 AM, Thierry Reding wrote:
...
> One other thing: in addition to the device tree binding, this will
> all have to be represented in the platform data as well to support
> the legacy board definitions currently in the tree. But instead of
> adding all of these changes to the patch that converts the code to
> a driver, I'm thinking it might be better to split these additions
> off into one or more separate patches. Do you have any objections?

So long as git bisect isn't broken for build- or run-time, that's just
fine.

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-13  7:52                             ` Thierry Reding
  (?)
@ 2012-06-13 20:21                                 ` Arnd Bergmann
  -1 siblings, 0 replies; 249+ messages in thread
From: Arnd Bergmann @ 2012-06-13 20:21 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: Thierry Reding, Mitch Bradley, Russell King, Stephen Warren,
	linux-pci-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Jesse Barnes,
	Rob Herring, Colin Cross, linux-tegra-u79uwXL29TY76Z2rM5mHXA

On Wednesday 13 June 2012, Thierry Reding wrote:
>                 pci@80000000 {
>                         reg = <0x80000000 0x00001000>;
>                         status = "disabled";
> 
>                         #address-cells = <3>;
>                         #size-cells = <2>;
> 
>                         ranges = <0x80400000 0x80400000 0x00008000   /* I/O */
>                                   0x90000000 0x90000000 0x08000000   /* non-prefetchable memory */
>                                   0xa0000000 0xa0000000 0x08000000>; /* prefetchable memory */
> 
>                         nvidia,ctrl-offset = <0x0>;
>                         nvidia,num-lanes = <2>;
>                 };
> 

I believe you will need an "interrupt-map" property here, to map the host
interrupts to the INTA-INTD lines of the attached devices.

I'm not sure whether we want to have a device_type="pciex" property here.
powerpc and sparc seem to use that information, to distinguish a pcie
bus from pci or cardbus.

	Arnd

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-13 20:21                                 ` Arnd Bergmann
  0 siblings, 0 replies; 249+ messages in thread
From: Arnd Bergmann @ 2012-06-13 20:21 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Thierry Reding, Mitch Bradley, Russell King, Stephen Warren,
	linux-pci, devicetree-discuss, Jesse Barnes, Rob Herring,
	Colin Cross, linux-tegra

On Wednesday 13 June 2012, Thierry Reding wrote:
>                 pci@80000000 {
>                         reg = <0x80000000 0x00001000>;
>                         status = "disabled";
> 
>                         #address-cells = <3>;
>                         #size-cells = <2>;
> 
>                         ranges = <0x80400000 0x80400000 0x00008000   /* I/O */
>                                   0x90000000 0x90000000 0x08000000   /* non-prefetchable memory */
>                                   0xa0000000 0xa0000000 0x08000000>; /* prefetchable memory */
> 
>                         nvidia,ctrl-offset = <0x0>;
>                         nvidia,num-lanes = <2>;
>                 };
> 

I believe you will need an "interrupt-map" property here, to map the host
interrupts to the INTA-INTD lines of the attached devices.

I'm not sure whether we want to have a device_type="pciex" property here.
powerpc and sparc seem to use that information, to distinguish a pcie
bus from pci or cardbus.

	Arnd

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-13 20:21                                 ` Arnd Bergmann
  0 siblings, 0 replies; 249+ messages in thread
From: Arnd Bergmann @ 2012-06-13 20:21 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 13 June 2012, Thierry Reding wrote:
>                 pci at 80000000 {
>                         reg = <0x80000000 0x00001000>;
>                         status = "disabled";
> 
>                         #address-cells = <3>;
>                         #size-cells = <2>;
> 
>                         ranges = <0x80400000 0x80400000 0x00008000   /* I/O */
>                                   0x90000000 0x90000000 0x08000000   /* non-prefetchable memory */
>                                   0xa0000000 0xa0000000 0x08000000>; /* prefetchable memory */
> 
>                         nvidia,ctrl-offset = <0x0>;
>                         nvidia,num-lanes = <2>;
>                 };
> 

I believe you will need an "interrupt-map" property here, to map the host
interrupts to the INTA-INTD lines of the attached devices.

I'm not sure whether we want to have a device_type="pciex" property here.
powerpc and sparc seem to use that information, to distinguish a pcie
bus from pci or cardbus.

	Arnd

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-13 20:21                                 ` Arnd Bergmann
  (?)
@ 2012-06-14  8:37                                     ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-14  8:37 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Mitch Bradley,
	Russell King, Stephen Warren, linux-pci-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Jesse Barnes,
	Rob Herring, Colin Cross, linux-tegra-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: text/plain, Size: 1367 bytes --]

On Wed, Jun 13, 2012 at 08:21:08PM +0000, Arnd Bergmann wrote:
> On Wednesday 13 June 2012, Thierry Reding wrote:
> >                 pci@80000000 {
> >                         reg = <0x80000000 0x00001000>;
> >                         status = "disabled";
> > 
> >                         #address-cells = <3>;
> >                         #size-cells = <2>;
> > 
> >                         ranges = <0x80400000 0x80400000 0x00008000   /* I/O */
> >                                   0x90000000 0x90000000 0x08000000   /* non-prefetchable memory */
> >                                   0xa0000000 0xa0000000 0x08000000>; /* prefetchable memory */
> > 
> >                         nvidia,ctrl-offset = <0x0>;
> >                         nvidia,num-lanes = <2>;
> >                 };
> > 
> 
> I believe you will need an "interrupt-map" property here, to map the host
> interrupts to the INTA-INTD lines of the attached devices.

Legacy interrupts are something I cannot test at all because I have no
hardware that supports them.

> I'm not sure whether we want to have a device_type="pciex" property here.
> powerpc and sparc seem to use that information, to distinguish a pcie
> bus from pci or cardbus.

That'd be rather useless information given that the Tegra is unlikely to
support either PCI or CardBus at some point.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-14  8:37                                     ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-14  8:37 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel, Mitch Bradley, Russell King, Stephen Warren,
	linux-pci, devicetree-discuss, Jesse Barnes, Rob Herring,
	Colin Cross, linux-tegra

[-- Attachment #1: Type: text/plain, Size: 1367 bytes --]

On Wed, Jun 13, 2012 at 08:21:08PM +0000, Arnd Bergmann wrote:
> On Wednesday 13 June 2012, Thierry Reding wrote:
> >                 pci@80000000 {
> >                         reg = <0x80000000 0x00001000>;
> >                         status = "disabled";
> > 
> >                         #address-cells = <3>;
> >                         #size-cells = <2>;
> > 
> >                         ranges = <0x80400000 0x80400000 0x00008000   /* I/O */
> >                                   0x90000000 0x90000000 0x08000000   /* non-prefetchable memory */
> >                                   0xa0000000 0xa0000000 0x08000000>; /* prefetchable memory */
> > 
> >                         nvidia,ctrl-offset = <0x0>;
> >                         nvidia,num-lanes = <2>;
> >                 };
> > 
> 
> I believe you will need an "interrupt-map" property here, to map the host
> interrupts to the INTA-INTD lines of the attached devices.

Legacy interrupts are something I cannot test at all because I have no
hardware that supports them.

> I'm not sure whether we want to have a device_type="pciex" property here.
> powerpc and sparc seem to use that information, to distinguish a pcie
> bus from pci or cardbus.

That'd be rather useless information given that the Tegra is unlikely to
support either PCI or CardBus at some point.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-14  8:37                                     ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-14  8:37 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jun 13, 2012 at 08:21:08PM +0000, Arnd Bergmann wrote:
> On Wednesday 13 June 2012, Thierry Reding wrote:
> >                 pci at 80000000 {
> >                         reg = <0x80000000 0x00001000>;
> >                         status = "disabled";
> > 
> >                         #address-cells = <3>;
> >                         #size-cells = <2>;
> > 
> >                         ranges = <0x80400000 0x80400000 0x00008000   /* I/O */
> >                                   0x90000000 0x90000000 0x08000000   /* non-prefetchable memory */
> >                                   0xa0000000 0xa0000000 0x08000000>; /* prefetchable memory */
> > 
> >                         nvidia,ctrl-offset = <0x0>;
> >                         nvidia,num-lanes = <2>;
> >                 };
> > 
> 
> I believe you will need an "interrupt-map" property here, to map the host
> interrupts to the INTA-INTD lines of the attached devices.

Legacy interrupts are something I cannot test at all because I have no
hardware that supports them.

> I'm not sure whether we want to have a device_type="pciex" property here.
> powerpc and sparc seem to use that information, to distinguish a pcie
> bus from pci or cardbus.

That'd be rather useless information given that the Tegra is unlikely to
support either PCI or CardBus at some point.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120614/b90536c5/attachment-0001.sig>

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-13  8:36                                         ` Mitch Bradley
  (?)
@ 2012-06-14  9:19                                             ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-14  9:19 UTC (permalink / raw)
  To: Mitch Bradley
  Cc: Stephen Warren, Russell King, linux-pci-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Jesse Barnes, Colin Cross, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

[-- Attachment #1: Type: text/plain, Size: 7079 bytes --]

On Tue, Jun 12, 2012 at 10:36:55PM -1000, Mitch Bradley wrote:
> On 6/12/2012 10:19 PM, Thierry Reding wrote:
> >On Tue, Jun 12, 2012 at 10:05:35PM -1000, Mitch Bradley wrote:
> >>On 6/12/2012 9:52 PM, Thierry Reding wrote:
> >>>I think the configuration spaces and downstream I/O ranges need to be in the
> >>>pcie-controller's reg property because they are remapped and used by the
> >>>controller driver, not by the individual ports.
> >>>
> >>>That's probably not really necessary but rather a result of how the driver
> >>>was written. Perhaps the driver should handle them differently instead,
> >>>listing the regions in the ranges property of the parent and listing the
> >>>corresponding partitions in the ranges properties of the pci child nodes.
> >>>
> >>>Like in the following, where the ranges property of the ports partition the
> >>>ranges passed from the parent evenly:
> >>>
> >>>	pcie-controller {
> >>>		compatible = "nvidia,tegra20-pcie";
> >>>		reg =<0x80003000 0x00000800   /* PADS registers */
> >>>		       0x80003800 0x00000200>; /* AFI registers */
> >>>		interrupts =<0 98 0x04   /* controller interrupt */
> >>>			      0 99 0x04>; /* MSI interrupt */
> >>>		status = "disabled";
> >>>
> >>>		ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
> >>>			  0x80004000 0x80004000 0x00100000   /* configuration space */
> >>>			  0x80104000 0x80100000 0x00100000   /* extended configuration space */
> >>>			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
> >>>			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
> >>>			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
> >>>
> >>>		#address-cells =<1>;
> >>>		#size-cells =<1>;
> >>>
> >>>		pci@80000000 {
> >>>			reg =<0x80000000 0x00001000>;
> >>>			status = "disabled";
> >>>
> >>>			#address-cells =<3>;
> >>>			#size-cells =<2>;
> >>>
> >>>			ranges =<0x80400000 0x80400000 0x00008000   /* I/O */
> >>>				  0x90000000 0x90000000 0x08000000   /* non-prefetchable memory */
> >>>				  0xa0000000 0xa0000000 0x08000000>; /* prefetchable memory */
> >>
> >>You are on the right track here, but the format of the child-address
> >>portion of the above ranges property is incorrect.  Since the child
> >>address space is the PCI address space, the child-address portion
> >>needs to be 3 cells.  It's not a linear address but rather a triple.
> >>The first cell identifies the address type (config, I/O, memory..)
> >>and the second and third cells are offsets within that subspace.
> >>The second and third cells will typically be 0.  The PCI binding has
> >>details.
> 
> Also, the size field in ranges is specified according to the child
> address space, so there must be 2 size cells in the ranges at this
> level.  Each ranges entry at this level is:
> 
> <child_address_space, child_address_high, child_address_low,
> parent_address, child_size_high, child_size_low>
> 
> The above should be:
> 
> 			ranges =<0x81000000 0 0  0x80400000  0 0x00008000   /* I/O */
> 				 0x82000000 0 0  0x90000000  0 0x08000000   /* non-prefetchable memory */
> 				 0xc2000000 0 0  0xa0000000  0 0x08000000>; /* prefetchable memory */
> 
> 

Okay, so the new pcie-controller node looks like this:

	pcie-controller {
		compatible = "nvidia,tegra20-pcie", "simple-bus";
		reg = <0x80003000 0x00000800   /* PADS registers */
		       0x80003800 0x00000200   /* AFI registers */
		       0x80004000 0x00100000   /* configuration space */
		       0x80104000 0x00100000>; /* extended configuration space */
		interrupts = <0 98 0x04   /* controller interrupt */
		              0 99 0x04>; /* MSI interrupt */
		status = "disabled";

		ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */
			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */

		#address-cells = <1>;
		#size-cells = <1>;

		pci@80000000 {
			compatible = "nvidia,tegra20-pcie-port";
			reg = <0x80000000 0x00001000>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;

			ranges = <0x81000000 0 0 0x80400000 0 0x00008000   /* I/O */
				  0x82000000 0 0 0x90000000 0 0x08000000   /* non-prefetchable memory */
				  0xc2000000 0 0 0xa0000000 0 0x08000000>; /* prefetchable memory */

			nvidia,ctrl-offset = <0x110>;
			nvidia,num-lanes = <2>;
		};

		pci@80001000 {
			compatible = "nvidia,tegra20-pcie-port";
			reg = <0x80001000 0x00001000>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;

			ranges = <0x81000000 0 0 0x80408000 0 0x00008000   /* I/O */
				  0x82000000 0 0 0x98000000 0 0x08000000   /* non-prefetchable memory */
				  0xc2000000 0 0 0xa8000000 0 0x08000000>; /* prefetchable memory */

			nvidia,ctrl-offset = <0x118>;
			nvidia,num-lanes = <2>;
		};
	};

While looking into some more code, trying to figure out how to hook this all
up with the device tree I ran into a problem. I need to actually create a
'struct device' for each of the ports, so I added the "simple-bus" to the
pcie-controller's "compatible" property. Furthermore, each PCI root port now
becomes a platform_device, which are supported by a new tegra-pcie-port
driver. I'm not sure if "port" is very common in PCI speek, so something like
tegra-pcie-bridge (compatible = "nvidia,tegra20-pcie-bridge") may be more
appropriate?

Using real platform devices is not only more straightforward (each bridge is
after all a separate parent for the PCI endpoints) but it also has the
advantage that the bridges are properly hooked up with the device tree. If I
read the code correctly, passing the 'struct device' to pci_scan_root_bus()
will allow the PCI core code to set up the proper pointers that allow busses
and endpoints below each bridge to be matched to the corresponding DT nodes.

However this causes other problems with the initialization of the PCIe
controller. The translations cannot be setup and the controller shouldn't be
enabled until after all the ports have been probed because it isn't clear
which of them are really active and which are not. For the DT case this can
probably be done by parsing the device tree and collecting the information,
but for the non-DT case this will probably be more difficult.

To solve this for both cases I could probably use device_for_each_child() and
check that all children have been properly probed before setting up the
translations and enabling the controller. That leaves the question of how to
verify that a device has been correctly probed. The easiest would probably be
to check if dev_get_drvdata() != NULL, but I'm still trying to decide whether
that's too ugly or not. I don't know of any other way to determine that
probing was successful. In addition it may still be useful to continue if one
of the devices failed to initialize (the link on only one of two enabled
ports is up).

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-14  9:19                                             ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-14  9:19 UTC (permalink / raw)
  To: Mitch Bradley
  Cc: Stephen Warren, Russell King, linux-pci, devicetree-discuss,
	Rob Herring, Jesse Barnes, Colin Cross, linux-tegra,
	linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 7079 bytes --]

On Tue, Jun 12, 2012 at 10:36:55PM -1000, Mitch Bradley wrote:
> On 6/12/2012 10:19 PM, Thierry Reding wrote:
> >On Tue, Jun 12, 2012 at 10:05:35PM -1000, Mitch Bradley wrote:
> >>On 6/12/2012 9:52 PM, Thierry Reding wrote:
> >>>I think the configuration spaces and downstream I/O ranges need to be in the
> >>>pcie-controller's reg property because they are remapped and used by the
> >>>controller driver, not by the individual ports.
> >>>
> >>>That's probably not really necessary but rather a result of how the driver
> >>>was written. Perhaps the driver should handle them differently instead,
> >>>listing the regions in the ranges property of the parent and listing the
> >>>corresponding partitions in the ranges properties of the pci child nodes.
> >>>
> >>>Like in the following, where the ranges property of the ports partition the
> >>>ranges passed from the parent evenly:
> >>>
> >>>	pcie-controller {
> >>>		compatible = "nvidia,tegra20-pcie";
> >>>		reg =<0x80003000 0x00000800   /* PADS registers */
> >>>		       0x80003800 0x00000200>; /* AFI registers */
> >>>		interrupts =<0 98 0x04   /* controller interrupt */
> >>>			      0 99 0x04>; /* MSI interrupt */
> >>>		status = "disabled";
> >>>
> >>>		ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
> >>>			  0x80004000 0x80004000 0x00100000   /* configuration space */
> >>>			  0x80104000 0x80100000 0x00100000   /* extended configuration space */
> >>>			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
> >>>			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
> >>>			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
> >>>
> >>>		#address-cells =<1>;
> >>>		#size-cells =<1>;
> >>>
> >>>		pci@80000000 {
> >>>			reg =<0x80000000 0x00001000>;
> >>>			status = "disabled";
> >>>
> >>>			#address-cells =<3>;
> >>>			#size-cells =<2>;
> >>>
> >>>			ranges =<0x80400000 0x80400000 0x00008000   /* I/O */
> >>>				  0x90000000 0x90000000 0x08000000   /* non-prefetchable memory */
> >>>				  0xa0000000 0xa0000000 0x08000000>; /* prefetchable memory */
> >>
> >>You are on the right track here, but the format of the child-address
> >>portion of the above ranges property is incorrect.  Since the child
> >>address space is the PCI address space, the child-address portion
> >>needs to be 3 cells.  It's not a linear address but rather a triple.
> >>The first cell identifies the address type (config, I/O, memory..)
> >>and the second and third cells are offsets within that subspace.
> >>The second and third cells will typically be 0.  The PCI binding has
> >>details.
> 
> Also, the size field in ranges is specified according to the child
> address space, so there must be 2 size cells in the ranges at this
> level.  Each ranges entry at this level is:
> 
> <child_address_space, child_address_high, child_address_low,
> parent_address, child_size_high, child_size_low>
> 
> The above should be:
> 
> 			ranges =<0x81000000 0 0  0x80400000  0 0x00008000   /* I/O */
> 				 0x82000000 0 0  0x90000000  0 0x08000000   /* non-prefetchable memory */
> 				 0xc2000000 0 0  0xa0000000  0 0x08000000>; /* prefetchable memory */
> 
> 

Okay, so the new pcie-controller node looks like this:

	pcie-controller {
		compatible = "nvidia,tegra20-pcie", "simple-bus";
		reg = <0x80003000 0x00000800   /* PADS registers */
		       0x80003800 0x00000200   /* AFI registers */
		       0x80004000 0x00100000   /* configuration space */
		       0x80104000 0x00100000>; /* extended configuration space */
		interrupts = <0 98 0x04   /* controller interrupt */
		              0 99 0x04>; /* MSI interrupt */
		status = "disabled";

		ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */
			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */

		#address-cells = <1>;
		#size-cells = <1>;

		pci@80000000 {
			compatible = "nvidia,tegra20-pcie-port";
			reg = <0x80000000 0x00001000>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;

			ranges = <0x81000000 0 0 0x80400000 0 0x00008000   /* I/O */
				  0x82000000 0 0 0x90000000 0 0x08000000   /* non-prefetchable memory */
				  0xc2000000 0 0 0xa0000000 0 0x08000000>; /* prefetchable memory */

			nvidia,ctrl-offset = <0x110>;
			nvidia,num-lanes = <2>;
		};

		pci@80001000 {
			compatible = "nvidia,tegra20-pcie-port";
			reg = <0x80001000 0x00001000>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;

			ranges = <0x81000000 0 0 0x80408000 0 0x00008000   /* I/O */
				  0x82000000 0 0 0x98000000 0 0x08000000   /* non-prefetchable memory */
				  0xc2000000 0 0 0xa8000000 0 0x08000000>; /* prefetchable memory */

			nvidia,ctrl-offset = <0x118>;
			nvidia,num-lanes = <2>;
		};
	};

While looking into some more code, trying to figure out how to hook this all
up with the device tree I ran into a problem. I need to actually create a
'struct device' for each of the ports, so I added the "simple-bus" to the
pcie-controller's "compatible" property. Furthermore, each PCI root port now
becomes a platform_device, which are supported by a new tegra-pcie-port
driver. I'm not sure if "port" is very common in PCI speek, so something like
tegra-pcie-bridge (compatible = "nvidia,tegra20-pcie-bridge") may be more
appropriate?

Using real platform devices is not only more straightforward (each bridge is
after all a separate parent for the PCI endpoints) but it also has the
advantage that the bridges are properly hooked up with the device tree. If I
read the code correctly, passing the 'struct device' to pci_scan_root_bus()
will allow the PCI core code to set up the proper pointers that allow busses
and endpoints below each bridge to be matched to the corresponding DT nodes.

However this causes other problems with the initialization of the PCIe
controller. The translations cannot be setup and the controller shouldn't be
enabled until after all the ports have been probed because it isn't clear
which of them are really active and which are not. For the DT case this can
probably be done by parsing the device tree and collecting the information,
but for the non-DT case this will probably be more difficult.

To solve this for both cases I could probably use device_for_each_child() and
check that all children have been properly probed before setting up the
translations and enabling the controller. That leaves the question of how to
verify that a device has been correctly probed. The easiest would probably be
to check if dev_get_drvdata() != NULL, but I'm still trying to decide whether
that's too ugly or not. I don't know of any other way to determine that
probing was successful. In addition it may still be useful to continue if one
of the devices failed to initialize (the link on only one of two enabled
ports is up).

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-14  9:19                                             ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-14  9:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jun 12, 2012 at 10:36:55PM -1000, Mitch Bradley wrote:
> On 6/12/2012 10:19 PM, Thierry Reding wrote:
> >On Tue, Jun 12, 2012 at 10:05:35PM -1000, Mitch Bradley wrote:
> >>On 6/12/2012 9:52 PM, Thierry Reding wrote:
> >>>I think the configuration spaces and downstream I/O ranges need to be in the
> >>>pcie-controller's reg property because they are remapped and used by the
> >>>controller driver, not by the individual ports.
> >>>
> >>>That's probably not really necessary but rather a result of how the driver
> >>>was written. Perhaps the driver should handle them differently instead,
> >>>listing the regions in the ranges property of the parent and listing the
> >>>corresponding partitions in the ranges properties of the pci child nodes.
> >>>
> >>>Like in the following, where the ranges property of the ports partition the
> >>>ranges passed from the parent evenly:
> >>>
> >>>	pcie-controller {
> >>>		compatible = "nvidia,tegra20-pcie";
> >>>		reg =<0x80003000 0x00000800   /* PADS registers */
> >>>		       0x80003800 0x00000200>; /* AFI registers */
> >>>		interrupts =<0 98 0x04   /* controller interrupt */
> >>>			      0 99 0x04>; /* MSI interrupt */
> >>>		status = "disabled";
> >>>
> >>>		ranges =<0x80000000 0x80000000 0x00002000   /* 2 root ports */
> >>>			  0x80004000 0x80004000 0x00100000   /* configuration space */
> >>>			  0x80104000 0x80100000 0x00100000   /* extended configuration space */
> >>>			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
> >>>			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
> >>>			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
> >>>
> >>>		#address-cells =<1>;
> >>>		#size-cells =<1>;
> >>>
> >>>		pci at 80000000 {
> >>>			reg =<0x80000000 0x00001000>;
> >>>			status = "disabled";
> >>>
> >>>			#address-cells =<3>;
> >>>			#size-cells =<2>;
> >>>
> >>>			ranges =<0x80400000 0x80400000 0x00008000   /* I/O */
> >>>				  0x90000000 0x90000000 0x08000000   /* non-prefetchable memory */
> >>>				  0xa0000000 0xa0000000 0x08000000>; /* prefetchable memory */
> >>
> >>You are on the right track here, but the format of the child-address
> >>portion of the above ranges property is incorrect.  Since the child
> >>address space is the PCI address space, the child-address portion
> >>needs to be 3 cells.  It's not a linear address but rather a triple.
> >>The first cell identifies the address type (config, I/O, memory..)
> >>and the second and third cells are offsets within that subspace.
> >>The second and third cells will typically be 0.  The PCI binding has
> >>details.
> 
> Also, the size field in ranges is specified according to the child
> address space, so there must be 2 size cells in the ranges at this
> level.  Each ranges entry at this level is:
> 
> <child_address_space, child_address_high, child_address_low,
> parent_address, child_size_high, child_size_low>
> 
> The above should be:
> 
> 			ranges =<0x81000000 0 0  0x80400000  0 0x00008000   /* I/O */
> 				 0x82000000 0 0  0x90000000  0 0x08000000   /* non-prefetchable memory */
> 				 0xc2000000 0 0  0xa0000000  0 0x08000000>; /* prefetchable memory */
> 
> 

Okay, so the new pcie-controller node looks like this:

	pcie-controller {
		compatible = "nvidia,tegra20-pcie", "simple-bus";
		reg = <0x80003000 0x00000800   /* PADS registers */
		       0x80003800 0x00000200   /* AFI registers */
		       0x80004000 0x00100000   /* configuration space */
		       0x80104000 0x00100000>; /* extended configuration space */
		interrupts = <0 98 0x04   /* controller interrupt */
		              0 99 0x04>; /* MSI interrupt */
		status = "disabled";

		ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */
			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */

		#address-cells = <1>;
		#size-cells = <1>;

		pci at 80000000 {
			compatible = "nvidia,tegra20-pcie-port";
			reg = <0x80000000 0x00001000>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;

			ranges = <0x81000000 0 0 0x80400000 0 0x00008000   /* I/O */
				  0x82000000 0 0 0x90000000 0 0x08000000   /* non-prefetchable memory */
				  0xc2000000 0 0 0xa0000000 0 0x08000000>; /* prefetchable memory */

			nvidia,ctrl-offset = <0x110>;
			nvidia,num-lanes = <2>;
		};

		pci at 80001000 {
			compatible = "nvidia,tegra20-pcie-port";
			reg = <0x80001000 0x00001000>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;

			ranges = <0x81000000 0 0 0x80408000 0 0x00008000   /* I/O */
				  0x82000000 0 0 0x98000000 0 0x08000000   /* non-prefetchable memory */
				  0xc2000000 0 0 0xa8000000 0 0x08000000>; /* prefetchable memory */

			nvidia,ctrl-offset = <0x118>;
			nvidia,num-lanes = <2>;
		};
	};

While looking into some more code, trying to figure out how to hook this all
up with the device tree I ran into a problem. I need to actually create a
'struct device' for each of the ports, so I added the "simple-bus" to the
pcie-controller's "compatible" property. Furthermore, each PCI root port now
becomes a platform_device, which are supported by a new tegra-pcie-port
driver. I'm not sure if "port" is very common in PCI speek, so something like
tegra-pcie-bridge (compatible = "nvidia,tegra20-pcie-bridge") may be more
appropriate?

Using real platform devices is not only more straightforward (each bridge is
after all a separate parent for the PCI endpoints) but it also has the
advantage that the bridges are properly hooked up with the device tree. If I
read the code correctly, passing the 'struct device' to pci_scan_root_bus()
will allow the PCI core code to set up the proper pointers that allow busses
and endpoints below each bridge to be matched to the corresponding DT nodes.

However this causes other problems with the initialization of the PCIe
controller. The translations cannot be setup and the controller shouldn't be
enabled until after all the ports have been probed because it isn't clear
which of them are really active and which are not. For the DT case this can
probably be done by parsing the device tree and collecting the information,
but for the non-DT case this will probably be more difficult.

To solve this for both cases I could probably use device_for_each_child() and
check that all children have been properly probed before setting up the
translations and enabling the controller. That leaves the question of how to
verify that a device has been correctly probed. The easiest would probably be
to check if dev_get_drvdata() != NULL, but I'm still trying to decide whether
that's too ugly or not. I don't know of any other way to determine that
probing was successful. In addition it may still be useful to continue if one
of the devices failed to initialize (the link on only one of two enabled
ports is up).

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120614/69eb44a0/attachment-0001.sig>

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-14  8:37                                     ` Thierry Reding
@ 2012-06-14 10:25                                       ` Arnd Bergmann
  -1 siblings, 0 replies; 249+ messages in thread
From: Arnd Bergmann @ 2012-06-14 10:25 UTC (permalink / raw)
  To: Thierry Reding
  Cc: linux-arm-kernel, Mitch Bradley, Russell King, Stephen Warren,
	linux-pci, devicetree-discuss, Jesse Barnes, Rob Herring,
	Colin Cross, linux-tegra

On Thursday 14 June 2012, Thierry Reding wrote:
> > 
> > I believe you will need an "interrupt-map" property here, to map the host
> > interrupts to the INTA-INTD lines of the attached devices.
>
> Legacy interrupts are something I cannot test at all because I have no
> hardware that supports them.

Hmm, I thought all PCIe hardware has to support them when you do not
enable MSI. What hardware do you have then?

> > I'm not sure whether we want to have a device_type="pciex" property here.
> > powerpc and sparc seem to use that information, to distinguish a pcie
> > bus from pci or cardbus.
> 
> That'd be rather useless information given that the Tegra is unlikely to
> support either PCI or CardBus at some point.

But the generic code does not know that.

	Arnd

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-14 10:25                                       ` Arnd Bergmann
  0 siblings, 0 replies; 249+ messages in thread
From: Arnd Bergmann @ 2012-06-14 10:25 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday 14 June 2012, Thierry Reding wrote:
> > 
> > I believe you will need an "interrupt-map" property here, to map the host
> > interrupts to the INTA-INTD lines of the attached devices.
>
> Legacy interrupts are something I cannot test at all because I have no
> hardware that supports them.

Hmm, I thought all PCIe hardware has to support them when you do not
enable MSI. What hardware do you have then?

> > I'm not sure whether we want to have a device_type="pciex" property here.
> > powerpc and sparc seem to use that information, to distinguish a pcie
> > bus from pci or cardbus.
> 
> That'd be rather useless information given that the Tegra is unlikely to
> support either PCI or CardBus at some point.

But the generic code does not know that.

	Arnd

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-14 10:25                                       ` Arnd Bergmann
@ 2012-06-14 10:31                                         ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-14 10:31 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel, Mitch Bradley, Russell King, Stephen Warren,
	linux-pci, devicetree-discuss, Jesse Barnes, Rob Herring,
	Colin Cross, linux-tegra

[-- Attachment #1: Type: text/plain, Size: 1147 bytes --]

On Thu, Jun 14, 2012 at 10:25:09AM +0000, Arnd Bergmann wrote:
> On Thursday 14 June 2012, Thierry Reding wrote:
> > > 
> > > I believe you will need an "interrupt-map" property here, to map the host
> > > interrupts to the INTA-INTD lines of the attached devices.
> >
> > Legacy interrupts are something I cannot test at all because I have no
> > hardware that supports them.
> 
> Hmm, I thought all PCIe hardware has to support them when you do not
> enable MSI. What hardware do you have then?

The TEC (Tamonten Evaluation Carrier) has an FPGA which is connected to one
of the Tegra PCIe ports and it only supports MSIs.

> > > I'm not sure whether we want to have a device_type="pciex" property here.
> > > powerpc and sparc seem to use that information, to distinguish a pcie
> > > bus from pci or cardbus.
> > 
> > That'd be rather useless information given that the Tegra is unlikely to
> > support either PCI or CardBus at some point.
> 
> But the generic code does not know that.

True. Still there's not much generic code on ARM, so maybe it'd be better to
add it along with the corresponding code?

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-14 10:31                                         ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-14 10:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jun 14, 2012 at 10:25:09AM +0000, Arnd Bergmann wrote:
> On Thursday 14 June 2012, Thierry Reding wrote:
> > > 
> > > I believe you will need an "interrupt-map" property here, to map the host
> > > interrupts to the INTA-INTD lines of the attached devices.
> >
> > Legacy interrupts are something I cannot test at all because I have no
> > hardware that supports them.
> 
> Hmm, I thought all PCIe hardware has to support them when you do not
> enable MSI. What hardware do you have then?

The TEC (Tamonten Evaluation Carrier) has an FPGA which is connected to one
of the Tegra PCIe ports and it only supports MSIs.

> > > I'm not sure whether we want to have a device_type="pciex" property here.
> > > powerpc and sparc seem to use that information, to distinguish a pcie
> > > bus from pci or cardbus.
> > 
> > That'd be rather useless information given that the Tegra is unlikely to
> > support either PCI or CardBus at some point.
> 
> But the generic code does not know that.

True. Still there's not much generic code on ARM, so maybe it'd be better to
add it along with the corresponding code?

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120614/ab4a7c31/attachment.sig>

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-14 10:31                                         ` Thierry Reding
@ 2012-06-14 11:06                                           ` Arnd Bergmann
  -1 siblings, 0 replies; 249+ messages in thread
From: Arnd Bergmann @ 2012-06-14 11:06 UTC (permalink / raw)
  To: Thierry Reding
  Cc: linux-arm-kernel, Mitch Bradley, Russell King, Stephen Warren,
	linux-pci, devicetree-discuss, Jesse Barnes, Rob Herring,
	Colin Cross, linux-tegra

On Thursday 14 June 2012, Thierry Reding wrote:
> On Thu, Jun 14, 2012 at 10:25:09AM +0000, Arnd Bergmann wrote:
> > On Thursday 14 June 2012, Thierry Reding wrote:
> > > > 
> > > > I believe you will need an "interrupt-map" property here, to map the host
> > > > interrupts to the INTA-INTD lines of the attached devices.
> > >
> > > Legacy interrupts are something I cannot test at all because I have no
> > > hardware that supports them.
> > 
> > Hmm, I thought all PCIe hardware has to support them when you do not
> > enable MSI. What hardware do you have then?
> 
> The TEC (Tamonten Evaluation Carrier) has an FPGA which is connected to one
> of the Tegra PCIe ports and it only supports MSIs.

Ah, I see. FPGA based devices often have incomplete PCI support so that
explains why you can't test it. The board also appears to have a
PCIe mini port though, so anything that you could plug in there should
also support LSI interrupts.

> > > > I'm not sure whether we want to have a device_type="pciex" property here.
> > > > powerpc and sparc seem to use that information, to distinguish a pcie
> > > > bus from pci or cardbus.
> > > 
> > > That'd be rather useless information given that the Tegra is unlikely to
> > > support either PCI or CardBus at some point.
> > 
> > But the generic code does not know that.
> 
> True. Still there's not much generic code on ARM, so maybe it'd be better to
> add it along with the corresponding code?

I hope we can make the PCI host probing architecture independent one day,
instead of each architecture implementing their own. I'd say better put
that property in there so we don't have to change it in case the future
generic code will need it. It is part of the binding at
http://www.openfirmware.org/1275/bindings/pci/pci-express.txt after all.

Note that we should generally not make /code/ be written with the
anticipation of a future extension, but anything that concerns interfaces
to code outside of the kernel (firmware or user space) is best written
in a conservative way to allow later changes.

	Arnd

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-14 11:06                                           ` Arnd Bergmann
  0 siblings, 0 replies; 249+ messages in thread
From: Arnd Bergmann @ 2012-06-14 11:06 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday 14 June 2012, Thierry Reding wrote:
> On Thu, Jun 14, 2012 at 10:25:09AM +0000, Arnd Bergmann wrote:
> > On Thursday 14 June 2012, Thierry Reding wrote:
> > > > 
> > > > I believe you will need an "interrupt-map" property here, to map the host
> > > > interrupts to the INTA-INTD lines of the attached devices.
> > >
> > > Legacy interrupts are something I cannot test at all because I have no
> > > hardware that supports them.
> > 
> > Hmm, I thought all PCIe hardware has to support them when you do not
> > enable MSI. What hardware do you have then?
> 
> The TEC (Tamonten Evaluation Carrier) has an FPGA which is connected to one
> of the Tegra PCIe ports and it only supports MSIs.

Ah, I see. FPGA based devices often have incomplete PCI support so that
explains why you can't test it. The board also appears to have a
PCIe mini port though, so anything that you could plug in there should
also support LSI interrupts.

> > > > I'm not sure whether we want to have a device_type="pciex" property here.
> > > > powerpc and sparc seem to use that information, to distinguish a pcie
> > > > bus from pci or cardbus.
> > > 
> > > That'd be rather useless information given that the Tegra is unlikely to
> > > support either PCI or CardBus at some point.
> > 
> > But the generic code does not know that.
> 
> True. Still there's not much generic code on ARM, so maybe it'd be better to
> add it along with the corresponding code?

I hope we can make the PCI host probing architecture independent one day,
instead of each architecture implementing their own. I'd say better put
that property in there so we don't have to change it in case the future
generic code will need it. It is part of the binding at
http://www.openfirmware.org/1275/bindings/pci/pci-express.txt after all.

Note that we should generally not make /code/ be written with the
anticipation of a future extension, but anything that concerns interfaces
to code outside of the kernel (firmware or user space) is best written
in a conservative way to allow later changes.

	Arnd

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-14 11:06                                           ` Arnd Bergmann
  (?)
@ 2012-06-14 11:58                                               ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-14 11:58 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Mitch Bradley,
	Russell King, Stephen Warren, linux-pci-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Jesse Barnes,
	Rob Herring, Colin Cross, linux-tegra-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: text/plain, Size: 2651 bytes --]

On Thu, Jun 14, 2012 at 11:06:48AM +0000, Arnd Bergmann wrote:
> On Thursday 14 June 2012, Thierry Reding wrote:
> > On Thu, Jun 14, 2012 at 10:25:09AM +0000, Arnd Bergmann wrote:
> > > On Thursday 14 June 2012, Thierry Reding wrote:
> > > > > 
> > > > > I believe you will need an "interrupt-map" property here, to map the host
> > > > > interrupts to the INTA-INTD lines of the attached devices.
> > > >
> > > > Legacy interrupts are something I cannot test at all because I have no
> > > > hardware that supports them.
> > > 
> > > Hmm, I thought all PCIe hardware has to support them when you do not
> > > enable MSI. What hardware do you have then?
> > 
> > The TEC (Tamonten Evaluation Carrier) has an FPGA which is connected to one
> > of the Tegra PCIe ports and it only supports MSIs.
> 
> Ah, I see. FPGA based devices often have incomplete PCI support so that
> explains why you can't test it. The board also appears to have a
> PCIe mini port though, so anything that you could plug in there should
> also support LSI interrupts.

Yes, I haven't gotten my hands on a suitable module yet, but I'll try. I'm
not very familiar with legacy interrupts, though, and I'll have to read up
on the interrupt map bindings.

> > > > > I'm not sure whether we want to have a device_type="pciex" property here.
> > > > > powerpc and sparc seem to use that information, to distinguish a pcie
> > > > > bus from pci or cardbus.
> > > > 
> > > > That'd be rather useless information given that the Tegra is unlikely to
> > > > support either PCI or CardBus at some point.
> > > 
> > > But the generic code does not know that.
> > 
> > True. Still there's not much generic code on ARM, so maybe it'd be better to
> > add it along with the corresponding code?
> 
> I hope we can make the PCI host probing architecture independent one day,
> instead of each architecture implementing their own. I'd say better put
> that property in there so we don't have to change it in case the future
> generic code will need it. It is part of the binding at
> http://www.openfirmware.org/1275/bindings/pci/pci-express.txt after all.

There seems to be quite a lot in the PCI core already. Unfortunately every
architecture seems to do things differently, so unification is probably going
to be quite difficult.

> Note that we should generally not make /code/ be written with the
> anticipation of a future extension, but anything that concerns interfaces
> to code outside of the kernel (firmware or user space) is best written
> in a conservative way to allow later changes.

Okay, I'll add the property.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-14 11:58                                               ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-14 11:58 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel, Mitch Bradley, Russell King, Stephen Warren,
	linux-pci, devicetree-discuss, Jesse Barnes, Rob Herring,
	Colin Cross, linux-tegra

[-- Attachment #1: Type: text/plain, Size: 2651 bytes --]

On Thu, Jun 14, 2012 at 11:06:48AM +0000, Arnd Bergmann wrote:
> On Thursday 14 June 2012, Thierry Reding wrote:
> > On Thu, Jun 14, 2012 at 10:25:09AM +0000, Arnd Bergmann wrote:
> > > On Thursday 14 June 2012, Thierry Reding wrote:
> > > > > 
> > > > > I believe you will need an "interrupt-map" property here, to map the host
> > > > > interrupts to the INTA-INTD lines of the attached devices.
> > > >
> > > > Legacy interrupts are something I cannot test at all because I have no
> > > > hardware that supports them.
> > > 
> > > Hmm, I thought all PCIe hardware has to support them when you do not
> > > enable MSI. What hardware do you have then?
> > 
> > The TEC (Tamonten Evaluation Carrier) has an FPGA which is connected to one
> > of the Tegra PCIe ports and it only supports MSIs.
> 
> Ah, I see. FPGA based devices often have incomplete PCI support so that
> explains why you can't test it. The board also appears to have a
> PCIe mini port though, so anything that you could plug in there should
> also support LSI interrupts.

Yes, I haven't gotten my hands on a suitable module yet, but I'll try. I'm
not very familiar with legacy interrupts, though, and I'll have to read up
on the interrupt map bindings.

> > > > > I'm not sure whether we want to have a device_type="pciex" property here.
> > > > > powerpc and sparc seem to use that information, to distinguish a pcie
> > > > > bus from pci or cardbus.
> > > > 
> > > > That'd be rather useless information given that the Tegra is unlikely to
> > > > support either PCI or CardBus at some point.
> > > 
> > > But the generic code does not know that.
> > 
> > True. Still there's not much generic code on ARM, so maybe it'd be better to
> > add it along with the corresponding code?
> 
> I hope we can make the PCI host probing architecture independent one day,
> instead of each architecture implementing their own. I'd say better put
> that property in there so we don't have to change it in case the future
> generic code will need it. It is part of the binding at
> http://www.openfirmware.org/1275/bindings/pci/pci-express.txt after all.

There seems to be quite a lot in the PCI core already. Unfortunately every
architecture seems to do things differently, so unification is probably going
to be quite difficult.

> Note that we should generally not make /code/ be written with the
> anticipation of a future extension, but anything that concerns interfaces
> to code outside of the kernel (firmware or user space) is best written
> in a conservative way to allow later changes.

Okay, I'll add the property.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-14 11:58                                               ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-14 11:58 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jun 14, 2012 at 11:06:48AM +0000, Arnd Bergmann wrote:
> On Thursday 14 June 2012, Thierry Reding wrote:
> > On Thu, Jun 14, 2012 at 10:25:09AM +0000, Arnd Bergmann wrote:
> > > On Thursday 14 June 2012, Thierry Reding wrote:
> > > > > 
> > > > > I believe you will need an "interrupt-map" property here, to map the host
> > > > > interrupts to the INTA-INTD lines of the attached devices.
> > > >
> > > > Legacy interrupts are something I cannot test at all because I have no
> > > > hardware that supports them.
> > > 
> > > Hmm, I thought all PCIe hardware has to support them when you do not
> > > enable MSI. What hardware do you have then?
> > 
> > The TEC (Tamonten Evaluation Carrier) has an FPGA which is connected to one
> > of the Tegra PCIe ports and it only supports MSIs.
> 
> Ah, I see. FPGA based devices often have incomplete PCI support so that
> explains why you can't test it. The board also appears to have a
> PCIe mini port though, so anything that you could plug in there should
> also support LSI interrupts.

Yes, I haven't gotten my hands on a suitable module yet, but I'll try. I'm
not very familiar with legacy interrupts, though, and I'll have to read up
on the interrupt map bindings.

> > > > > I'm not sure whether we want to have a device_type="pciex" property here.
> > > > > powerpc and sparc seem to use that information, to distinguish a pcie
> > > > > bus from pci or cardbus.
> > > > 
> > > > That'd be rather useless information given that the Tegra is unlikely to
> > > > support either PCI or CardBus at some point.
> > > 
> > > But the generic code does not know that.
> > 
> > True. Still there's not much generic code on ARM, so maybe it'd be better to
> > add it along with the corresponding code?
> 
> I hope we can make the PCI host probing architecture independent one day,
> instead of each architecture implementing their own. I'd say better put
> that property in there so we don't have to change it in case the future
> generic code will need it. It is part of the binding at
> http://www.openfirmware.org/1275/bindings/pci/pci-express.txt after all.

There seems to be quite a lot in the PCI core already. Unfortunately every
architecture seems to do things differently, so unification is probably going
to be quite difficult.

> Note that we should generally not make /code/ be written with the
> anticipation of a future extension, but anything that concerns interfaces
> to code outside of the kernel (firmware or user space) is best written
> in a conservative way to allow later changes.

Okay, I'll add the property.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120614/3c9c8a18/attachment.sig>

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-14  9:19                                             ` Thierry Reding
  (?)
@ 2012-06-14 18:30                                                 ` Stephen Warren
  -1 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-14 18:30 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Mitch Bradley, Russell King, linux-pci-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Jesse Barnes, Colin Cross, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On 06/14/2012 03:19 AM, Thierry Reding wrote:
...
> Okay, so the new pcie-controller node looks like this:
> 
> pcie-controller { compatible = "nvidia,tegra20-pcie",
> "simple-bus"; reg = <0x80003000 0x00000800   /* PADS registers */ 
> 0x80003800 0x00000200   /* AFI registers */ 0x80004000 0x00100000
> /* configuration space */ 0x80104000 0x00100000>; /* extended
> configuration space */ interrupts = <0 98 0x04   /* controller
> interrupt */ 0 99 0x04>; /* MSI interrupt */ status = "disabled";
> 
> ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */ 
> 0x80400000 0x80400000 0x00010000   /* downstream I/O */ 0x90000000
> 0x90000000 0x10000000   /* non-prefetchable memory */ 0xa0000000
> 0xa0000000 0x10000000>; /* prefetchable memory */

Do we actually need to specifically enumerate all the ranges; would
just "ranges;" be simpler?

> #address-cells = <1>; #size-cells = <1>;
> 
> pci@80000000 {

I'm still not convinced that using the address of the port's registers
is the correct way to represent each port. The port index seems much
more useful.

The main reason here is that there are a lot of registers that contain
fields for each port - far more than the combination of this node's
reg and ctrl-offset (which I assume is an address offset for just one
example of this issue) properties can describe. The bit position and
bit stride of these fields isn't necessarily the same in each
register. Do we want a property like ctrl-offset for every single type
of field in every single shared register that describes the location
of the relevant data, or just a single "port ID" bit that can be
applied to anything?

(Perhaps this isn't so obvious looking at the TRM since it doesn't
document all registers, and I'm also looking at the Tegra30
documentation too, which might be more exposed to this - I haven't
correlated all the documentation sources to be sure though)

> compatible = "nvidia,tegra20-pcie-port"; reg = <0x80000000
> 0x00001000>; status = "disabled";
> 
> #address-cells = <3>; #size-cells = <2>;
> 
> ranges = <0x81000000 0 0 0x80400000 0 0x00008000   /* I/O */ 
> 0x82000000 0 0 0x90000000 0 0x08000000   /* non-prefetchable memory
> */ 0xc2000000 0 0 0xa0000000 0 0x08000000>; /* prefetchable memory
> */

The values here appear identical for both ports. Surely they should
describe just the parts of the overall address space that have been
assigned/delegated to the individual port/bridge?

Note that initial indications are that the overall controller receives
transactions for those address ranges, and standard PCIe bridge
registers are used to steer chunks of these address ranges into the
individual downstream ports/busses. Hence, standard PCIe documentation
should indicate how to do this.

> nvidia,ctrl-offset = <0x110>; nvidia,num-lanes = <2>; };
> 
> pci@80001000 { compatible = "nvidia,tegra20-pcie-port"; reg =
> <0x80001000 0x00001000>; status = "disabled";
> 
> #address-cells = <3>; #size-cells = <2>;
> 
> ranges = <0x81000000 0 0 0x80408000 0 0x00008000   /* I/O */ 
> 0x82000000 0 0 0x98000000 0 0x08000000   /* non-prefetchable memory
> */ 0xc2000000 0 0 0xa8000000 0 0x08000000>; /* prefetchable memory
> */
> 
> nvidia,ctrl-offset = <0x118>; nvidia,num-lanes = <2>; }; };
> 
> While looking into some more code, trying to figure out how to hook
> this all up with the device tree I ran into a problem. I need to
> actually create a 'struct device' for each of the ports, so I added
> the "simple-bus" to the pcie-controller's "compatible" property.
> Furthermore, each PCI root port now becomes a platform_device,
> which are supported by a new tegra-pcie-port driver. I'm not sure
> if "port" is very common in PCI speek, so something like 
> tegra-pcie-bridge (compatible = "nvidia,tegra20-pcie-bridge") may
> be more appropriate?

What is it that drives the need for each port to be a 'struct device'?
The current driver supports 2 host ports, yet there's only a single
struct device for it. Does the DT code assume a 1:1 mapping between
struct device and DT node that represents the child bus? If so,
perhaps it'd be better to rework that code to accept a DT node as a
parameter and call it multiple times, rather than accept a struct
device as a parameter and hence need multiple devices?

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-14 18:30                                                 ` Stephen Warren
  0 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-14 18:30 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Mitch Bradley, Russell King, linux-pci, devicetree-discuss,
	Rob Herring, Jesse Barnes, Colin Cross, linux-tegra,
	linux-arm-kernel

On 06/14/2012 03:19 AM, Thierry Reding wrote:
...
> Okay, so the new pcie-controller node looks like this:
> 
> pcie-controller { compatible = "nvidia,tegra20-pcie",
> "simple-bus"; reg = <0x80003000 0x00000800   /* PADS registers */ 
> 0x80003800 0x00000200   /* AFI registers */ 0x80004000 0x00100000
> /* configuration space */ 0x80104000 0x00100000>; /* extended
> configuration space */ interrupts = <0 98 0x04   /* controller
> interrupt */ 0 99 0x04>; /* MSI interrupt */ status = "disabled";
> 
> ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */ 
> 0x80400000 0x80400000 0x00010000   /* downstream I/O */ 0x90000000
> 0x90000000 0x10000000   /* non-prefetchable memory */ 0xa0000000
> 0xa0000000 0x10000000>; /* prefetchable memory */

Do we actually need to specifically enumerate all the ranges; would
just "ranges;" be simpler?

> #address-cells = <1>; #size-cells = <1>;
> 
> pci@80000000 {

I'm still not convinced that using the address of the port's registers
is the correct way to represent each port. The port index seems much
more useful.

The main reason here is that there are a lot of registers that contain
fields for each port - far more than the combination of this node's
reg and ctrl-offset (which I assume is an address offset for just one
example of this issue) properties can describe. The bit position and
bit stride of these fields isn't necessarily the same in each
register. Do we want a property like ctrl-offset for every single type
of field in every single shared register that describes the location
of the relevant data, or just a single "port ID" bit that can be
applied to anything?

(Perhaps this isn't so obvious looking at the TRM since it doesn't
document all registers, and I'm also looking at the Tegra30
documentation too, which might be more exposed to this - I haven't
correlated all the documentation sources to be sure though)

> compatible = "nvidia,tegra20-pcie-port"; reg = <0x80000000
> 0x00001000>; status = "disabled";
> 
> #address-cells = <3>; #size-cells = <2>;
> 
> ranges = <0x81000000 0 0 0x80400000 0 0x00008000   /* I/O */ 
> 0x82000000 0 0 0x90000000 0 0x08000000   /* non-prefetchable memory
> */ 0xc2000000 0 0 0xa0000000 0 0x08000000>; /* prefetchable memory
> */

The values here appear identical for both ports. Surely they should
describe just the parts of the overall address space that have been
assigned/delegated to the individual port/bridge?

Note that initial indications are that the overall controller receives
transactions for those address ranges, and standard PCIe bridge
registers are used to steer chunks of these address ranges into the
individual downstream ports/busses. Hence, standard PCIe documentation
should indicate how to do this.

> nvidia,ctrl-offset = <0x110>; nvidia,num-lanes = <2>; };
> 
> pci@80001000 { compatible = "nvidia,tegra20-pcie-port"; reg =
> <0x80001000 0x00001000>; status = "disabled";
> 
> #address-cells = <3>; #size-cells = <2>;
> 
> ranges = <0x81000000 0 0 0x80408000 0 0x00008000   /* I/O */ 
> 0x82000000 0 0 0x98000000 0 0x08000000   /* non-prefetchable memory
> */ 0xc2000000 0 0 0xa8000000 0 0x08000000>; /* prefetchable memory
> */
> 
> nvidia,ctrl-offset = <0x118>; nvidia,num-lanes = <2>; }; };
> 
> While looking into some more code, trying to figure out how to hook
> this all up with the device tree I ran into a problem. I need to
> actually create a 'struct device' for each of the ports, so I added
> the "simple-bus" to the pcie-controller's "compatible" property.
> Furthermore, each PCI root port now becomes a platform_device,
> which are supported by a new tegra-pcie-port driver. I'm not sure
> if "port" is very common in PCI speek, so something like 
> tegra-pcie-bridge (compatible = "nvidia,tegra20-pcie-bridge") may
> be more appropriate?

What is it that drives the need for each port to be a 'struct device'?
The current driver supports 2 host ports, yet there's only a single
struct device for it. Does the DT code assume a 1:1 mapping between
struct device and DT node that represents the child bus? If so,
perhaps it'd be better to rework that code to accept a DT node as a
parameter and call it multiple times, rather than accept a struct
device as a parameter and hence need multiple devices?

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-14 18:30                                                 ` Stephen Warren
  0 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-14 18:30 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/14/2012 03:19 AM, Thierry Reding wrote:
...
> Okay, so the new pcie-controller node looks like this:
> 
> pcie-controller { compatible = "nvidia,tegra20-pcie",
> "simple-bus"; reg = <0x80003000 0x00000800   /* PADS registers */ 
> 0x80003800 0x00000200   /* AFI registers */ 0x80004000 0x00100000
> /* configuration space */ 0x80104000 0x00100000>; /* extended
> configuration space */ interrupts = <0 98 0x04   /* controller
> interrupt */ 0 99 0x04>; /* MSI interrupt */ status = "disabled";
> 
> ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */ 
> 0x80400000 0x80400000 0x00010000   /* downstream I/O */ 0x90000000
> 0x90000000 0x10000000   /* non-prefetchable memory */ 0xa0000000
> 0xa0000000 0x10000000>; /* prefetchable memory */

Do we actually need to specifically enumerate all the ranges; would
just "ranges;" be simpler?

> #address-cells = <1>; #size-cells = <1>;
> 
> pci at 80000000 {

I'm still not convinced that using the address of the port's registers
is the correct way to represent each port. The port index seems much
more useful.

The main reason here is that there are a lot of registers that contain
fields for each port - far more than the combination of this node's
reg and ctrl-offset (which I assume is an address offset for just one
example of this issue) properties can describe. The bit position and
bit stride of these fields isn't necessarily the same in each
register. Do we want a property like ctrl-offset for every single type
of field in every single shared register that describes the location
of the relevant data, or just a single "port ID" bit that can be
applied to anything?

(Perhaps this isn't so obvious looking at the TRM since it doesn't
document all registers, and I'm also looking at the Tegra30
documentation too, which might be more exposed to this - I haven't
correlated all the documentation sources to be sure though)

> compatible = "nvidia,tegra20-pcie-port"; reg = <0x80000000
> 0x00001000>; status = "disabled";
> 
> #address-cells = <3>; #size-cells = <2>;
> 
> ranges = <0x81000000 0 0 0x80400000 0 0x00008000   /* I/O */ 
> 0x82000000 0 0 0x90000000 0 0x08000000   /* non-prefetchable memory
> */ 0xc2000000 0 0 0xa0000000 0 0x08000000>; /* prefetchable memory
> */

The values here appear identical for both ports. Surely they should
describe just the parts of the overall address space that have been
assigned/delegated to the individual port/bridge?

Note that initial indications are that the overall controller receives
transactions for those address ranges, and standard PCIe bridge
registers are used to steer chunks of these address ranges into the
individual downstream ports/busses. Hence, standard PCIe documentation
should indicate how to do this.

> nvidia,ctrl-offset = <0x110>; nvidia,num-lanes = <2>; };
> 
> pci at 80001000 { compatible = "nvidia,tegra20-pcie-port"; reg =
> <0x80001000 0x00001000>; status = "disabled";
> 
> #address-cells = <3>; #size-cells = <2>;
> 
> ranges = <0x81000000 0 0 0x80408000 0 0x00008000   /* I/O */ 
> 0x82000000 0 0 0x98000000 0 0x08000000   /* non-prefetchable memory
> */ 0xc2000000 0 0 0xa8000000 0 0x08000000>; /* prefetchable memory
> */
> 
> nvidia,ctrl-offset = <0x118>; nvidia,num-lanes = <2>; }; };
> 
> While looking into some more code, trying to figure out how to hook
> this all up with the device tree I ran into a problem. I need to
> actually create a 'struct device' for each of the ports, so I added
> the "simple-bus" to the pcie-controller's "compatible" property.
> Furthermore, each PCI root port now becomes a platform_device,
> which are supported by a new tegra-pcie-port driver. I'm not sure
> if "port" is very common in PCI speek, so something like 
> tegra-pcie-bridge (compatible = "nvidia,tegra20-pcie-bridge") may
> be more appropriate?

What is it that drives the need for each port to be a 'struct device'?
The current driver supports 2 host ports, yet there's only a single
struct device for it. Does the DT code assume a 1:1 mapping between
struct device and DT node that represents the child bus? If so,
perhaps it'd be better to rework that code to accept a DT node as a
parameter and call it multiple times, rather than accept a struct
device as a parameter and hence need multiple devices?

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-14 18:30                                                 ` Stephen Warren
  (?)
@ 2012-06-14 19:29                                                     ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-14 19:29 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Mitch Bradley, Russell King, linux-pci-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Jesse Barnes, Colin Cross, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

[-- Attachment #1: Type: text/plain, Size: 5813 bytes --]

On Thu, Jun 14, 2012 at 12:30:50PM -0600, Stephen Warren wrote:
> On 06/14/2012 03:19 AM, Thierry Reding wrote:
> ...
> > Okay, so the new pcie-controller node looks like this:
> > 
> > pcie-controller { compatible = "nvidia,tegra20-pcie",
> > "simple-bus"; reg = <0x80003000 0x00000800   /* PADS registers */ 
> > 0x80003800 0x00000200   /* AFI registers */ 0x80004000 0x00100000
> > /* configuration space */ 0x80104000 0x00100000>; /* extended
> > configuration space */ interrupts = <0 98 0x04   /* controller
> > interrupt */ 0 99 0x04>; /* MSI interrupt */ status = "disabled";
> > 
> > ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */ 
> > 0x80400000 0x80400000 0x00010000   /* downstream I/O */ 0x90000000
> > 0x90000000 0x10000000   /* non-prefetchable memory */ 0xa0000000
> > 0xa0000000 0x10000000>; /* prefetchable memory */
> 
> Do we actually need to specifically enumerate all the ranges; would
> just "ranges;" be simpler?

I think they need to be listed here in order for the child nodes to be able
to map them using their ranges property. It's possible that it'll work by
specifying an empty ranges, but I don't think it'd be correct in the OF
sense.

> > #address-cells = <1>; #size-cells = <1>;
> > 
> > pci@80000000 {
> 
> I'm still not convinced that using the address of the port's registers
> is the correct way to represent each port. The port index seems much
> more useful.
> 
> The main reason here is that there are a lot of registers that contain
> fields for each port - far more than the combination of this node's
> reg and ctrl-offset (which I assume is an address offset for just one
> example of this issue) properties can describe. The bit position and
> bit stride of these fields isn't necessarily the same in each
> register. Do we want a property like ctrl-offset for every single type
> of field in every single shared register that describes the location
> of the relevant data, or just a single "port ID" bit that can be
> applied to anything?
> 
> (Perhaps this isn't so obvious looking at the TRM since it doesn't
> document all registers, and I'm also looking at the Tegra30
> documentation too, which might be more exposed to this - I haven't
> correlated all the documentation sources to be sure though)

I agree that maybe adding properties for each bit position or register offset
may not work out too well. But I think it still makes sense to use the base
address of the port's registers (see below). We could of course add some code
to determine the index from the base address at initialization time and reuse
the index where appropriate.

> > compatible = "nvidia,tegra20-pcie-port"; reg = <0x80000000
> > 0x00001000>; status = "disabled";
> > 
> > #address-cells = <3>; #size-cells = <2>;
> > 
> > ranges = <0x81000000 0 0 0x80400000 0 0x00008000   /* I/O */ 
> > 0x82000000 0 0 0x90000000 0 0x08000000   /* non-prefetchable memory
> > */ 0xc2000000 0 0 0xa0000000 0 0x08000000>; /* prefetchable memory
> > */
> 
> The values here appear identical for both ports. Surely they should
> describe just the parts of the overall address space that have been
> assigned/delegated to the individual port/bridge?

They're not identical. Port 0 gets the first half and port 1 gets the second
half of the ranges specified in the parent.

> Note that initial indications are that the overall controller receives
> transactions for those address ranges, and standard PCIe bridge
> registers are used to steer chunks of these address ranges into the
> individual downstream ports/busses. Hence, standard PCIe documentation
> should indicate how to do this.

Yes, I believe that works with the code I have currently, which basically
parses the ranges property of each port and initializes the I/O, memory and
prefetchable regions from those values.

> > nvidia,ctrl-offset = <0x110>; nvidia,num-lanes = <2>; };
> > 
> > pci@80001000 { compatible = "nvidia,tegra20-pcie-port"; reg =
> > <0x80001000 0x00001000>; status = "disabled";
> > 
> > #address-cells = <3>; #size-cells = <2>;
> > 
> > ranges = <0x81000000 0 0 0x80408000 0 0x00008000   /* I/O */ 
> > 0x82000000 0 0 0x98000000 0 0x08000000   /* non-prefetchable memory
> > */ 0xc2000000 0 0 0xa8000000 0 0x08000000>; /* prefetchable memory
> > */
> > 
> > nvidia,ctrl-offset = <0x118>; nvidia,num-lanes = <2>; }; };
> > 
> > While looking into some more code, trying to figure out how to hook
> > this all up with the device tree I ran into a problem. I need to
> > actually create a 'struct device' for each of the ports, so I added
> > the "simple-bus" to the pcie-controller's "compatible" property.
> > Furthermore, each PCI root port now becomes a platform_device,
> > which are supported by a new tegra-pcie-port driver. I'm not sure
> > if "port" is very common in PCI speek, so something like 
> > tegra-pcie-bridge (compatible = "nvidia,tegra20-pcie-bridge") may
> > be more appropriate?
> 
> What is it that drives the need for each port to be a 'struct device'?
> The current driver supports 2 host ports, yet there's only a single
> struct device for it. Does the DT code assume a 1:1 mapping between
> struct device and DT node that represents the child bus? If so,
> perhaps it'd be better to rework that code to accept a DT node as a
> parameter and call it multiple times, rather than accept a struct
> device as a parameter and hence need multiple devices?

It's not so much the DT code, but rather the PCI core and ultimately the
device model that requires it. Each port is basically a PCI host bridge that
provides a root PCI bus and the device model is used to represent the
hierachy of the busses. Providing just the DT node isn't going to be enough.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-14 19:29                                                     ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-14 19:29 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Mitch Bradley, Russell King, linux-pci, devicetree-discuss,
	Rob Herring, Jesse Barnes, Colin Cross, linux-tegra,
	linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 5813 bytes --]

On Thu, Jun 14, 2012 at 12:30:50PM -0600, Stephen Warren wrote:
> On 06/14/2012 03:19 AM, Thierry Reding wrote:
> ...
> > Okay, so the new pcie-controller node looks like this:
> > 
> > pcie-controller { compatible = "nvidia,tegra20-pcie",
> > "simple-bus"; reg = <0x80003000 0x00000800   /* PADS registers */ 
> > 0x80003800 0x00000200   /* AFI registers */ 0x80004000 0x00100000
> > /* configuration space */ 0x80104000 0x00100000>; /* extended
> > configuration space */ interrupts = <0 98 0x04   /* controller
> > interrupt */ 0 99 0x04>; /* MSI interrupt */ status = "disabled";
> > 
> > ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */ 
> > 0x80400000 0x80400000 0x00010000   /* downstream I/O */ 0x90000000
> > 0x90000000 0x10000000   /* non-prefetchable memory */ 0xa0000000
> > 0xa0000000 0x10000000>; /* prefetchable memory */
> 
> Do we actually need to specifically enumerate all the ranges; would
> just "ranges;" be simpler?

I think they need to be listed here in order for the child nodes to be able
to map them using their ranges property. It's possible that it'll work by
specifying an empty ranges, but I don't think it'd be correct in the OF
sense.

> > #address-cells = <1>; #size-cells = <1>;
> > 
> > pci@80000000 {
> 
> I'm still not convinced that using the address of the port's registers
> is the correct way to represent each port. The port index seems much
> more useful.
> 
> The main reason here is that there are a lot of registers that contain
> fields for each port - far more than the combination of this node's
> reg and ctrl-offset (which I assume is an address offset for just one
> example of this issue) properties can describe. The bit position and
> bit stride of these fields isn't necessarily the same in each
> register. Do we want a property like ctrl-offset for every single type
> of field in every single shared register that describes the location
> of the relevant data, or just a single "port ID" bit that can be
> applied to anything?
> 
> (Perhaps this isn't so obvious looking at the TRM since it doesn't
> document all registers, and I'm also looking at the Tegra30
> documentation too, which might be more exposed to this - I haven't
> correlated all the documentation sources to be sure though)

I agree that maybe adding properties for each bit position or register offset
may not work out too well. But I think it still makes sense to use the base
address of the port's registers (see below). We could of course add some code
to determine the index from the base address at initialization time and reuse
the index where appropriate.

> > compatible = "nvidia,tegra20-pcie-port"; reg = <0x80000000
> > 0x00001000>; status = "disabled";
> > 
> > #address-cells = <3>; #size-cells = <2>;
> > 
> > ranges = <0x81000000 0 0 0x80400000 0 0x00008000   /* I/O */ 
> > 0x82000000 0 0 0x90000000 0 0x08000000   /* non-prefetchable memory
> > */ 0xc2000000 0 0 0xa0000000 0 0x08000000>; /* prefetchable memory
> > */
> 
> The values here appear identical for both ports. Surely they should
> describe just the parts of the overall address space that have been
> assigned/delegated to the individual port/bridge?

They're not identical. Port 0 gets the first half and port 1 gets the second
half of the ranges specified in the parent.

> Note that initial indications are that the overall controller receives
> transactions for those address ranges, and standard PCIe bridge
> registers are used to steer chunks of these address ranges into the
> individual downstream ports/busses. Hence, standard PCIe documentation
> should indicate how to do this.

Yes, I believe that works with the code I have currently, which basically
parses the ranges property of each port and initializes the I/O, memory and
prefetchable regions from those values.

> > nvidia,ctrl-offset = <0x110>; nvidia,num-lanes = <2>; };
> > 
> > pci@80001000 { compatible = "nvidia,tegra20-pcie-port"; reg =
> > <0x80001000 0x00001000>; status = "disabled";
> > 
> > #address-cells = <3>; #size-cells = <2>;
> > 
> > ranges = <0x81000000 0 0 0x80408000 0 0x00008000   /* I/O */ 
> > 0x82000000 0 0 0x98000000 0 0x08000000   /* non-prefetchable memory
> > */ 0xc2000000 0 0 0xa8000000 0 0x08000000>; /* prefetchable memory
> > */
> > 
> > nvidia,ctrl-offset = <0x118>; nvidia,num-lanes = <2>; }; };
> > 
> > While looking into some more code, trying to figure out how to hook
> > this all up with the device tree I ran into a problem. I need to
> > actually create a 'struct device' for each of the ports, so I added
> > the "simple-bus" to the pcie-controller's "compatible" property.
> > Furthermore, each PCI root port now becomes a platform_device,
> > which are supported by a new tegra-pcie-port driver. I'm not sure
> > if "port" is very common in PCI speek, so something like 
> > tegra-pcie-bridge (compatible = "nvidia,tegra20-pcie-bridge") may
> > be more appropriate?
> 
> What is it that drives the need for each port to be a 'struct device'?
> The current driver supports 2 host ports, yet there's only a single
> struct device for it. Does the DT code assume a 1:1 mapping between
> struct device and DT node that represents the child bus? If so,
> perhaps it'd be better to rework that code to accept a DT node as a
> parameter and call it multiple times, rather than accept a struct
> device as a parameter and hence need multiple devices?

It's not so much the DT code, but rather the PCI core and ultimately the
device model that requires it. Each port is basically a PCI host bridge that
provides a root PCI bus and the device model is used to represent the
hierachy of the busses. Providing just the DT node isn't going to be enough.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-14 19:29                                                     ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-14 19:29 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jun 14, 2012 at 12:30:50PM -0600, Stephen Warren wrote:
> On 06/14/2012 03:19 AM, Thierry Reding wrote:
> ...
> > Okay, so the new pcie-controller node looks like this:
> > 
> > pcie-controller { compatible = "nvidia,tegra20-pcie",
> > "simple-bus"; reg = <0x80003000 0x00000800   /* PADS registers */ 
> > 0x80003800 0x00000200   /* AFI registers */ 0x80004000 0x00100000
> > /* configuration space */ 0x80104000 0x00100000>; /* extended
> > configuration space */ interrupts = <0 98 0x04   /* controller
> > interrupt */ 0 99 0x04>; /* MSI interrupt */ status = "disabled";
> > 
> > ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */ 
> > 0x80400000 0x80400000 0x00010000   /* downstream I/O */ 0x90000000
> > 0x90000000 0x10000000   /* non-prefetchable memory */ 0xa0000000
> > 0xa0000000 0x10000000>; /* prefetchable memory */
> 
> Do we actually need to specifically enumerate all the ranges; would
> just "ranges;" be simpler?

I think they need to be listed here in order for the child nodes to be able
to map them using their ranges property. It's possible that it'll work by
specifying an empty ranges, but I don't think it'd be correct in the OF
sense.

> > #address-cells = <1>; #size-cells = <1>;
> > 
> > pci at 80000000 {
> 
> I'm still not convinced that using the address of the port's registers
> is the correct way to represent each port. The port index seems much
> more useful.
> 
> The main reason here is that there are a lot of registers that contain
> fields for each port - far more than the combination of this node's
> reg and ctrl-offset (which I assume is an address offset for just one
> example of this issue) properties can describe. The bit position and
> bit stride of these fields isn't necessarily the same in each
> register. Do we want a property like ctrl-offset for every single type
> of field in every single shared register that describes the location
> of the relevant data, or just a single "port ID" bit that can be
> applied to anything?
> 
> (Perhaps this isn't so obvious looking at the TRM since it doesn't
> document all registers, and I'm also looking at the Tegra30
> documentation too, which might be more exposed to this - I haven't
> correlated all the documentation sources to be sure though)

I agree that maybe adding properties for each bit position or register offset
may not work out too well. But I think it still makes sense to use the base
address of the port's registers (see below). We could of course add some code
to determine the index from the base address at initialization time and reuse
the index where appropriate.

> > compatible = "nvidia,tegra20-pcie-port"; reg = <0x80000000
> > 0x00001000>; status = "disabled";
> > 
> > #address-cells = <3>; #size-cells = <2>;
> > 
> > ranges = <0x81000000 0 0 0x80400000 0 0x00008000   /* I/O */ 
> > 0x82000000 0 0 0x90000000 0 0x08000000   /* non-prefetchable memory
> > */ 0xc2000000 0 0 0xa0000000 0 0x08000000>; /* prefetchable memory
> > */
> 
> The values here appear identical for both ports. Surely they should
> describe just the parts of the overall address space that have been
> assigned/delegated to the individual port/bridge?

They're not identical. Port 0 gets the first half and port 1 gets the second
half of the ranges specified in the parent.

> Note that initial indications are that the overall controller receives
> transactions for those address ranges, and standard PCIe bridge
> registers are used to steer chunks of these address ranges into the
> individual downstream ports/busses. Hence, standard PCIe documentation
> should indicate how to do this.

Yes, I believe that works with the code I have currently, which basically
parses the ranges property of each port and initializes the I/O, memory and
prefetchable regions from those values.

> > nvidia,ctrl-offset = <0x110>; nvidia,num-lanes = <2>; };
> > 
> > pci at 80001000 { compatible = "nvidia,tegra20-pcie-port"; reg =
> > <0x80001000 0x00001000>; status = "disabled";
> > 
> > #address-cells = <3>; #size-cells = <2>;
> > 
> > ranges = <0x81000000 0 0 0x80408000 0 0x00008000   /* I/O */ 
> > 0x82000000 0 0 0x98000000 0 0x08000000   /* non-prefetchable memory
> > */ 0xc2000000 0 0 0xa8000000 0 0x08000000>; /* prefetchable memory
> > */
> > 
> > nvidia,ctrl-offset = <0x118>; nvidia,num-lanes = <2>; }; };
> > 
> > While looking into some more code, trying to figure out how to hook
> > this all up with the device tree I ran into a problem. I need to
> > actually create a 'struct device' for each of the ports, so I added
> > the "simple-bus" to the pcie-controller's "compatible" property.
> > Furthermore, each PCI root port now becomes a platform_device,
> > which are supported by a new tegra-pcie-port driver. I'm not sure
> > if "port" is very common in PCI speek, so something like 
> > tegra-pcie-bridge (compatible = "nvidia,tegra20-pcie-bridge") may
> > be more appropriate?
> 
> What is it that drives the need for each port to be a 'struct device'?
> The current driver supports 2 host ports, yet there's only a single
> struct device for it. Does the DT code assume a 1:1 mapping between
> struct device and DT node that represents the child bus? If so,
> perhaps it'd be better to rework that code to accept a DT node as a
> parameter and call it multiple times, rather than accept a struct
> device as a parameter and hence need multiple devices?

It's not so much the DT code, but rather the PCI core and ultimately the
device model that requires it. Each port is basically a PCI host bridge that
provides a root PCI bus and the device model is used to represent the
hierachy of the busses. Providing just the DT node isn't going to be enough.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120614/d3b0a9d4/attachment-0001.sig>

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-14 19:29                                                     ` Thierry Reding
  (?)
@ 2012-06-14 19:50                                                         ` Stephen Warren
  -1 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-14 19:50 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Mitch Bradley, Russell King, linux-pci-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Jesse Barnes, Colin Cross, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On 06/14/2012 01:29 PM, Thierry Reding wrote:
> On Thu, Jun 14, 2012 at 12:30:50PM -0600, Stephen Warren wrote:
>> On 06/14/2012 03:19 AM, Thierry Reding wrote:
...
>>> #address-cells = <1>; #size-cells = <1>;
>>> 
>>> pci@80000000 {
>> 
>> I'm still not convinced that using the address of the port's
>> registers is the correct way to represent each port. The port
>> index seems much more useful.
>> 
>> The main reason here is that there are a lot of registers that
>> contain fields for each port - far more than the combination of
>> this node's reg and ctrl-offset (which I assume is an address
>> offset for just one example of this issue) properties can
>> describe. The bit position and bit stride of these fields isn't
>> necessarily the same in each register. Do we want a property like
>> ctrl-offset for every single type of field in every single shared
>> register that describes the location of the relevant data, or
>> just a single "port ID" bit that can be applied to anything?
>> 
>> (Perhaps this isn't so obvious looking at the TRM since it
>> doesn't document all registers, and I'm also looking at the
>> Tegra30 documentation too, which might be more exposed to this -
>> I haven't correlated all the documentation sources to be sure
>> though)
> 
> I agree that maybe adding properties for each bit position or
> register offset may not work out too well. But I think it still
> makes sense to use the base address of the port's registers (see
> below). We could of course add some code to determine the index
> from the base address at initialization time and reuse the index
> where appropriate.

To me, working back from address to ID then using the ID to calculate
some other addresses seems far more icky than just calculating all the
addresses based off of one ID. But, I suppose this doesn't make a huge
practical difference.

>>> compatible = "nvidia,tegra20-pcie-port"; reg = <0x80000000 
>>> 0x00001000>; status = "disabled";
>>> 
>>> #address-cells = <3>; #size-cells = <2>;
>>> 
>>> ranges = <0x81000000 0 0 0x80400000 0 0x00008000   /* I/O */ 
>>> 0x82000000 0 0 0x90000000 0 0x08000000   /* non-prefetchable
>>> memory */ 0xc2000000 0 0 0xa0000000 0 0x08000000>; /*
>>> prefetchable memory */
>> 
>> The values here appear identical for both ports. Surely they
>> should describe just the parts of the overall address space that
>> have been assigned/delegated to the individual port/bridge?
> 
> They're not identical. Port 0 gets the first half and port 1 gets
> the second half of the ranges specified in the parent.

Oh right, I missed some 8s and 0s that looked the same!

>>> While looking into some more code, trying to figure out how to
>>> hook this all up with the device tree I ran into a problem. I
>>> need to actually create a 'struct device' for each of the
>>> ports, so I added the "simple-bus" to the pcie-controller's
>>> "compatible" property. Furthermore, each PCI root port now
>>> becomes a platform_device, which are supported by a new
>>> tegra-pcie-port driver. I'm not sure if "port" is very common
>>> in PCI speek, so something like tegra-pcie-bridge (compatible =
>>> "nvidia,tegra20-pcie-bridge") may be more appropriate?
>> 
>> What is it that drives the need for each port to be a 'struct
>> device'? The current driver supports 2 host ports, yet there's
>> only a single struct device for it. Does the DT code assume a 1:1
>> mapping between struct device and DT node that represents the
>> child bus? If so, perhaps it'd be better to rework that code to
>> accept a DT node as a parameter and call it multiple times,
>> rather than accept a struct device as a parameter and hence need
>> multiple devices?
> 
> It's not so much the DT code, but rather the PCI core and
> ultimately the device model that requires it. Each port is
> basically a PCI host bridge that provides a root PCI bus and the
> device model is used to represent the hierachy of the busses.
> Providing just the DT node isn't going to be enough.

But the existing driver works without /any/ devices, let alone one per
port.

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-14 19:50                                                         ` Stephen Warren
  0 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-14 19:50 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Mitch Bradley, Russell King, linux-pci, devicetree-discuss,
	Rob Herring, Jesse Barnes, Colin Cross, linux-tegra,
	linux-arm-kernel

On 06/14/2012 01:29 PM, Thierry Reding wrote:
> On Thu, Jun 14, 2012 at 12:30:50PM -0600, Stephen Warren wrote:
>> On 06/14/2012 03:19 AM, Thierry Reding wrote:
...
>>> #address-cells = <1>; #size-cells = <1>;
>>> 
>>> pci@80000000 {
>> 
>> I'm still not convinced that using the address of the port's
>> registers is the correct way to represent each port. The port
>> index seems much more useful.
>> 
>> The main reason here is that there are a lot of registers that
>> contain fields for each port - far more than the combination of
>> this node's reg and ctrl-offset (which I assume is an address
>> offset for just one example of this issue) properties can
>> describe. The bit position and bit stride of these fields isn't
>> necessarily the same in each register. Do we want a property like
>> ctrl-offset for every single type of field in every single shared
>> register that describes the location of the relevant data, or
>> just a single "port ID" bit that can be applied to anything?
>> 
>> (Perhaps this isn't so obvious looking at the TRM since it
>> doesn't document all registers, and I'm also looking at the
>> Tegra30 documentation too, which might be more exposed to this -
>> I haven't correlated all the documentation sources to be sure
>> though)
> 
> I agree that maybe adding properties for each bit position or
> register offset may not work out too well. But I think it still
> makes sense to use the base address of the port's registers (see
> below). We could of course add some code to determine the index
> from the base address at initialization time and reuse the index
> where appropriate.

To me, working back from address to ID then using the ID to calculate
some other addresses seems far more icky than just calculating all the
addresses based off of one ID. But, I suppose this doesn't make a huge
practical difference.

>>> compatible = "nvidia,tegra20-pcie-port"; reg = <0x80000000 
>>> 0x00001000>; status = "disabled";
>>> 
>>> #address-cells = <3>; #size-cells = <2>;
>>> 
>>> ranges = <0x81000000 0 0 0x80400000 0 0x00008000   /* I/O */ 
>>> 0x82000000 0 0 0x90000000 0 0x08000000   /* non-prefetchable
>>> memory */ 0xc2000000 0 0 0xa0000000 0 0x08000000>; /*
>>> prefetchable memory */
>> 
>> The values here appear identical for both ports. Surely they
>> should describe just the parts of the overall address space that
>> have been assigned/delegated to the individual port/bridge?
> 
> They're not identical. Port 0 gets the first half and port 1 gets
> the second half of the ranges specified in the parent.

Oh right, I missed some 8s and 0s that looked the same!

>>> While looking into some more code, trying to figure out how to
>>> hook this all up with the device tree I ran into a problem. I
>>> need to actually create a 'struct device' for each of the
>>> ports, so I added the "simple-bus" to the pcie-controller's
>>> "compatible" property. Furthermore, each PCI root port now
>>> becomes a platform_device, which are supported by a new
>>> tegra-pcie-port driver. I'm not sure if "port" is very common
>>> in PCI speek, so something like tegra-pcie-bridge (compatible =
>>> "nvidia,tegra20-pcie-bridge") may be more appropriate?
>> 
>> What is it that drives the need for each port to be a 'struct
>> device'? The current driver supports 2 host ports, yet there's
>> only a single struct device for it. Does the DT code assume a 1:1
>> mapping between struct device and DT node that represents the
>> child bus? If so, perhaps it'd be better to rework that code to
>> accept a DT node as a parameter and call it multiple times,
>> rather than accept a struct device as a parameter and hence need
>> multiple devices?
> 
> It's not so much the DT code, but rather the PCI core and
> ultimately the device model that requires it. Each port is
> basically a PCI host bridge that provides a root PCI bus and the
> device model is used to represent the hierachy of the busses.
> Providing just the DT node isn't going to be enough.

But the existing driver works without /any/ devices, let alone one per
port.

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-14 19:50                                                         ` Stephen Warren
  0 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-14 19:50 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/14/2012 01:29 PM, Thierry Reding wrote:
> On Thu, Jun 14, 2012 at 12:30:50PM -0600, Stephen Warren wrote:
>> On 06/14/2012 03:19 AM, Thierry Reding wrote:
...
>>> #address-cells = <1>; #size-cells = <1>;
>>> 
>>> pci at 80000000 {
>> 
>> I'm still not convinced that using the address of the port's
>> registers is the correct way to represent each port. The port
>> index seems much more useful.
>> 
>> The main reason here is that there are a lot of registers that
>> contain fields for each port - far more than the combination of
>> this node's reg and ctrl-offset (which I assume is an address
>> offset for just one example of this issue) properties can
>> describe. The bit position and bit stride of these fields isn't
>> necessarily the same in each register. Do we want a property like
>> ctrl-offset for every single type of field in every single shared
>> register that describes the location of the relevant data, or
>> just a single "port ID" bit that can be applied to anything?
>> 
>> (Perhaps this isn't so obvious looking at the TRM since it
>> doesn't document all registers, and I'm also looking at the
>> Tegra30 documentation too, which might be more exposed to this -
>> I haven't correlated all the documentation sources to be sure
>> though)
> 
> I agree that maybe adding properties for each bit position or
> register offset may not work out too well. But I think it still
> makes sense to use the base address of the port's registers (see
> below). We could of course add some code to determine the index
> from the base address at initialization time and reuse the index
> where appropriate.

To me, working back from address to ID then using the ID to calculate
some other addresses seems far more icky than just calculating all the
addresses based off of one ID. But, I suppose this doesn't make a huge
practical difference.

>>> compatible = "nvidia,tegra20-pcie-port"; reg = <0x80000000 
>>> 0x00001000>; status = "disabled";
>>> 
>>> #address-cells = <3>; #size-cells = <2>;
>>> 
>>> ranges = <0x81000000 0 0 0x80400000 0 0x00008000   /* I/O */ 
>>> 0x82000000 0 0 0x90000000 0 0x08000000   /* non-prefetchable
>>> memory */ 0xc2000000 0 0 0xa0000000 0 0x08000000>; /*
>>> prefetchable memory */
>> 
>> The values here appear identical for both ports. Surely they
>> should describe just the parts of the overall address space that
>> have been assigned/delegated to the individual port/bridge?
> 
> They're not identical. Port 0 gets the first half and port 1 gets
> the second half of the ranges specified in the parent.

Oh right, I missed some 8s and 0s that looked the same!

>>> While looking into some more code, trying to figure out how to
>>> hook this all up with the device tree I ran into a problem. I
>>> need to actually create a 'struct device' for each of the
>>> ports, so I added the "simple-bus" to the pcie-controller's
>>> "compatible" property. Furthermore, each PCI root port now
>>> becomes a platform_device, which are supported by a new
>>> tegra-pcie-port driver. I'm not sure if "port" is very common
>>> in PCI speek, so something like tegra-pcie-bridge (compatible =
>>> "nvidia,tegra20-pcie-bridge") may be more appropriate?
>> 
>> What is it that drives the need for each port to be a 'struct
>> device'? The current driver supports 2 host ports, yet there's
>> only a single struct device for it. Does the DT code assume a 1:1
>> mapping between struct device and DT node that represents the
>> child bus? If so, perhaps it'd be better to rework that code to
>> accept a DT node as a parameter and call it multiple times,
>> rather than accept a struct device as a parameter and hence need
>> multiple devices?
> 
> It's not so much the DT code, but rather the PCI core and
> ultimately the device model that requires it. Each port is
> basically a PCI host bridge that provides a root PCI bus and the
> device model is used to represent the hierachy of the busses.
> Providing just the DT node isn't going to be enough.

But the existing driver works without /any/ devices, let alone one per
port.

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-14 19:50                                                         ` Stephen Warren
  (?)
@ 2012-06-15  6:12                                                             ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-15  6:12 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Mitch Bradley, Russell King, linux-pci-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Jesse Barnes, Colin Cross, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Arnd Bergmann

[-- Attachment #1: Type: text/plain, Size: 5806 bytes --]

On Thu, Jun 14, 2012 at 01:50:56PM -0600, Stephen Warren wrote:
> On 06/14/2012 01:29 PM, Thierry Reding wrote:
> > On Thu, Jun 14, 2012 at 12:30:50PM -0600, Stephen Warren wrote:
> >> On 06/14/2012 03:19 AM, Thierry Reding wrote:
> ...
> >>> #address-cells = <1>; #size-cells = <1>;
> >>> 
> >>> pci@80000000 {
> >> 
> >> I'm still not convinced that using the address of the port's
> >> registers is the correct way to represent each port. The port
> >> index seems much more useful.
> >> 
> >> The main reason here is that there are a lot of registers that
> >> contain fields for each port - far more than the combination of
> >> this node's reg and ctrl-offset (which I assume is an address
> >> offset for just one example of this issue) properties can
> >> describe. The bit position and bit stride of these fields isn't
> >> necessarily the same in each register. Do we want a property like
> >> ctrl-offset for every single type of field in every single shared
> >> register that describes the location of the relevant data, or
> >> just a single "port ID" bit that can be applied to anything?
> >> 
> >> (Perhaps this isn't so obvious looking at the TRM since it
> >> doesn't document all registers, and I'm also looking at the
> >> Tegra30 documentation too, which might be more exposed to this -
> >> I haven't correlated all the documentation sources to be sure
> >> though)
> > 
> > I agree that maybe adding properties for each bit position or
> > register offset may not work out too well. But I think it still
> > makes sense to use the base address of the port's registers (see
> > below). We could of course add some code to determine the index
> > from the base address at initialization time and reuse the index
> > where appropriate.
> 
> To me, working back from address to ID then using the ID to calculate
> some other addresses seems far more icky than just calculating all the
> addresses based off of one ID. But, I suppose this doesn't make a huge
> practical difference.

This really depends on the device vs. no device decision below. If we can
make it work without needing an extra device for it, then using the index
is certainly better. However, if we instantiate devices from the DT, then
we have the address anyway and adding the index as a property would be
redundant and error prone (what happens if somebody sets the index of the
port at address 0x80000000 to 2?).

> >>> compatible = "nvidia,tegra20-pcie-port"; reg = <0x80000000 
> >>> 0x00001000>; status = "disabled";
> >>> 
> >>> #address-cells = <3>; #size-cells = <2>;
> >>> 
> >>> ranges = <0x81000000 0 0 0x80400000 0 0x00008000   /* I/O */ 
> >>> 0x82000000 0 0 0x90000000 0 0x08000000   /* non-prefetchable
> >>> memory */ 0xc2000000 0 0 0xa0000000 0 0x08000000>; /*
> >>> prefetchable memory */
> >> 
> >> The values here appear identical for both ports. Surely they
> >> should describe just the parts of the overall address space that
> >> have been assigned/delegated to the individual port/bridge?
> > 
> > They're not identical. Port 0 gets the first half and port 1 gets
> > the second half of the ranges specified in the parent.
> 
> Oh right, I missed some 8s and 0s that looked the same!
> 
> >>> While looking into some more code, trying to figure out how to
> >>> hook this all up with the device tree I ran into a problem. I
> >>> need to actually create a 'struct device' for each of the
> >>> ports, so I added the "simple-bus" to the pcie-controller's
> >>> "compatible" property. Furthermore, each PCI root port now
> >>> becomes a platform_device, which are supported by a new
> >>> tegra-pcie-port driver. I'm not sure if "port" is very common
> >>> in PCI speek, so something like tegra-pcie-bridge (compatible =
> >>> "nvidia,tegra20-pcie-bridge") may be more appropriate?
> >> 
> >> What is it that drives the need for each port to be a 'struct
> >> device'? The current driver supports 2 host ports, yet there's
> >> only a single struct device for it. Does the DT code assume a 1:1
> >> mapping between struct device and DT node that represents the
> >> child bus? If so, perhaps it'd be better to rework that code to
> >> accept a DT node as a parameter and call it multiple times,
> >> rather than accept a struct device as a parameter and hence need
> >> multiple devices?
> > 
> > It's not so much the DT code, but rather the PCI core and
> > ultimately the device model that requires it. Each port is
> > basically a PCI host bridge that provides a root PCI bus and the
> > device model is used to represent the hierachy of the busses.
> > Providing just the DT node isn't going to be enough.
> 
> But the existing driver works without /any/ devices, let alone one per
> port.

That doesn't necessarily mean it is correct. The representation of the
device tree (as in the Linux kernel device tree) isn't quite accurate
because you're missing the link of the host bridge to the parent PCIe
controller. It also means that the representation of the kernel device
tree doesn't match the DT representation.

Additionally, if you look at how PCI busses and devices are matched to
their respective DT nodes, the code in drivers/pci/of.c provides a
default implementation of pcibios_get_phb_of_node(), which matches the
struct pci_bus up with the device_node of the parent device.

If we keep the current implementation that passes NULL as parent to the
pci_scan_root_bus() function, then we'll have to provide a custom
implementation of pcibios_get_phb_of_node() which has to go through
similar hoops as the x86 version (see arch/x86/kernel/devicetree.c).
That of course will not contribute to improving the current state of
fragmentation in the PCI subsystem.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-15  6:12                                                             ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-15  6:12 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Mitch Bradley, Russell King, linux-pci, devicetree-discuss,
	Rob Herring, Jesse Barnes, Colin Cross, linux-tegra,
	linux-arm-kernel, Arnd Bergmann

[-- Attachment #1: Type: text/plain, Size: 5806 bytes --]

On Thu, Jun 14, 2012 at 01:50:56PM -0600, Stephen Warren wrote:
> On 06/14/2012 01:29 PM, Thierry Reding wrote:
> > On Thu, Jun 14, 2012 at 12:30:50PM -0600, Stephen Warren wrote:
> >> On 06/14/2012 03:19 AM, Thierry Reding wrote:
> ...
> >>> #address-cells = <1>; #size-cells = <1>;
> >>> 
> >>> pci@80000000 {
> >> 
> >> I'm still not convinced that using the address of the port's
> >> registers is the correct way to represent each port. The port
> >> index seems much more useful.
> >> 
> >> The main reason here is that there are a lot of registers that
> >> contain fields for each port - far more than the combination of
> >> this node's reg and ctrl-offset (which I assume is an address
> >> offset for just one example of this issue) properties can
> >> describe. The bit position and bit stride of these fields isn't
> >> necessarily the same in each register. Do we want a property like
> >> ctrl-offset for every single type of field in every single shared
> >> register that describes the location of the relevant data, or
> >> just a single "port ID" bit that can be applied to anything?
> >> 
> >> (Perhaps this isn't so obvious looking at the TRM since it
> >> doesn't document all registers, and I'm also looking at the
> >> Tegra30 documentation too, which might be more exposed to this -
> >> I haven't correlated all the documentation sources to be sure
> >> though)
> > 
> > I agree that maybe adding properties for each bit position or
> > register offset may not work out too well. But I think it still
> > makes sense to use the base address of the port's registers (see
> > below). We could of course add some code to determine the index
> > from the base address at initialization time and reuse the index
> > where appropriate.
> 
> To me, working back from address to ID then using the ID to calculate
> some other addresses seems far more icky than just calculating all the
> addresses based off of one ID. But, I suppose this doesn't make a huge
> practical difference.

This really depends on the device vs. no device decision below. If we can
make it work without needing an extra device for it, then using the index
is certainly better. However, if we instantiate devices from the DT, then
we have the address anyway and adding the index as a property would be
redundant and error prone (what happens if somebody sets the index of the
port at address 0x80000000 to 2?).

> >>> compatible = "nvidia,tegra20-pcie-port"; reg = <0x80000000 
> >>> 0x00001000>; status = "disabled";
> >>> 
> >>> #address-cells = <3>; #size-cells = <2>;
> >>> 
> >>> ranges = <0x81000000 0 0 0x80400000 0 0x00008000   /* I/O */ 
> >>> 0x82000000 0 0 0x90000000 0 0x08000000   /* non-prefetchable
> >>> memory */ 0xc2000000 0 0 0xa0000000 0 0x08000000>; /*
> >>> prefetchable memory */
> >> 
> >> The values here appear identical for both ports. Surely they
> >> should describe just the parts of the overall address space that
> >> have been assigned/delegated to the individual port/bridge?
> > 
> > They're not identical. Port 0 gets the first half and port 1 gets
> > the second half of the ranges specified in the parent.
> 
> Oh right, I missed some 8s and 0s that looked the same!
> 
> >>> While looking into some more code, trying to figure out how to
> >>> hook this all up with the device tree I ran into a problem. I
> >>> need to actually create a 'struct device' for each of the
> >>> ports, so I added the "simple-bus" to the pcie-controller's
> >>> "compatible" property. Furthermore, each PCI root port now
> >>> becomes a platform_device, which are supported by a new
> >>> tegra-pcie-port driver. I'm not sure if "port" is very common
> >>> in PCI speek, so something like tegra-pcie-bridge (compatible =
> >>> "nvidia,tegra20-pcie-bridge") may be more appropriate?
> >> 
> >> What is it that drives the need for each port to be a 'struct
> >> device'? The current driver supports 2 host ports, yet there's
> >> only a single struct device for it. Does the DT code assume a 1:1
> >> mapping between struct device and DT node that represents the
> >> child bus? If so, perhaps it'd be better to rework that code to
> >> accept a DT node as a parameter and call it multiple times,
> >> rather than accept a struct device as a parameter and hence need
> >> multiple devices?
> > 
> > It's not so much the DT code, but rather the PCI core and
> > ultimately the device model that requires it. Each port is
> > basically a PCI host bridge that provides a root PCI bus and the
> > device model is used to represent the hierachy of the busses.
> > Providing just the DT node isn't going to be enough.
> 
> But the existing driver works without /any/ devices, let alone one per
> port.

That doesn't necessarily mean it is correct. The representation of the
device tree (as in the Linux kernel device tree) isn't quite accurate
because you're missing the link of the host bridge to the parent PCIe
controller. It also means that the representation of the kernel device
tree doesn't match the DT representation.

Additionally, if you look at how PCI busses and devices are matched to
their respective DT nodes, the code in drivers/pci/of.c provides a
default implementation of pcibios_get_phb_of_node(), which matches the
struct pci_bus up with the device_node of the parent device.

If we keep the current implementation that passes NULL as parent to the
pci_scan_root_bus() function, then we'll have to provide a custom
implementation of pcibios_get_phb_of_node() which has to go through
similar hoops as the x86 version (see arch/x86/kernel/devicetree.c).
That of course will not contribute to improving the current state of
fragmentation in the PCI subsystem.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-15  6:12                                                             ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-15  6:12 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jun 14, 2012 at 01:50:56PM -0600, Stephen Warren wrote:
> On 06/14/2012 01:29 PM, Thierry Reding wrote:
> > On Thu, Jun 14, 2012 at 12:30:50PM -0600, Stephen Warren wrote:
> >> On 06/14/2012 03:19 AM, Thierry Reding wrote:
> ...
> >>> #address-cells = <1>; #size-cells = <1>;
> >>> 
> >>> pci at 80000000 {
> >> 
> >> I'm still not convinced that using the address of the port's
> >> registers is the correct way to represent each port. The port
> >> index seems much more useful.
> >> 
> >> The main reason here is that there are a lot of registers that
> >> contain fields for each port - far more than the combination of
> >> this node's reg and ctrl-offset (which I assume is an address
> >> offset for just one example of this issue) properties can
> >> describe. The bit position and bit stride of these fields isn't
> >> necessarily the same in each register. Do we want a property like
> >> ctrl-offset for every single type of field in every single shared
> >> register that describes the location of the relevant data, or
> >> just a single "port ID" bit that can be applied to anything?
> >> 
> >> (Perhaps this isn't so obvious looking at the TRM since it
> >> doesn't document all registers, and I'm also looking at the
> >> Tegra30 documentation too, which might be more exposed to this -
> >> I haven't correlated all the documentation sources to be sure
> >> though)
> > 
> > I agree that maybe adding properties for each bit position or
> > register offset may not work out too well. But I think it still
> > makes sense to use the base address of the port's registers (see
> > below). We could of course add some code to determine the index
> > from the base address at initialization time and reuse the index
> > where appropriate.
> 
> To me, working back from address to ID then using the ID to calculate
> some other addresses seems far more icky than just calculating all the
> addresses based off of one ID. But, I suppose this doesn't make a huge
> practical difference.

This really depends on the device vs. no device decision below. If we can
make it work without needing an extra device for it, then using the index
is certainly better. However, if we instantiate devices from the DT, then
we have the address anyway and adding the index as a property would be
redundant and error prone (what happens if somebody sets the index of the
port at address 0x80000000 to 2?).

> >>> compatible = "nvidia,tegra20-pcie-port"; reg = <0x80000000 
> >>> 0x00001000>; status = "disabled";
> >>> 
> >>> #address-cells = <3>; #size-cells = <2>;
> >>> 
> >>> ranges = <0x81000000 0 0 0x80400000 0 0x00008000   /* I/O */ 
> >>> 0x82000000 0 0 0x90000000 0 0x08000000   /* non-prefetchable
> >>> memory */ 0xc2000000 0 0 0xa0000000 0 0x08000000>; /*
> >>> prefetchable memory */
> >> 
> >> The values here appear identical for both ports. Surely they
> >> should describe just the parts of the overall address space that
> >> have been assigned/delegated to the individual port/bridge?
> > 
> > They're not identical. Port 0 gets the first half and port 1 gets
> > the second half of the ranges specified in the parent.
> 
> Oh right, I missed some 8s and 0s that looked the same!
> 
> >>> While looking into some more code, trying to figure out how to
> >>> hook this all up with the device tree I ran into a problem. I
> >>> need to actually create a 'struct device' for each of the
> >>> ports, so I added the "simple-bus" to the pcie-controller's
> >>> "compatible" property. Furthermore, each PCI root port now
> >>> becomes a platform_device, which are supported by a new
> >>> tegra-pcie-port driver. I'm not sure if "port" is very common
> >>> in PCI speek, so something like tegra-pcie-bridge (compatible =
> >>> "nvidia,tegra20-pcie-bridge") may be more appropriate?
> >> 
> >> What is it that drives the need for each port to be a 'struct
> >> device'? The current driver supports 2 host ports, yet there's
> >> only a single struct device for it. Does the DT code assume a 1:1
> >> mapping between struct device and DT node that represents the
> >> child bus? If so, perhaps it'd be better to rework that code to
> >> accept a DT node as a parameter and call it multiple times,
> >> rather than accept a struct device as a parameter and hence need
> >> multiple devices?
> > 
> > It's not so much the DT code, but rather the PCI core and
> > ultimately the device model that requires it. Each port is
> > basically a PCI host bridge that provides a root PCI bus and the
> > device model is used to represent the hierachy of the busses.
> > Providing just the DT node isn't going to be enough.
> 
> But the existing driver works without /any/ devices, let alone one per
> port.

That doesn't necessarily mean it is correct. The representation of the
device tree (as in the Linux kernel device tree) isn't quite accurate
because you're missing the link of the host bridge to the parent PCIe
controller. It also means that the representation of the kernel device
tree doesn't match the DT representation.

Additionally, if you look at how PCI busses and devices are matched to
their respective DT nodes, the code in drivers/pci/of.c provides a
default implementation of pcibios_get_phb_of_node(), which matches the
struct pci_bus up with the device_node of the parent device.

If we keep the current implementation that passes NULL as parent to the
pci_scan_root_bus() function, then we'll have to provide a custom
implementation of pcibios_get_phb_of_node() which has to go through
similar hoops as the x86 version (see arch/x86/kernel/devicetree.c).
That of course will not contribute to improving the current state of
fragmentation in the PCI subsystem.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120615/0fe915be/attachment-0001.sig>

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-15  6:12                                                             ` Thierry Reding
@ 2012-06-19 13:30                                                               ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-19 13:30 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Mitch Bradley, Russell King, linux-pci, devicetree-discuss,
	Rob Herring, Jesse Barnes, Colin Cross, linux-tegra,
	linux-arm-kernel, Arnd Bergmann

[-- Attachment #1: Type: text/plain, Size: 8901 bytes --]

On Fri, Jun 15, 2012 at 08:12:36AM +0200, Thierry Reding wrote:
> On Thu, Jun 14, 2012 at 01:50:56PM -0600, Stephen Warren wrote:
> > On 06/14/2012 01:29 PM, Thierry Reding wrote:
> > > On Thu, Jun 14, 2012 at 12:30:50PM -0600, Stephen Warren wrote:
> > >> On 06/14/2012 03:19 AM, Thierry Reding wrote:
> > ...
> > >>> #address-cells = <1>; #size-cells = <1>;
> > >>> 
> > >>> pci@80000000 {
> > >> 
> > >> I'm still not convinced that using the address of the port's
> > >> registers is the correct way to represent each port. The port
> > >> index seems much more useful.
> > >> 
> > >> The main reason here is that there are a lot of registers that
> > >> contain fields for each port - far more than the combination of
> > >> this node's reg and ctrl-offset (which I assume is an address
> > >> offset for just one example of this issue) properties can
> > >> describe. The bit position and bit stride of these fields isn't
> > >> necessarily the same in each register. Do we want a property like
> > >> ctrl-offset for every single type of field in every single shared
> > >> register that describes the location of the relevant data, or
> > >> just a single "port ID" bit that can be applied to anything?
> > >> 
> > >> (Perhaps this isn't so obvious looking at the TRM since it
> > >> doesn't document all registers, and I'm also looking at the
> > >> Tegra30 documentation too, which might be more exposed to this -
> > >> I haven't correlated all the documentation sources to be sure
> > >> though)
> > > 
> > > I agree that maybe adding properties for each bit position or
> > > register offset may not work out too well. But I think it still
> > > makes sense to use the base address of the port's registers (see
> > > below). We could of course add some code to determine the index
> > > from the base address at initialization time and reuse the index
> > > where appropriate.
> > 
> > To me, working back from address to ID then using the ID to calculate
> > some other addresses seems far more icky than just calculating all the
> > addresses based off of one ID. But, I suppose this doesn't make a huge
> > practical difference.
> 
> This really depends on the device vs. no device decision below. If we can
> make it work without needing an extra device for it, then using the index
> is certainly better. However, if we instantiate devices from the DT, then
> we have the address anyway and adding the index as a property would be
> redundant and error prone (what happens if somebody sets the index of the
> port at address 0x80000000 to 2?).

An additional problem with this is that we'd have to add the following
to the pcie-controller node:

	#address-cells = <1>;
	#size-cells = <0>;

This will conflict with the "ranges" property, because suddenly we can
no longer map the regions properly. Maybe Mitch can comment on whether
this is possible or not?

To make it clearer what I'm talking about, here's the DT snippet again
(with the compatible property removed from the pci@ nodes because they
are no longer probed by a driver, the "simple-bus" removed from the
pcie-controller node's compatible property removed and its #address-
and #size-cells properties adjusted as described above).

	pcie-controller {
		compatible = "nvidia,tegra20-pcie";
		reg = <0x80003000 0x00000800   /* PADS registers */
		       0x80003800 0x00000200   /* AFI registers */
		       0x80004000 0x00100000   /* configuration space */
		       0x80104000 0x00100000>; /* extended configuration space */
		interrupts = <0 98 0x04   /* controller interrupt */
			      0 99 0x04>; /* MSI interrupt */
		status = "disabled";

		ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */
			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */

		#address-cells = <1>;
		#size-cells = <0>;

		pci@0 {
			reg = <2>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;

			ranges = <0x81000000 0 0 0x80400000 0 0x00008000   /* I/O */
				  0x82000000 0 0 0x90000000 0 0x08000000   /* non-prefetchable memory */
				  0xc2000000 0 0 0xa0000000 0 0x08000000>; /* prefetchable memory */

			nvidia,ctrl-offset = <0x110>;
			nvidia,num-lanes = <2>;
		};

		pci@1 {
			reg = <1>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;

			ranges = <0x81000000 0 0 0x80408000 0 0x00008000   /* I/O */
				  0x82000000 0 0 0x98000000 0 0x08000000   /* non-prefetchable memory */
				  0xc2000000 0 0 0xa8000000 0 0x08000000>; /* prefetchable memory */

			nvidia,ctrl-offset = <0x118>;
			nvidia,num-lanes = <2>;
		};
	};

AIUI none of the ranges properties are valid anymore, because the bus
represented by pcie-controller no longer reflects the truth, namely that
it translates the CPU address space to the PCI address space.

> > >>> compatible = "nvidia,tegra20-pcie-port"; reg = <0x80000000 
> > >>> 0x00001000>; status = "disabled";
> > >>> 
> > >>> #address-cells = <3>; #size-cells = <2>;
> > >>> 
> > >>> ranges = <0x81000000 0 0 0x80400000 0 0x00008000   /* I/O */ 
> > >>> 0x82000000 0 0 0x90000000 0 0x08000000   /* non-prefetchable
> > >>> memory */ 0xc2000000 0 0 0xa0000000 0 0x08000000>; /*
> > >>> prefetchable memory */
> > >> 
> > >> The values here appear identical for both ports. Surely they
> > >> should describe just the parts of the overall address space that
> > >> have been assigned/delegated to the individual port/bridge?
> > > 
> > > They're not identical. Port 0 gets the first half and port 1 gets
> > > the second half of the ranges specified in the parent.
> > 
> > Oh right, I missed some 8s and 0s that looked the same!
> > 
> > >>> While looking into some more code, trying to figure out how to
> > >>> hook this all up with the device tree I ran into a problem. I
> > >>> need to actually create a 'struct device' for each of the
> > >>> ports, so I added the "simple-bus" to the pcie-controller's
> > >>> "compatible" property. Furthermore, each PCI root port now
> > >>> becomes a platform_device, which are supported by a new
> > >>> tegra-pcie-port driver. I'm not sure if "port" is very common
> > >>> in PCI speek, so something like tegra-pcie-bridge (compatible =
> > >>> "nvidia,tegra20-pcie-bridge") may be more appropriate?
> > >> 
> > >> What is it that drives the need for each port to be a 'struct
> > >> device'? The current driver supports 2 host ports, yet there's
> > >> only a single struct device for it. Does the DT code assume a 1:1
> > >> mapping between struct device and DT node that represents the
> > >> child bus? If so, perhaps it'd be better to rework that code to
> > >> accept a DT node as a parameter and call it multiple times,
> > >> rather than accept a struct device as a parameter and hence need
> > >> multiple devices?
> > > 
> > > It's not so much the DT code, but rather the PCI core and
> > > ultimately the device model that requires it. Each port is
> > > basically a PCI host bridge that provides a root PCI bus and the
> > > device model is used to represent the hierachy of the busses.
> > > Providing just the DT node isn't going to be enough.
> > 
> > But the existing driver works without /any/ devices, let alone one per
> > port.
> 
> That doesn't necessarily mean it is correct. The representation of the
> device tree (as in the Linux kernel device tree) isn't quite accurate
> because you're missing the link of the host bridge to the parent PCIe
> controller. It also means that the representation of the kernel device
> tree doesn't match the DT representation.
> 
> Additionally, if you look at how PCI busses and devices are matched to
> their respective DT nodes, the code in drivers/pci/of.c provides a
> default implementation of pcibios_get_phb_of_node(), which matches the
> struct pci_bus up with the device_node of the parent device.
> 
> If we keep the current implementation that passes NULL as parent to the
> pci_scan_root_bus() function, then we'll have to provide a custom
> implementation of pcibios_get_phb_of_node() which has to go through
> similar hoops as the x86 version (see arch/x86/kernel/devicetree.c).
> That of course will not contribute to improving the current state of
> fragmentation in the PCI subsystem.

I suppose this could work if we passed the 'struct device' of the pcie-
controller node as the parent for all ports instead of requiring a
separate device for each port. That way the pcie-controller would get to
be a parent for two/three bridges on Tegra20/30.

I'll have a go at the implementation, but I'm busy with other stuff and
it will probably be some time before I can get back on it.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-19 13:30                                                               ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-19 13:30 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jun 15, 2012 at 08:12:36AM +0200, Thierry Reding wrote:
> On Thu, Jun 14, 2012 at 01:50:56PM -0600, Stephen Warren wrote:
> > On 06/14/2012 01:29 PM, Thierry Reding wrote:
> > > On Thu, Jun 14, 2012 at 12:30:50PM -0600, Stephen Warren wrote:
> > >> On 06/14/2012 03:19 AM, Thierry Reding wrote:
> > ...
> > >>> #address-cells = <1>; #size-cells = <1>;
> > >>> 
> > >>> pci at 80000000 {
> > >> 
> > >> I'm still not convinced that using the address of the port's
> > >> registers is the correct way to represent each port. The port
> > >> index seems much more useful.
> > >> 
> > >> The main reason here is that there are a lot of registers that
> > >> contain fields for each port - far more than the combination of
> > >> this node's reg and ctrl-offset (which I assume is an address
> > >> offset for just one example of this issue) properties can
> > >> describe. The bit position and bit stride of these fields isn't
> > >> necessarily the same in each register. Do we want a property like
> > >> ctrl-offset for every single type of field in every single shared
> > >> register that describes the location of the relevant data, or
> > >> just a single "port ID" bit that can be applied to anything?
> > >> 
> > >> (Perhaps this isn't so obvious looking at the TRM since it
> > >> doesn't document all registers, and I'm also looking at the
> > >> Tegra30 documentation too, which might be more exposed to this -
> > >> I haven't correlated all the documentation sources to be sure
> > >> though)
> > > 
> > > I agree that maybe adding properties for each bit position or
> > > register offset may not work out too well. But I think it still
> > > makes sense to use the base address of the port's registers (see
> > > below). We could of course add some code to determine the index
> > > from the base address at initialization time and reuse the index
> > > where appropriate.
> > 
> > To me, working back from address to ID then using the ID to calculate
> > some other addresses seems far more icky than just calculating all the
> > addresses based off of one ID. But, I suppose this doesn't make a huge
> > practical difference.
> 
> This really depends on the device vs. no device decision below. If we can
> make it work without needing an extra device for it, then using the index
> is certainly better. However, if we instantiate devices from the DT, then
> we have the address anyway and adding the index as a property would be
> redundant and error prone (what happens if somebody sets the index of the
> port at address 0x80000000 to 2?).

An additional problem with this is that we'd have to add the following
to the pcie-controller node:

	#address-cells = <1>;
	#size-cells = <0>;

This will conflict with the "ranges" property, because suddenly we can
no longer map the regions properly. Maybe Mitch can comment on whether
this is possible or not?

To make it clearer what I'm talking about, here's the DT snippet again
(with the compatible property removed from the pci@ nodes because they
are no longer probed by a driver, the "simple-bus" removed from the
pcie-controller node's compatible property removed and its #address-
and #size-cells properties adjusted as described above).

	pcie-controller {
		compatible = "nvidia,tegra20-pcie";
		reg = <0x80003000 0x00000800   /* PADS registers */
		       0x80003800 0x00000200   /* AFI registers */
		       0x80004000 0x00100000   /* configuration space */
		       0x80104000 0x00100000>; /* extended configuration space */
		interrupts = <0 98 0x04   /* controller interrupt */
			      0 99 0x04>; /* MSI interrupt */
		status = "disabled";

		ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */
			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */

		#address-cells = <1>;
		#size-cells = <0>;

		pci at 0 {
			reg = <2>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;

			ranges = <0x81000000 0 0 0x80400000 0 0x00008000   /* I/O */
				  0x82000000 0 0 0x90000000 0 0x08000000   /* non-prefetchable memory */
				  0xc2000000 0 0 0xa0000000 0 0x08000000>; /* prefetchable memory */

			nvidia,ctrl-offset = <0x110>;
			nvidia,num-lanes = <2>;
		};

		pci at 1 {
			reg = <1>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;

			ranges = <0x81000000 0 0 0x80408000 0 0x00008000   /* I/O */
				  0x82000000 0 0 0x98000000 0 0x08000000   /* non-prefetchable memory */
				  0xc2000000 0 0 0xa8000000 0 0x08000000>; /* prefetchable memory */

			nvidia,ctrl-offset = <0x118>;
			nvidia,num-lanes = <2>;
		};
	};

AIUI none of the ranges properties are valid anymore, because the bus
represented by pcie-controller no longer reflects the truth, namely that
it translates the CPU address space to the PCI address space.

> > >>> compatible = "nvidia,tegra20-pcie-port"; reg = <0x80000000 
> > >>> 0x00001000>; status = "disabled";
> > >>> 
> > >>> #address-cells = <3>; #size-cells = <2>;
> > >>> 
> > >>> ranges = <0x81000000 0 0 0x80400000 0 0x00008000   /* I/O */ 
> > >>> 0x82000000 0 0 0x90000000 0 0x08000000   /* non-prefetchable
> > >>> memory */ 0xc2000000 0 0 0xa0000000 0 0x08000000>; /*
> > >>> prefetchable memory */
> > >> 
> > >> The values here appear identical for both ports. Surely they
> > >> should describe just the parts of the overall address space that
> > >> have been assigned/delegated to the individual port/bridge?
> > > 
> > > They're not identical. Port 0 gets the first half and port 1 gets
> > > the second half of the ranges specified in the parent.
> > 
> > Oh right, I missed some 8s and 0s that looked the same!
> > 
> > >>> While looking into some more code, trying to figure out how to
> > >>> hook this all up with the device tree I ran into a problem. I
> > >>> need to actually create a 'struct device' for each of the
> > >>> ports, so I added the "simple-bus" to the pcie-controller's
> > >>> "compatible" property. Furthermore, each PCI root port now
> > >>> becomes a platform_device, which are supported by a new
> > >>> tegra-pcie-port driver. I'm not sure if "port" is very common
> > >>> in PCI speek, so something like tegra-pcie-bridge (compatible =
> > >>> "nvidia,tegra20-pcie-bridge") may be more appropriate?
> > >> 
> > >> What is it that drives the need for each port to be a 'struct
> > >> device'? The current driver supports 2 host ports, yet there's
> > >> only a single struct device for it. Does the DT code assume a 1:1
> > >> mapping between struct device and DT node that represents the
> > >> child bus? If so, perhaps it'd be better to rework that code to
> > >> accept a DT node as a parameter and call it multiple times,
> > >> rather than accept a struct device as a parameter and hence need
> > >> multiple devices?
> > > 
> > > It's not so much the DT code, but rather the PCI core and
> > > ultimately the device model that requires it. Each port is
> > > basically a PCI host bridge that provides a root PCI bus and the
> > > device model is used to represent the hierachy of the busses.
> > > Providing just the DT node isn't going to be enough.
> > 
> > But the existing driver works without /any/ devices, let alone one per
> > port.
> 
> That doesn't necessarily mean it is correct. The representation of the
> device tree (as in the Linux kernel device tree) isn't quite accurate
> because you're missing the link of the host bridge to the parent PCIe
> controller. It also means that the representation of the kernel device
> tree doesn't match the DT representation.
> 
> Additionally, if you look at how PCI busses and devices are matched to
> their respective DT nodes, the code in drivers/pci/of.c provides a
> default implementation of pcibios_get_phb_of_node(), which matches the
> struct pci_bus up with the device_node of the parent device.
> 
> If we keep the current implementation that passes NULL as parent to the
> pci_scan_root_bus() function, then we'll have to provide a custom
> implementation of pcibios_get_phb_of_node() which has to go through
> similar hoops as the x86 version (see arch/x86/kernel/devicetree.c).
> That of course will not contribute to improving the current state of
> fragmentation in the PCI subsystem.

I suppose this could work if we passed the 'struct device' of the pcie-
controller node as the parent for all ports instead of requiring a
separate device for each port. That way the pcie-controller would get to
be a parent for two/three bridges on Tegra20/30.

I'll have a go at the implementation, but I'm busy with other stuff and
it will probably be some time before I can get back on it.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120619/7b0150ac/attachment.sig>

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-19 13:30                                                               ` Thierry Reding
  (?)
@ 2012-06-19 16:40                                                                   ` Stephen Warren
  -1 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-19 16:40 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Mitch Bradley, Russell King, linux-pci-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Jesse Barnes, Colin Cross, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Arnd Bergmann

On 06/19/2012 07:30 AM, Thierry Reding wrote:
> On Fri, Jun 15, 2012 at 08:12:36AM +0200, Thierry Reding wrote:
>> On Thu, Jun 14, 2012 at 01:50:56PM -0600, Stephen Warren wrote:
...
>>> To me, working back from address to ID then using the ID to calculate
>>> some other addresses seems far more icky than just calculating all the
>>> addresses based off of one ID. But, I suppose this doesn't make a huge
>>> practical difference.
>>
>> This really depends on the device vs. no device decision below. If we can
>> make it work without needing an extra device for it, then using the index
>> is certainly better. However, if we instantiate devices from the DT, then
>> we have the address anyway and adding the index as a property would be
>> redundant and error prone (what happens if somebody sets the index of the
>> port at address 0x80000000 to 2?).
> 
> An additional problem with this is that we'd have to add the following
> to the pcie-controller node:
> 
> 	#address-cells = <1>;
> 	#size-cells = <0>;
> 
> This will conflict with the "ranges" property, because suddenly we can
> no longer map the regions properly. Maybe Mitch can comment on whether
> this is possible or not?
> 
> To make it clearer what I'm talking about, here's the DT snippet again
> (with the compatible property removed from the pci@ nodes because they
> are no longer probed by a driver, the "simple-bus" removed from the
> pcie-controller node's compatible property removed and its #address-
> and #size-cells properties adjusted as described above).
> 
> 	pcie-controller {
> 		compatible = "nvidia,tegra20-pcie";
> 		reg = <0x80003000 0x00000800   /* PADS registers */
> 		       0x80003800 0x00000200   /* AFI registers */
> 		       0x80004000 0x00100000   /* configuration space */
> 		       0x80104000 0x00100000>; /* extended configuration space */
> 		interrupts = <0 98 0x04   /* controller interrupt */
> 			      0 99 0x04>; /* MSI interrupt */
> 		status = "disabled";
> 
> 		ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */
> 			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
> 			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
> 			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
> 
> 		#address-cells = <1>;
> 		#size-cells = <0>;
> 
> 		pci@0 {
> 			reg = <2>;
> 			status = "disabled";
> 
> 			#address-cells = <3>;
> 			#size-cells = <2>;
> 
> 			ranges = <0x81000000 0 0 0x80400000 0 0x00008000   /* I/O */
> 				  0x82000000 0 0 0x90000000 0 0x08000000   /* non-prefetchable memory */
> 				  0xc2000000 0 0 0xa0000000 0 0x08000000>; /* prefetchable memory */
> 
> 			nvidia,ctrl-offset = <0x110>;
> 			nvidia,num-lanes = <2>;
> 		};
> 
> 		pci@1 {
> 			reg = <1>;
> 			status = "disabled";
> 
> 			#address-cells = <3>;
> 			#size-cells = <2>;
> 
> 			ranges = <0x81000000 0 0 0x80408000 0 0x00008000   /* I/O */
> 				  0x82000000 0 0 0x98000000 0 0x08000000   /* non-prefetchable memory */
> 				  0xc2000000 0 0 0xa8000000 0 0x08000000>; /* prefetchable memory */
> 
> 			nvidia,ctrl-offset = <0x118>;
> 			nvidia,num-lanes = <2>;
> 		};
> 	};
> 
> AIUI none of the ranges properties are valid anymore, because the bus
> represented by pcie-controller no longer reflects the truth, namely that
> it translates the CPU address space to the PCI address space.

Yes, I imagine that's a show-stopper for this approach.

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-19 16:40                                                                   ` Stephen Warren
  0 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-19 16:40 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Mitch Bradley, Russell King, linux-pci, devicetree-discuss,
	Rob Herring, Jesse Barnes, Colin Cross, linux-tegra,
	linux-arm-kernel, Arnd Bergmann

On 06/19/2012 07:30 AM, Thierry Reding wrote:
> On Fri, Jun 15, 2012 at 08:12:36AM +0200, Thierry Reding wrote:
>> On Thu, Jun 14, 2012 at 01:50:56PM -0600, Stephen Warren wrote:
...
>>> To me, working back from address to ID then using the ID to calculate
>>> some other addresses seems far more icky than just calculating all the
>>> addresses based off of one ID. But, I suppose this doesn't make a huge
>>> practical difference.
>>
>> This really depends on the device vs. no device decision below. If we can
>> make it work without needing an extra device for it, then using the index
>> is certainly better. However, if we instantiate devices from the DT, then
>> we have the address anyway and adding the index as a property would be
>> redundant and error prone (what happens if somebody sets the index of the
>> port at address 0x80000000 to 2?).
> 
> An additional problem with this is that we'd have to add the following
> to the pcie-controller node:
> 
> 	#address-cells = <1>;
> 	#size-cells = <0>;
> 
> This will conflict with the "ranges" property, because suddenly we can
> no longer map the regions properly. Maybe Mitch can comment on whether
> this is possible or not?
> 
> To make it clearer what I'm talking about, here's the DT snippet again
> (with the compatible property removed from the pci@ nodes because they
> are no longer probed by a driver, the "simple-bus" removed from the
> pcie-controller node's compatible property removed and its #address-
> and #size-cells properties adjusted as described above).
> 
> 	pcie-controller {
> 		compatible = "nvidia,tegra20-pcie";
> 		reg = <0x80003000 0x00000800   /* PADS registers */
> 		       0x80003800 0x00000200   /* AFI registers */
> 		       0x80004000 0x00100000   /* configuration space */
> 		       0x80104000 0x00100000>; /* extended configuration space */
> 		interrupts = <0 98 0x04   /* controller interrupt */
> 			      0 99 0x04>; /* MSI interrupt */
> 		status = "disabled";
> 
> 		ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */
> 			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
> 			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
> 			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
> 
> 		#address-cells = <1>;
> 		#size-cells = <0>;
> 
> 		pci@0 {
> 			reg = <2>;
> 			status = "disabled";
> 
> 			#address-cells = <3>;
> 			#size-cells = <2>;
> 
> 			ranges = <0x81000000 0 0 0x80400000 0 0x00008000   /* I/O */
> 				  0x82000000 0 0 0x90000000 0 0x08000000   /* non-prefetchable memory */
> 				  0xc2000000 0 0 0xa0000000 0 0x08000000>; /* prefetchable memory */
> 
> 			nvidia,ctrl-offset = <0x110>;
> 			nvidia,num-lanes = <2>;
> 		};
> 
> 		pci@1 {
> 			reg = <1>;
> 			status = "disabled";
> 
> 			#address-cells = <3>;
> 			#size-cells = <2>;
> 
> 			ranges = <0x81000000 0 0 0x80408000 0 0x00008000   /* I/O */
> 				  0x82000000 0 0 0x98000000 0 0x08000000   /* non-prefetchable memory */
> 				  0xc2000000 0 0 0xa8000000 0 0x08000000>; /* prefetchable memory */
> 
> 			nvidia,ctrl-offset = <0x118>;
> 			nvidia,num-lanes = <2>;
> 		};
> 	};
> 
> AIUI none of the ranges properties are valid anymore, because the bus
> represented by pcie-controller no longer reflects the truth, namely that
> it translates the CPU address space to the PCI address space.

Yes, I imagine that's a show-stopper for this approach.

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-19 16:40                                                                   ` Stephen Warren
  0 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-19 16:40 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/19/2012 07:30 AM, Thierry Reding wrote:
> On Fri, Jun 15, 2012 at 08:12:36AM +0200, Thierry Reding wrote:
>> On Thu, Jun 14, 2012 at 01:50:56PM -0600, Stephen Warren wrote:
...
>>> To me, working back from address to ID then using the ID to calculate
>>> some other addresses seems far more icky than just calculating all the
>>> addresses based off of one ID. But, I suppose this doesn't make a huge
>>> practical difference.
>>
>> This really depends on the device vs. no device decision below. If we can
>> make it work without needing an extra device for it, then using the index
>> is certainly better. However, if we instantiate devices from the DT, then
>> we have the address anyway and adding the index as a property would be
>> redundant and error prone (what happens if somebody sets the index of the
>> port at address 0x80000000 to 2?).
> 
> An additional problem with this is that we'd have to add the following
> to the pcie-controller node:
> 
> 	#address-cells = <1>;
> 	#size-cells = <0>;
> 
> This will conflict with the "ranges" property, because suddenly we can
> no longer map the regions properly. Maybe Mitch can comment on whether
> this is possible or not?
> 
> To make it clearer what I'm talking about, here's the DT snippet again
> (with the compatible property removed from the pci@ nodes because they
> are no longer probed by a driver, the "simple-bus" removed from the
> pcie-controller node's compatible property removed and its #address-
> and #size-cells properties adjusted as described above).
> 
> 	pcie-controller {
> 		compatible = "nvidia,tegra20-pcie";
> 		reg = <0x80003000 0x00000800   /* PADS registers */
> 		       0x80003800 0x00000200   /* AFI registers */
> 		       0x80004000 0x00100000   /* configuration space */
> 		       0x80104000 0x00100000>; /* extended configuration space */
> 		interrupts = <0 98 0x04   /* controller interrupt */
> 			      0 99 0x04>; /* MSI interrupt */
> 		status = "disabled";
> 
> 		ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */
> 			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
> 			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
> 			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
> 
> 		#address-cells = <1>;
> 		#size-cells = <0>;
> 
> 		pci at 0 {
> 			reg = <2>;
> 			status = "disabled";
> 
> 			#address-cells = <3>;
> 			#size-cells = <2>;
> 
> 			ranges = <0x81000000 0 0 0x80400000 0 0x00008000   /* I/O */
> 				  0x82000000 0 0 0x90000000 0 0x08000000   /* non-prefetchable memory */
> 				  0xc2000000 0 0 0xa0000000 0 0x08000000>; /* prefetchable memory */
> 
> 			nvidia,ctrl-offset = <0x110>;
> 			nvidia,num-lanes = <2>;
> 		};
> 
> 		pci at 1 {
> 			reg = <1>;
> 			status = "disabled";
> 
> 			#address-cells = <3>;
> 			#size-cells = <2>;
> 
> 			ranges = <0x81000000 0 0 0x80408000 0 0x00008000   /* I/O */
> 				  0x82000000 0 0 0x98000000 0 0x08000000   /* non-prefetchable memory */
> 				  0xc2000000 0 0 0xa8000000 0 0x08000000>; /* prefetchable memory */
> 
> 			nvidia,ctrl-offset = <0x118>;
> 			nvidia,num-lanes = <2>;
> 		};
> 	};
> 
> AIUI none of the ranges properties are valid anymore, because the bus
> represented by pcie-controller no longer reflects the truth, namely that
> it translates the CPU address space to the PCI address space.

Yes, I imagine that's a show-stopper for this approach.

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-19 13:30                                                               ` Thierry Reding
@ 2012-06-19 21:31                                                                 ` Mitch Bradley
  -1 siblings, 0 replies; 249+ messages in thread
From: Mitch Bradley @ 2012-06-19 21:31 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Stephen Warren, Russell King, linux-pci, devicetree-discuss,
	Rob Herring, Jesse Barnes, Colin Cross, linux-tegra,
	linux-arm-kernel, Arnd Bergmann

On 6/19/2012 3:30 AM, Thierry Reding wrote:
> On Fri, Jun 15, 2012 at 08:12:36AM +0200, Thierry Reding wrote:
>> On Thu, Jun 14, 2012 at 01:50:56PM -0600, Stephen Warren wrote:
>>> On 06/14/2012 01:29 PM, Thierry Reding wrote:
>>>> On Thu, Jun 14, 2012 at 12:30:50PM -0600, Stephen Warren wrote:
>>>>> On 06/14/2012 03:19 AM, Thierry Reding wrote:
>>> ...
>>>>>> #address-cells = <1>; #size-cells = <1>;
>>>>>>
>>>>>> pci@80000000 {
>>>>>
>>>>> I'm still not convinced that using the address of the port's
>>>>> registers is the correct way to represent each port. The port
>>>>> index seems much more useful.
>>>>>
>>>>> The main reason here is that there are a lot of registers that
>>>>> contain fields for each port - far more than the combination of
>>>>> this node's reg and ctrl-offset (which I assume is an address
>>>>> offset for just one example of this issue) properties can
>>>>> describe. The bit position and bit stride of these fields isn't
>>>>> necessarily the same in each register. Do we want a property like
>>>>> ctrl-offset for every single type of field in every single shared
>>>>> register that describes the location of the relevant data, or
>>>>> just a single "port ID" bit that can be applied to anything?
>>>>>
>>>>> (Perhaps this isn't so obvious looking at the TRM since it
>>>>> doesn't document all registers, and I'm also looking at the
>>>>> Tegra30 documentation too, which might be more exposed to this -
>>>>> I haven't correlated all the documentation sources to be sure
>>>>> though)
>>>>
>>>> I agree that maybe adding properties for each bit position or
>>>> register offset may not work out too well. But I think it still
>>>> makes sense to use the base address of the port's registers (see
>>>> below). We could of course add some code to determine the index
>>>> from the base address at initialization time and reuse the index
>>>> where appropriate.
>>>
>>> To me, working back from address to ID then using the ID to calculate
>>> some other addresses seems far more icky than just calculating all the
>>> addresses based off of one ID. But, I suppose this doesn't make a huge
>>> practical difference.
>>
>> This really depends on the device vs. no device decision below. If we can
>> make it work without needing an extra device for it, then using the index
>> is certainly better. However, if we instantiate devices from the DT, then
>> we have the address anyway and adding the index as a property would be
>> redundant and error prone (what happens if somebody sets the index of the
>> port at address 0x80000000 to 2?).
>
> An additional problem with this is that we'd have to add the following
> to the pcie-controller node:
>
> 	#address-cells = <1>;
> 	#size-cells = <0>;
>
> This will conflict with the "ranges" property, because suddenly we can
> no longer map the regions properly. Maybe Mitch can comment on whether
> this is possible or not?
>
> To make it clearer what I'm talking about, here's the DT snippet again
> (with the compatible property removed from the pci@ nodes because they
> are no longer probed by a driver, the "simple-bus" removed from the
> pcie-controller node's compatible property removed and its #address-
> and #size-cells properties adjusted as described above).
>
> 	pcie-controller {
> 		compatible = "nvidia,tegra20-pcie";
> 		reg = <0x80003000 0x00000800   /* PADS registers */
> 		       0x80003800 0x00000200   /* AFI registers */
> 		       0x80004000 0x00100000   /* configuration space */
> 		       0x80104000 0x00100000>; /* extended configuration space */
> 		interrupts = <0 98 0x04   /* controller interrupt */
> 			      0 99 0x04>; /* MSI interrupt */
> 		status = "disabled";
>
> 		ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */
> 			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
> 			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
> 			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
>
> 		#address-cells = <1>;
> 		#size-cells = <0>;
>
> 		pci@0 {
> 			reg = <2>;
> 			status = "disabled";
>
> 			#address-cells = <3>;
> 			#size-cells = <2>;
>
> 			ranges = <0x81000000 0 0 0x80400000 0 0x00008000   /* I/O */
> 				  0x82000000 0 0 0x90000000 0 0x08000000   /* non-prefetchable memory */
> 				  0xc2000000 0 0 0xa0000000 0 0x08000000>; /* prefetchable memory */
>
> 			nvidia,ctrl-offset = <0x110>;
> 			nvidia,num-lanes = <2>;
> 		};
>
> 		pci@1 {
> 			reg = <1>;
> 			status = "disabled";
>
> 			#address-cells = <3>;
> 			#size-cells = <2>;
>
> 			ranges = <0x81000000 0 0 0x80408000 0 0x00008000   /* I/O */
> 				  0x82000000 0 0 0x98000000 0 0x08000000   /* non-prefetchable memory */
> 				  0xc2000000 0 0 0xa8000000 0 0x08000000>; /* prefetchable memory */
>
> 			nvidia,ctrl-offset = <0x118>;
> 			nvidia,num-lanes = <2>;
> 		};
> 	};
>
> AIUI none of the ranges properties are valid anymore, because the bus
> represented by pcie-controller no longer reflects the truth, namely that
> it translates the CPU address space to the PCI address space.
>

I think you can use a small-integer port number as an address by 
defining the intermediate address space properly, and using appropriate 
ranges above and below.  Here's a swag at how that would look.

I present three versions, using different choices for the intermediate 
address space encoding.  The intermediate address space may seem 
somewhat artificial, in that it decouples the "linear pass through of 
ranges" between the lower PCI address space and the upper CPU address 
space.  But in another sense, it accurately reflects that fact that the 
bus bridge "slices and dices" that linear address space into 
non-contiguous pieces.

Note that I'm also fixing a problem that I neglected to mention earlier 
- namely the fact that config space is part of the child PCI address 
space so it must be passed through.

Version A - 3 address cells:  In this version, the intermediate address 
space has 3 cells:  port#, address type, offset.  Address type is
   0 : root port
   1 : config space
   2 : extended config space
   3 : I/O
   4 : non-prefetchable memory
   5 : prefetchable memory.

The third cell "offset" is necessary so that the size field has a number 
space that can include it.

	pcie-controller {
		compatible = "nvidia,tegra20-pcie";
		reg = <0x80003000 0x00000800   /* PADS registers */
		       0x80003800 0x00000200>; /* extended configuration space */
		interrupts = <0 98 0x04   /* controller interrupt */
			      0 99 0x04>; /* MSI interrupt */
		status = "disabled";

		ranges = <0 0 0  0x80000000 0x00001000   /* Root port 0 */
			  0 1 0  0x80004000 0x00080000   /* Port 0 config space */
			  0 2 0  0x80104000 0x00080000   /* Port 0 ext config space *
			  0 3 0  0x80400000 0x00008000   /* Port 0 downstream I/O */
			  0 4 0  0x90000000 0x08000000   /* Port 0 non-prefetchable memory */
			  0 5 0  0xa0000000 0x08000000   /* Port 0 prefetchable memory */

			  1 0 0  0x80001000 0x00001000   /* Root port 1 */
			  1 1 0  0x80004000 0x00080000   /* Port 1 config space */
			  1 2 0  0x80184000 0x00080000   /* Port 1 ext config space */
			  1 3 0  0x80408000 0x00010000   /* Port 1 downstream I/O */
			  1 4 0  0x98000000 0x08000000   /* Port 1 non-prefetchable memory */
			  1 5 0  0xa0000000 0x08000000>; /* Port 1 prefetchable memory */

		#address-cells = <3>;
		#size-cells = <1>;

		pci@0 {
			reg = <0 0 0 0x1000>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;

			ranges = <0x80000000 0 0  0 1 0  0 0x00080000   /* config */
				  0x90000000 0 0  0 2 0  0 0x00080000   /* extended config */
				  0x81000000 0 0  0 3 0  0 0x00008000   /* I/O */
				  0x82000000 0 0  0 4 0  0 0x08000000   /* non-prefetchable memory */
				  0xc2000000 0 0  0 5 0  0 0x08000000>; /* prefetchable memory */

			nvidia,ctrl-offset = <0x110>;
			nvidia,num-lanes = <2>;
		};


		pci@1 {
			reg = <1 0 0 0x1000>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;

			ranges = <0x80000000 0 0  1 1 0  0 0x00080000   /* config */
				  0x90000000 0 0  1 2 0  0 0x00080000   /* extended config */
				  0x81000000 0 0  1 3 0  0 0x00008000   /* I/O */
				  0x82000000 0 0  1 4 0  0 0x08000000   /* non-prefetchable memory */
				  0xc2000000 0 0  1 5 0  0 0x08000000>; /* prefetchable memory */

			nvidia,ctrl-offset = <0x118>;
			nvidia,num-lanes = <2>;
		};

Version B - 2 address cells:  In this first version, the intermediate
address space has 2 cells:  port#, offset.  The address type (I/O, mem,
etc) is the high digit of in the offset:
    Offset 0....... : Root port
    Offset 1....... : config
    Offset 2....... : extended config
    Offset 3....... : I/O
    Offset 4....... : non-prefetchable memory
    Offset 5....... : prefetchable memory.

	pcie-controller {
		compatible = "nvidia,tegra20-pcie";
		reg = <0x80003000 0x00000800   /* PADS registers */
		       0x80003800 0x00000200>; /* AFI registers */

		interrupts = <0 98 0x04   /* controller interrupt */
			      0 99 0x04>; /* MSI interrupt */
		status = "disabled";

		ranges = <0 0x00000000  0x80000000 0x00001000   /* Root port 0 */
			  0 0x10000000  0x80004000 0x00080000   /* Port 0 config */
			  0 0x20000000  0x80104000 0x00080000	/* Port 0 ext config */
			  0 0x30000000  0x80400000 0x00008000   /* Port 0 downstream I/O */
			  0 0x40000000  0x90000000 0x08000000   /* Port 0 non-prefetchable memory */
			  0 0x50000000  0xa0000000 0x08000000   /* Port 0 prefetchable memory */

			  1 0x00000000  0x80001000 0x00001000   /* Root port 1 */
			  1 0x10000000  0x80084000 0x00080000   /* Port 1 config */
			  1 0x20000000  0x80184000 0x00080000	/* Port 1 ext config */
			  1 0x30000000  0x80408000 0x00010000   /* Port 1 downstream I/O */
			  1 0x40000000  0x98000000 0x08000000   /* Port 1 non-prefetchable memory */
			  1 0x50000000  0xa0000000 0x08000000>; /* Port 1 prefetchable memory */

		#address-cells = <2>;
		#size-cells = <1>;

		pci@0 {
			reg = <0 0 0x1000>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;

			ranges = <0x80000000 0 0  0 0x10000000  0 0x00080000   /* config */
				  0x90000000 0 0  0 0x20000000  0 0x00080000   /* ext config */
				  0x81000000 0 0  0 0x30000000  0 0x00008000   /* I/O */
				  0x82000000 0 0  0 0x40000000  0 0x08000000   /* non-prefetchable memory */
				  0xc2000000 0 0  0 0x50000000  0 0x08000000>; /* prefetchable memory */

			nvidia,ctrl-offset = <0x110>;
			nvidia,num-lanes = <2>;
		};


		pci@1 {
			reg = <1 0 0x1000>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;

			ranges = <0x80000000 0 0  1 0x10000000  0 0x00080000   /* config */
				  0x90000000 0 0  1 0x20000000  0 0x00080000   /* ext config */
				  0x81000000 0 0  1 0x30000000  0 0x00008000   /* I/O */
				  0x82000000 0 0  1 0x40000000  0 0x08000000   /* non-prefetchable memory */
				  0xc2000000 0 0  1 0x50000000  0 0x08000000>; /* prefetchable memory */

			nvidia,ctrl-offset = <0x118>;
			nvidia,num-lanes = <2>;
		};

  
Version C - 2 address cells, 0 size cells (!) : In this version we hide the size component in the intermediate space.  I don't know if that will actually work, but my guess is that it probably would.  The intermediate address space is like version A with the omission of the offset field.  The intermediate address just specifies the port number and the address type.

	pcie-controller {
		compatible = "nvidia,tegra20-pcie";
		reg = <0x80003000 0x00000800   /* PADS registers */
		       0x80003800 0x00000200>; /* AFI registers */
		interrupts = <0 98 0x04   /* controller interrupt */
			      0 99 0x04>; /* MSI interrupt */
		status = "disabled";

		ranges = <0 0  0x80000000   /* Root port 0 */
			  0 1  0x80004000   /* Port 0 config */
			  0 2  0x80104000   /* Port 0 ext config */
			  0 3  0x80400000   /* Port 0 downstream I/O */
			  0 4  0x90000000   /* Port 0 non-prefetchable memory */
			  0 5  0xa0000000   /* Port 0 prefetchable memory */

			  1 0  0x80001000   /* Root port 1 */
			  1 1  0x80084000   /* Port 1 config */
			  1 2  0x80184000   /* Port 1 ext config */
			  1 3  0x80408000   /* Port 1 downstream I/O */
			  1 4  0x98000000   /* Port 1 non-prefetchable memory */
			  1 5  0xa0000000>; /* Port 1 prefetchable memory */

		#address-cells = <2>;
		#size-cells = <0>;

		pci@0 {
			reg = <0 0>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;

			ranges = <0x80000000 0 0  0 1  0 0x00080000   /* config */
				  0x90000000 0 0  0 2  0 0x00080000   /* ext config */
				  0x81000000 0 0  0 3  0 0x00008000   /* I/O */
				  0x82000000 0 0  0 4  0 0x08000000   /* non-prefetchable memory */
				  0xc2000000 0 0  0 5  0 0x08000000>; /* prefetchable memory */

			nvidia,ctrl-offset = <0x110>;
			nvidia,num-lanes = <2>;
		};


		pci@1 {
			reg = <1 0>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;

			ranges = <0x80000000 0 0  1 1  0 0x00080000   /* config */
				  0x90000000 0 0  1 2  0 0x00080000   /* ext config */
				  0x81000000 0 0  1 3  0 0x00008000   /* I/O */
				  0x82000000 0 0  1 4  0 0x08000000   /* non-prefetchable memory */
				  0xc2000000 0 0  1 5  0 0x08000000>; /* prefetchable memory */

			nvidia,ctrl-offset = <0x118>;
			nvidia,num-lanes = <2>;
		};

In version C, you might even be able to include the ctrl register offset as a second entry in the reg property.
  

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-19 21:31                                                                 ` Mitch Bradley
  0 siblings, 0 replies; 249+ messages in thread
From: Mitch Bradley @ 2012-06-19 21:31 UTC (permalink / raw)
  To: linux-arm-kernel

On 6/19/2012 3:30 AM, Thierry Reding wrote:
> On Fri, Jun 15, 2012 at 08:12:36AM +0200, Thierry Reding wrote:
>> On Thu, Jun 14, 2012 at 01:50:56PM -0600, Stephen Warren wrote:
>>> On 06/14/2012 01:29 PM, Thierry Reding wrote:
>>>> On Thu, Jun 14, 2012 at 12:30:50PM -0600, Stephen Warren wrote:
>>>>> On 06/14/2012 03:19 AM, Thierry Reding wrote:
>>> ...
>>>>>> #address-cells = <1>; #size-cells = <1>;
>>>>>>
>>>>>> pci at 80000000 {
>>>>>
>>>>> I'm still not convinced that using the address of the port's
>>>>> registers is the correct way to represent each port. The port
>>>>> index seems much more useful.
>>>>>
>>>>> The main reason here is that there are a lot of registers that
>>>>> contain fields for each port - far more than the combination of
>>>>> this node's reg and ctrl-offset (which I assume is an address
>>>>> offset for just one example of this issue) properties can
>>>>> describe. The bit position and bit stride of these fields isn't
>>>>> necessarily the same in each register. Do we want a property like
>>>>> ctrl-offset for every single type of field in every single shared
>>>>> register that describes the location of the relevant data, or
>>>>> just a single "port ID" bit that can be applied to anything?
>>>>>
>>>>> (Perhaps this isn't so obvious looking at the TRM since it
>>>>> doesn't document all registers, and I'm also looking at the
>>>>> Tegra30 documentation too, which might be more exposed to this -
>>>>> I haven't correlated all the documentation sources to be sure
>>>>> though)
>>>>
>>>> I agree that maybe adding properties for each bit position or
>>>> register offset may not work out too well. But I think it still
>>>> makes sense to use the base address of the port's registers (see
>>>> below). We could of course add some code to determine the index
>>>> from the base address at initialization time and reuse the index
>>>> where appropriate.
>>>
>>> To me, working back from address to ID then using the ID to calculate
>>> some other addresses seems far more icky than just calculating all the
>>> addresses based off of one ID. But, I suppose this doesn't make a huge
>>> practical difference.
>>
>> This really depends on the device vs. no device decision below. If we can
>> make it work without needing an extra device for it, then using the index
>> is certainly better. However, if we instantiate devices from the DT, then
>> we have the address anyway and adding the index as a property would be
>> redundant and error prone (what happens if somebody sets the index of the
>> port at address 0x80000000 to 2?).
>
> An additional problem with this is that we'd have to add the following
> to the pcie-controller node:
>
> 	#address-cells = <1>;
> 	#size-cells = <0>;
>
> This will conflict with the "ranges" property, because suddenly we can
> no longer map the regions properly. Maybe Mitch can comment on whether
> this is possible or not?
>
> To make it clearer what I'm talking about, here's the DT snippet again
> (with the compatible property removed from the pci@ nodes because they
> are no longer probed by a driver, the "simple-bus" removed from the
> pcie-controller node's compatible property removed and its #address-
> and #size-cells properties adjusted as described above).
>
> 	pcie-controller {
> 		compatible = "nvidia,tegra20-pcie";
> 		reg = <0x80003000 0x00000800   /* PADS registers */
> 		       0x80003800 0x00000200   /* AFI registers */
> 		       0x80004000 0x00100000   /* configuration space */
> 		       0x80104000 0x00100000>; /* extended configuration space */
> 		interrupts = <0 98 0x04   /* controller interrupt */
> 			      0 99 0x04>; /* MSI interrupt */
> 		status = "disabled";
>
> 		ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */
> 			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
> 			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
> 			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
>
> 		#address-cells = <1>;
> 		#size-cells = <0>;
>
> 		pci at 0 {
> 			reg = <2>;
> 			status = "disabled";
>
> 			#address-cells = <3>;
> 			#size-cells = <2>;
>
> 			ranges = <0x81000000 0 0 0x80400000 0 0x00008000   /* I/O */
> 				  0x82000000 0 0 0x90000000 0 0x08000000   /* non-prefetchable memory */
> 				  0xc2000000 0 0 0xa0000000 0 0x08000000>; /* prefetchable memory */
>
> 			nvidia,ctrl-offset = <0x110>;
> 			nvidia,num-lanes = <2>;
> 		};
>
> 		pci at 1 {
> 			reg = <1>;
> 			status = "disabled";
>
> 			#address-cells = <3>;
> 			#size-cells = <2>;
>
> 			ranges = <0x81000000 0 0 0x80408000 0 0x00008000   /* I/O */
> 				  0x82000000 0 0 0x98000000 0 0x08000000   /* non-prefetchable memory */
> 				  0xc2000000 0 0 0xa8000000 0 0x08000000>; /* prefetchable memory */
>
> 			nvidia,ctrl-offset = <0x118>;
> 			nvidia,num-lanes = <2>;
> 		};
> 	};
>
> AIUI none of the ranges properties are valid anymore, because the bus
> represented by pcie-controller no longer reflects the truth, namely that
> it translates the CPU address space to the PCI address space.
>

I think you can use a small-integer port number as an address by 
defining the intermediate address space properly, and using appropriate 
ranges above and below.  Here's a swag at how that would look.

I present three versions, using different choices for the intermediate 
address space encoding.  The intermediate address space may seem 
somewhat artificial, in that it decouples the "linear pass through of 
ranges" between the lower PCI address space and the upper CPU address 
space.  But in another sense, it accurately reflects that fact that the 
bus bridge "slices and dices" that linear address space into 
non-contiguous pieces.

Note that I'm also fixing a problem that I neglected to mention earlier 
- namely the fact that config space is part of the child PCI address 
space so it must be passed through.

Version A - 3 address cells:  In this version, the intermediate address 
space has 3 cells:  port#, address type, offset.  Address type is
   0 : root port
   1 : config space
   2 : extended config space
   3 : I/O
   4 : non-prefetchable memory
   5 : prefetchable memory.

The third cell "offset" is necessary so that the size field has a number 
space that can include it.

	pcie-controller {
		compatible = "nvidia,tegra20-pcie";
		reg = <0x80003000 0x00000800   /* PADS registers */
		       0x80003800 0x00000200>; /* extended configuration space */
		interrupts = <0 98 0x04   /* controller interrupt */
			      0 99 0x04>; /* MSI interrupt */
		status = "disabled";

		ranges = <0 0 0  0x80000000 0x00001000   /* Root port 0 */
			  0 1 0  0x80004000 0x00080000   /* Port 0 config space */
			  0 2 0  0x80104000 0x00080000   /* Port 0 ext config space *
			  0 3 0  0x80400000 0x00008000   /* Port 0 downstream I/O */
			  0 4 0  0x90000000 0x08000000   /* Port 0 non-prefetchable memory */
			  0 5 0  0xa0000000 0x08000000   /* Port 0 prefetchable memory */

			  1 0 0  0x80001000 0x00001000   /* Root port 1 */
			  1 1 0  0x80004000 0x00080000   /* Port 1 config space */
			  1 2 0  0x80184000 0x00080000   /* Port 1 ext config space */
			  1 3 0  0x80408000 0x00010000   /* Port 1 downstream I/O */
			  1 4 0  0x98000000 0x08000000   /* Port 1 non-prefetchable memory */
			  1 5 0  0xa0000000 0x08000000>; /* Port 1 prefetchable memory */

		#address-cells = <3>;
		#size-cells = <1>;

		pci at 0 {
			reg = <0 0 0 0x1000>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;

			ranges = <0x80000000 0 0  0 1 0  0 0x00080000   /* config */
				  0x90000000 0 0  0 2 0  0 0x00080000   /* extended config */
				  0x81000000 0 0  0 3 0  0 0x00008000   /* I/O */
				  0x82000000 0 0  0 4 0  0 0x08000000   /* non-prefetchable memory */
				  0xc2000000 0 0  0 5 0  0 0x08000000>; /* prefetchable memory */

			nvidia,ctrl-offset = <0x110>;
			nvidia,num-lanes = <2>;
		};


		pci at 1 {
			reg = <1 0 0 0x1000>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;

			ranges = <0x80000000 0 0  1 1 0  0 0x00080000   /* config */
				  0x90000000 0 0  1 2 0  0 0x00080000   /* extended config */
				  0x81000000 0 0  1 3 0  0 0x00008000   /* I/O */
				  0x82000000 0 0  1 4 0  0 0x08000000   /* non-prefetchable memory */
				  0xc2000000 0 0  1 5 0  0 0x08000000>; /* prefetchable memory */

			nvidia,ctrl-offset = <0x118>;
			nvidia,num-lanes = <2>;
		};

Version B - 2 address cells:  In this first version, the intermediate
address space has 2 cells:  port#, offset.  The address type (I/O, mem,
etc) is the high digit of in the offset:
    Offset 0....... : Root port
    Offset 1....... : config
    Offset 2....... : extended config
    Offset 3....... : I/O
    Offset 4....... : non-prefetchable memory
    Offset 5....... : prefetchable memory.

	pcie-controller {
		compatible = "nvidia,tegra20-pcie";
		reg = <0x80003000 0x00000800   /* PADS registers */
		       0x80003800 0x00000200>; /* AFI registers */

		interrupts = <0 98 0x04   /* controller interrupt */
			      0 99 0x04>; /* MSI interrupt */
		status = "disabled";

		ranges = <0 0x00000000  0x80000000 0x00001000   /* Root port 0 */
			  0 0x10000000  0x80004000 0x00080000   /* Port 0 config */
			  0 0x20000000  0x80104000 0x00080000	/* Port 0 ext config */
			  0 0x30000000  0x80400000 0x00008000   /* Port 0 downstream I/O */
			  0 0x40000000  0x90000000 0x08000000   /* Port 0 non-prefetchable memory */
			  0 0x50000000  0xa0000000 0x08000000   /* Port 0 prefetchable memory */

			  1 0x00000000  0x80001000 0x00001000   /* Root port 1 */
			  1 0x10000000  0x80084000 0x00080000   /* Port 1 config */
			  1 0x20000000  0x80184000 0x00080000	/* Port 1 ext config */
			  1 0x30000000  0x80408000 0x00010000   /* Port 1 downstream I/O */
			  1 0x40000000  0x98000000 0x08000000   /* Port 1 non-prefetchable memory */
			  1 0x50000000  0xa0000000 0x08000000>; /* Port 1 prefetchable memory */

		#address-cells = <2>;
		#size-cells = <1>;

		pci at 0 {
			reg = <0 0 0x1000>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;

			ranges = <0x80000000 0 0  0 0x10000000  0 0x00080000   /* config */
				  0x90000000 0 0  0 0x20000000  0 0x00080000   /* ext config */
				  0x81000000 0 0  0 0x30000000  0 0x00008000   /* I/O */
				  0x82000000 0 0  0 0x40000000  0 0x08000000   /* non-prefetchable memory */
				  0xc2000000 0 0  0 0x50000000  0 0x08000000>; /* prefetchable memory */

			nvidia,ctrl-offset = <0x110>;
			nvidia,num-lanes = <2>;
		};


		pci at 1 {
			reg = <1 0 0x1000>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;

			ranges = <0x80000000 0 0  1 0x10000000  0 0x00080000   /* config */
				  0x90000000 0 0  1 0x20000000  0 0x00080000   /* ext config */
				  0x81000000 0 0  1 0x30000000  0 0x00008000   /* I/O */
				  0x82000000 0 0  1 0x40000000  0 0x08000000   /* non-prefetchable memory */
				  0xc2000000 0 0  1 0x50000000  0 0x08000000>; /* prefetchable memory */

			nvidia,ctrl-offset = <0x118>;
			nvidia,num-lanes = <2>;
		};

  
Version C - 2 address cells, 0 size cells (!) : In this version we hide the size component in the intermediate space.  I don't know if that will actually work, but my guess is that it probably would.  The intermediate address space is like version A with the omission of the offset field.  The intermediate address just specifies the port number and the address type.

	pcie-controller {
		compatible = "nvidia,tegra20-pcie";
		reg = <0x80003000 0x00000800   /* PADS registers */
		       0x80003800 0x00000200>; /* AFI registers */
		interrupts = <0 98 0x04   /* controller interrupt */
			      0 99 0x04>; /* MSI interrupt */
		status = "disabled";

		ranges = <0 0  0x80000000   /* Root port 0 */
			  0 1  0x80004000   /* Port 0 config */
			  0 2  0x80104000   /* Port 0 ext config */
			  0 3  0x80400000   /* Port 0 downstream I/O */
			  0 4  0x90000000   /* Port 0 non-prefetchable memory */
			  0 5  0xa0000000   /* Port 0 prefetchable memory */

			  1 0  0x80001000   /* Root port 1 */
			  1 1  0x80084000   /* Port 1 config */
			  1 2  0x80184000   /* Port 1 ext config */
			  1 3  0x80408000   /* Port 1 downstream I/O */
			  1 4  0x98000000   /* Port 1 non-prefetchable memory */
			  1 5  0xa0000000>; /* Port 1 prefetchable memory */

		#address-cells = <2>;
		#size-cells = <0>;

		pci at 0 {
			reg = <0 0>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;

			ranges = <0x80000000 0 0  0 1  0 0x00080000   /* config */
				  0x90000000 0 0  0 2  0 0x00080000   /* ext config */
				  0x81000000 0 0  0 3  0 0x00008000   /* I/O */
				  0x82000000 0 0  0 4  0 0x08000000   /* non-prefetchable memory */
				  0xc2000000 0 0  0 5  0 0x08000000>; /* prefetchable memory */

			nvidia,ctrl-offset = <0x110>;
			nvidia,num-lanes = <2>;
		};


		pci at 1 {
			reg = <1 0>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;

			ranges = <0x80000000 0 0  1 1  0 0x00080000   /* config */
				  0x90000000 0 0  1 2  0 0x00080000   /* ext config */
				  0x81000000 0 0  1 3  0 0x00008000   /* I/O */
				  0x82000000 0 0  1 4  0 0x08000000   /* non-prefetchable memory */
				  0xc2000000 0 0  1 5  0 0x08000000>; /* prefetchable memory */

			nvidia,ctrl-offset = <0x118>;
			nvidia,num-lanes = <2>;
		};

In version C, you might even be able to include the ctrl register offset as a second entry in the reg property.
  

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-19 21:31                                                                 ` Mitch Bradley
@ 2012-06-20 16:32                                                                   ` Stephen Warren
  -1 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-20 16:32 UTC (permalink / raw)
  To: Mitch Bradley
  Cc: Thierry Reding, Russell King, linux-pci, devicetree-discuss,
	Rob Herring, Jesse Barnes, Colin Cross, linux-tegra,
	linux-arm-kernel, Arnd Bergmann

On 06/19/2012 03:31 PM, Mitch Bradley wrote:
> On 6/19/2012 3:30 AM, Thierry Reding wrote:
>> On Fri, Jun 15, 2012 at 08:12:36AM +0200, Thierry Reding wrote:
>>> On Thu, Jun 14, 2012 at 01:50:56PM -0600, Stephen Warren wrote:
>>>> On 06/14/2012 01:29 PM, Thierry Reding wrote:
>>>>> On Thu, Jun 14, 2012 at 12:30:50PM -0600, Stephen Warren wrote:
>>>>>> On 06/14/2012 03:19 AM, Thierry Reding wrote:
>>>> ...
>>>>>>> #address-cells = <1>; #size-cells = <1>;
>>>>>>>
>>>>>>> pci@80000000 {
>>>>>>
>>>>>> I'm still not convinced that using the address of the port's
>>>>>> registers is the correct way to represent each port. The port
>>>>>> index seems much more useful.
>>>>>>
>>>>>> The main reason here is that there are a lot of registers that
>>>>>> contain fields for each port - far more than the combination of
>>>>>> this node's reg and ctrl-offset (which I assume is an address
>>>>>> offset for just one example of this issue) properties can
>>>>>> describe. The bit position and bit stride of these fields isn't
>>>>>> necessarily the same in each register. Do we want a property like
>>>>>> ctrl-offset for every single type of field in every single shared
>>>>>> register that describes the location of the relevant data, or
>>>>>> just a single "port ID" bit that can be applied to anything?
>>>>>>
>>>>>> (Perhaps this isn't so obvious looking at the TRM since it
>>>>>> doesn't document all registers, and I'm also looking at the
>>>>>> Tegra30 documentation too, which might be more exposed to this -
>>>>>> I haven't correlated all the documentation sources to be sure
>>>>>> though)
>>>>>
>>>>> I agree that maybe adding properties for each bit position or
>>>>> register offset may not work out too well. But I think it still
>>>>> makes sense to use the base address of the port's registers (see
>>>>> below). We could of course add some code to determine the index
>>>>> from the base address at initialization time and reuse the index
>>>>> where appropriate.
>>>>
>>>> To me, working back from address to ID then using the ID to calculate
>>>> some other addresses seems far more icky than just calculating all the
>>>> addresses based off of one ID. But, I suppose this doesn't make a huge
>>>> practical difference.
>>>
>>> This really depends on the device vs. no device decision below. If we
>>> can
>>> make it work without needing an extra device for it, then using the
>>> index
>>> is certainly better. However, if we instantiate devices from the DT,
>>> then
>>> we have the address anyway and adding the index as a property would be
>>> redundant and error prone (what happens if somebody sets the index of
>>> the
>>> port at address 0x80000000 to 2?).
>>
>> An additional problem with this is that we'd have to add the following
>> to the pcie-controller node:
>>
>>     #address-cells = <1>;
>>     #size-cells = <0>;
>>
>> This will conflict with the "ranges" property, because suddenly we can
>> no longer map the regions properly. Maybe Mitch can comment on whether
>> this is possible or not?
>>
>> To make it clearer what I'm talking about, here's the DT snippet again
>> (with the compatible property removed from the pci@ nodes because they
>> are no longer probed by a driver, the "simple-bus" removed from the
>> pcie-controller node's compatible property removed and its #address-
>> and #size-cells properties adjusted as described above).
>>
>>     pcie-controller {
>>         compatible = "nvidia,tegra20-pcie";
>>         reg = <0x80003000 0x00000800   /* PADS registers */
>>                0x80003800 0x00000200   /* AFI registers */
>>                0x80004000 0x00100000   /* configuration space */
>>                0x80104000 0x00100000>; /* extended configuration space */
>>         interrupts = <0 98 0x04   /* controller interrupt */
>>                   0 99 0x04>; /* MSI interrupt */
>>         status = "disabled";
>>
>>         ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */
>>               0x80400000 0x80400000 0x00010000   /* downstream I/O */
>>               0x90000000 0x90000000 0x10000000   /* non-prefetchable
>> memory */
>>               0xa0000000 0xa0000000 0x10000000>; /* prefetchable
>> memory */
>>
>>         #address-cells = <1>;
>>         #size-cells = <0>;
>>
>>         pci@0 {
>>             reg = <2>;
>>             status = "disabled";
>>
>>             #address-cells = <3>;
>>             #size-cells = <2>;
>>
>>             ranges = <0x81000000 0 0 0x80400000 0 0x00008000   /* I/O */
>>                   0x82000000 0 0 0x90000000 0 0x08000000   /*
>> non-prefetchable memory */
>>                   0xc2000000 0 0 0xa0000000 0 0x08000000>; /*
>> prefetchable memory */
>>
>>             nvidia,ctrl-offset = <0x110>;
>>             nvidia,num-lanes = <2>;
>>         };
>>
>>         pci@1 {
>>             reg = <1>;
>>             status = "disabled";
>>
>>             #address-cells = <3>;
>>             #size-cells = <2>;
>>
>>             ranges = <0x81000000 0 0 0x80408000 0 0x00008000   /* I/O */
>>                   0x82000000 0 0 0x98000000 0 0x08000000   /*
>> non-prefetchable memory */
>>                   0xc2000000 0 0 0xa8000000 0 0x08000000>; /*
>> prefetchable memory */
>>
>>             nvidia,ctrl-offset = <0x118>;
>>             nvidia,num-lanes = <2>;
>>         };
>>     };
>>
>> AIUI none of the ranges properties are valid anymore, because the bus
>> represented by pcie-controller no longer reflects the truth, namely that
>> it translates the CPU address space to the PCI address space.
>>
> 
> I think you can use a small-integer port number as an address by
> defining the intermediate address space properly, and using appropriate
> ranges above and below.  Here's a swag at how that would look.
> 
> I present three versions, using different choices for the intermediate
> address space encoding.  The intermediate address space may seem
> somewhat artificial, in that it decouples the "linear pass through of
> ranges" between the lower PCI address space and the upper CPU address
> space.  But in another sense, it accurately reflects that fact that the
> bus bridge "slices and dices" that linear address space into
> non-contiguous pieces.
> 
> Note that I'm also fixing a problem that I neglected to mention earlier
> - namely the fact that config space is part of the child PCI address
> space so it must be passed through.

Impressive. I do tend to like these ideas...

> Version A - 3 address cells:  In this version, the intermediate address
> space has 3 cells:  port#, address type, offset.  Address type is

I think I personally tend to prefer this option; I like that everything
is explicit and nicely separated.

>   0 : root port
>   1 : config space
>   2 : extended config space
>   3 : I/O
>   4 : non-prefetchable memory
>   5 : prefetchable memory.
> 
> The third cell "offset" is necessary so that the size field has a number
> space that can include it.

Can you expand on that sentence a bit more; I don't quite understand
that aspect. Thanks.

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-20 16:32                                                                   ` Stephen Warren
  0 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-20 16:32 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/19/2012 03:31 PM, Mitch Bradley wrote:
> On 6/19/2012 3:30 AM, Thierry Reding wrote:
>> On Fri, Jun 15, 2012 at 08:12:36AM +0200, Thierry Reding wrote:
>>> On Thu, Jun 14, 2012 at 01:50:56PM -0600, Stephen Warren wrote:
>>>> On 06/14/2012 01:29 PM, Thierry Reding wrote:
>>>>> On Thu, Jun 14, 2012 at 12:30:50PM -0600, Stephen Warren wrote:
>>>>>> On 06/14/2012 03:19 AM, Thierry Reding wrote:
>>>> ...
>>>>>>> #address-cells = <1>; #size-cells = <1>;
>>>>>>>
>>>>>>> pci at 80000000 {
>>>>>>
>>>>>> I'm still not convinced that using the address of the port's
>>>>>> registers is the correct way to represent each port. The port
>>>>>> index seems much more useful.
>>>>>>
>>>>>> The main reason here is that there are a lot of registers that
>>>>>> contain fields for each port - far more than the combination of
>>>>>> this node's reg and ctrl-offset (which I assume is an address
>>>>>> offset for just one example of this issue) properties can
>>>>>> describe. The bit position and bit stride of these fields isn't
>>>>>> necessarily the same in each register. Do we want a property like
>>>>>> ctrl-offset for every single type of field in every single shared
>>>>>> register that describes the location of the relevant data, or
>>>>>> just a single "port ID" bit that can be applied to anything?
>>>>>>
>>>>>> (Perhaps this isn't so obvious looking at the TRM since it
>>>>>> doesn't document all registers, and I'm also looking at the
>>>>>> Tegra30 documentation too, which might be more exposed to this -
>>>>>> I haven't correlated all the documentation sources to be sure
>>>>>> though)
>>>>>
>>>>> I agree that maybe adding properties for each bit position or
>>>>> register offset may not work out too well. But I think it still
>>>>> makes sense to use the base address of the port's registers (see
>>>>> below). We could of course add some code to determine the index
>>>>> from the base address at initialization time and reuse the index
>>>>> where appropriate.
>>>>
>>>> To me, working back from address to ID then using the ID to calculate
>>>> some other addresses seems far more icky than just calculating all the
>>>> addresses based off of one ID. But, I suppose this doesn't make a huge
>>>> practical difference.
>>>
>>> This really depends on the device vs. no device decision below. If we
>>> can
>>> make it work without needing an extra device for it, then using the
>>> index
>>> is certainly better. However, if we instantiate devices from the DT,
>>> then
>>> we have the address anyway and adding the index as a property would be
>>> redundant and error prone (what happens if somebody sets the index of
>>> the
>>> port at address 0x80000000 to 2?).
>>
>> An additional problem with this is that we'd have to add the following
>> to the pcie-controller node:
>>
>>     #address-cells = <1>;
>>     #size-cells = <0>;
>>
>> This will conflict with the "ranges" property, because suddenly we can
>> no longer map the regions properly. Maybe Mitch can comment on whether
>> this is possible or not?
>>
>> To make it clearer what I'm talking about, here's the DT snippet again
>> (with the compatible property removed from the pci@ nodes because they
>> are no longer probed by a driver, the "simple-bus" removed from the
>> pcie-controller node's compatible property removed and its #address-
>> and #size-cells properties adjusted as described above).
>>
>>     pcie-controller {
>>         compatible = "nvidia,tegra20-pcie";
>>         reg = <0x80003000 0x00000800   /* PADS registers */
>>                0x80003800 0x00000200   /* AFI registers */
>>                0x80004000 0x00100000   /* configuration space */
>>                0x80104000 0x00100000>; /* extended configuration space */
>>         interrupts = <0 98 0x04   /* controller interrupt */
>>                   0 99 0x04>; /* MSI interrupt */
>>         status = "disabled";
>>
>>         ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */
>>               0x80400000 0x80400000 0x00010000   /* downstream I/O */
>>               0x90000000 0x90000000 0x10000000   /* non-prefetchable
>> memory */
>>               0xa0000000 0xa0000000 0x10000000>; /* prefetchable
>> memory */
>>
>>         #address-cells = <1>;
>>         #size-cells = <0>;
>>
>>         pci at 0 {
>>             reg = <2>;
>>             status = "disabled";
>>
>>             #address-cells = <3>;
>>             #size-cells = <2>;
>>
>>             ranges = <0x81000000 0 0 0x80400000 0 0x00008000   /* I/O */
>>                   0x82000000 0 0 0x90000000 0 0x08000000   /*
>> non-prefetchable memory */
>>                   0xc2000000 0 0 0xa0000000 0 0x08000000>; /*
>> prefetchable memory */
>>
>>             nvidia,ctrl-offset = <0x110>;
>>             nvidia,num-lanes = <2>;
>>         };
>>
>>         pci at 1 {
>>             reg = <1>;
>>             status = "disabled";
>>
>>             #address-cells = <3>;
>>             #size-cells = <2>;
>>
>>             ranges = <0x81000000 0 0 0x80408000 0 0x00008000   /* I/O */
>>                   0x82000000 0 0 0x98000000 0 0x08000000   /*
>> non-prefetchable memory */
>>                   0xc2000000 0 0 0xa8000000 0 0x08000000>; /*
>> prefetchable memory */
>>
>>             nvidia,ctrl-offset = <0x118>;
>>             nvidia,num-lanes = <2>;
>>         };
>>     };
>>
>> AIUI none of the ranges properties are valid anymore, because the bus
>> represented by pcie-controller no longer reflects the truth, namely that
>> it translates the CPU address space to the PCI address space.
>>
> 
> I think you can use a small-integer port number as an address by
> defining the intermediate address space properly, and using appropriate
> ranges above and below.  Here's a swag at how that would look.
> 
> I present three versions, using different choices for the intermediate
> address space encoding.  The intermediate address space may seem
> somewhat artificial, in that it decouples the "linear pass through of
> ranges" between the lower PCI address space and the upper CPU address
> space.  But in another sense, it accurately reflects that fact that the
> bus bridge "slices and dices" that linear address space into
> non-contiguous pieces.
> 
> Note that I'm also fixing a problem that I neglected to mention earlier
> - namely the fact that config space is part of the child PCI address
> space so it must be passed through.

Impressive. I do tend to like these ideas...

> Version A - 3 address cells:  In this version, the intermediate address
> space has 3 cells:  port#, address type, offset.  Address type is

I think I personally tend to prefer this option; I like that everything
is explicit and nicely separated.

>   0 : root port
>   1 : config space
>   2 : extended config space
>   3 : I/O
>   4 : non-prefetchable memory
>   5 : prefetchable memory.
> 
> The third cell "offset" is necessary so that the size field has a number
> space that can include it.

Can you expand on that sentence a bit more; I don't quite understand
that aspect. Thanks.

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-20 16:32                                                                   ` Stephen Warren
@ 2012-06-20 17:41                                                                     ` Mitch Bradley
  -1 siblings, 0 replies; 249+ messages in thread
From: Mitch Bradley @ 2012-06-20 17:41 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Thierry Reding, Russell King, linux-pci, devicetree-discuss,
	Rob Herring, Jesse Barnes, Colin Cross, linux-tegra,
	linux-arm-kernel, Arnd Bergmann

On 6/20/2012 6:32 AM, Stephen Warren wrote:
> On 06/19/2012 03:31 PM, Mitch Bradley wrote:
> ...
>
>
> The third cell "offset" is necessary so that the size field has a number
> space that can include it.
>
> Can you expand on that sentence a bit more; I don't quite understand
> that aspect. Thanks.

The meaning of "size"(in the context of "reg" which is phys,size) is 
"the device occupies a
contiguous sequence of addresses beginning at phys and continuing to 
phys+size-1". The
implicit addition occurs on the last #size-cells cells of the phys.

Suppose you have 2-cell phys where the values for different devices are 
<0 0>, <0 1>, <0 2>, <1 0>, <1 1>,
<1 2>.  The first number is the port number and the second is address 
space type.  It doesn't make
sense to say that size is 0x8000, because that would imply that the 
device extends from, say,
<1 2> to <1 0x8001>.

I'm not sure this is written down anywhere as explicitly as above, but 
it is certainly implicit
in the way that ranges properties work, and it is certainly part of the 
mental model that
was in my head when I developed the device tree addressing scheme.

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-20 17:41                                                                     ` Mitch Bradley
  0 siblings, 0 replies; 249+ messages in thread
From: Mitch Bradley @ 2012-06-20 17:41 UTC (permalink / raw)
  To: linux-arm-kernel

On 6/20/2012 6:32 AM, Stephen Warren wrote:
> On 06/19/2012 03:31 PM, Mitch Bradley wrote:
> ...
>
>
> The third cell "offset" is necessary so that the size field has a number
> space that can include it.
>
> Can you expand on that sentence a bit more; I don't quite understand
> that aspect. Thanks.

The meaning of "size"(in the context of "reg" which is phys,size) is 
"the device occupies a
contiguous sequence of addresses beginning at phys and continuing to 
phys+size-1". The
implicit addition occurs on the last #size-cells cells of the phys.

Suppose you have 2-cell phys where the values for different devices are 
<0 0>, <0 1>, <0 2>, <1 0>, <1 1>,
<1 2>.  The first number is the port number and the second is address 
space type.  It doesn't make
sense to say that size is 0x8000, because that would imply that the 
device extends from, say,
<1 2> to <1 0x8001>.

I'm not sure this is written down anywhere as explicitly as above, but 
it is certainly implicit
in the way that ranges properties work, and it is certainly part of the 
mental model that
was in my head when I developed the device tree addressing scheme.

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-20 17:41                                                                     ` Mitch Bradley
  (?)
@ 2012-06-20 17:47                                                                         ` Stephen Warren
  -1 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-20 17:47 UTC (permalink / raw)
  To: Mitch Bradley
  Cc: Thierry Reding, Russell King, linux-pci-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Jesse Barnes, Colin Cross, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Arnd Bergmann

On 06/20/2012 11:41 AM, Mitch Bradley wrote:
> On 6/20/2012 6:32 AM, Stephen Warren wrote:
>> On 06/19/2012 03:31 PM, Mitch Bradley wrote:
>> ...
>>
>>
>> The third cell "offset" is necessary so that the size field has a number
>> space that can include it.
>>
>> Can you expand on that sentence a bit more; I don't quite understand
>> that aspect. Thanks.
> 
> The meaning of "size"(in the context of "reg" which is phys,size) is
> "the device occupies a
> contiguous sequence of addresses beginning at phys and continuing to
> phys+size-1". The
> implicit addition occurs on the last #size-cells cells of the phys.

Ah right of course - that makes perfect sense. Thanks.

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-20 17:47                                                                         ` Stephen Warren
  0 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-20 17:47 UTC (permalink / raw)
  To: Mitch Bradley
  Cc: Thierry Reding, Russell King, linux-pci, devicetree-discuss,
	Rob Herring, Jesse Barnes, Colin Cross, linux-tegra,
	linux-arm-kernel, Arnd Bergmann

On 06/20/2012 11:41 AM, Mitch Bradley wrote:
> On 6/20/2012 6:32 AM, Stephen Warren wrote:
>> On 06/19/2012 03:31 PM, Mitch Bradley wrote:
>> ...
>>
>>
>> The third cell "offset" is necessary so that the size field has a number
>> space that can include it.
>>
>> Can you expand on that sentence a bit more; I don't quite understand
>> that aspect. Thanks.
> 
> The meaning of "size"(in the context of "reg" which is phys,size) is
> "the device occupies a
> contiguous sequence of addresses beginning at phys and continuing to
> phys+size-1". The
> implicit addition occurs on the last #size-cells cells of the phys.

Ah right of course - that makes perfect sense. Thanks.

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-20 17:47                                                                         ` Stephen Warren
  0 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-20 17:47 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/20/2012 11:41 AM, Mitch Bradley wrote:
> On 6/20/2012 6:32 AM, Stephen Warren wrote:
>> On 06/19/2012 03:31 PM, Mitch Bradley wrote:
>> ...
>>
>>
>> The third cell "offset" is necessary so that the size field has a number
>> space that can include it.
>>
>> Can you expand on that sentence a bit more; I don't quite understand
>> that aspect. Thanks.
> 
> The meaning of "size"(in the context of "reg" which is phys,size) is
> "the device occupies a
> contiguous sequence of addresses beginning at phys and continuing to
> phys+size-1". The
> implicit addition occurs on the last #size-cells cells of the phys.

Ah right of course - that makes perfect sense. Thanks.

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-19 21:31                                                                 ` Mitch Bradley
@ 2012-06-20 19:57                                                                   ` Arnd Bergmann
  -1 siblings, 0 replies; 249+ messages in thread
From: Arnd Bergmann @ 2012-06-20 19:57 UTC (permalink / raw)
  To: Mitch Bradley
  Cc: Thierry Reding, Stephen Warren, Russell King, linux-pci,
	devicetree-discuss, Rob Herring, Jesse Barnes, Colin Cross,
	linux-tegra, linux-arm-kernel

On Tuesday 19 June 2012, Mitch Bradley wrote:

> Version A - 3 address cells:  In this version, the intermediate address 
> space has 3 cells:  port#, address type, offset.  Address type is
>    0 : root port
>    1 : config space
>    2 : extended config space
>    3 : I/O
>    4 : non-prefetchable memory
>    5 : prefetchable memory.
> 
> The third cell "offset" is necessary so that the size field has a number 
> space that can include it.

I agree with Stephen that this is a clever way to encode all the address spaces,
very nice!

> Version B - 2 address cells:  In this first version, the intermediate
> address space has 2 cells:  port#, offset.  The address type (I/O, mem,
> etc) is the high digit of in the offset:
>     Offset 0....... : Root port
>     Offset 1....... : config
>     Offset 2....... : extended config
>     Offset 3....... : I/O
>     Offset 4....... : non-prefetchable memory
>     Offset 5....... : prefetchable memory.

This is similar to how the PCI binding works internally, but I find that
a bit confusing as well, so given those two choices, I'd prefer the first
one.
   
> Version C - 2 address cells, 0 size cells (!) : In this version we hide the size component in 
> the intermediate space.  I don't know if that will actually work, but my guess is that it
> probably would.  The intermediate address space is like version A with the omission of the
> offset field.  The intermediate address just specifies the port number and the address type.

My guess is that it doesn't work with the current Linux code that transforms
the addresses. I've just recently seen the code complain about any platform
device whose parent has #size-cells=0.

	Arnd

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-20 19:57                                                                   ` Arnd Bergmann
  0 siblings, 0 replies; 249+ messages in thread
From: Arnd Bergmann @ 2012-06-20 19:57 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 19 June 2012, Mitch Bradley wrote:

> Version A - 3 address cells:  In this version, the intermediate address 
> space has 3 cells:  port#, address type, offset.  Address type is
>    0 : root port
>    1 : config space
>    2 : extended config space
>    3 : I/O
>    4 : non-prefetchable memory
>    5 : prefetchable memory.
> 
> The third cell "offset" is necessary so that the size field has a number 
> space that can include it.

I agree with Stephen that this is a clever way to encode all the address spaces,
very nice!

> Version B - 2 address cells:  In this first version, the intermediate
> address space has 2 cells:  port#, offset.  The address type (I/O, mem,
> etc) is the high digit of in the offset:
>     Offset 0....... : Root port
>     Offset 1....... : config
>     Offset 2....... : extended config
>     Offset 3....... : I/O
>     Offset 4....... : non-prefetchable memory
>     Offset 5....... : prefetchable memory.

This is similar to how the PCI binding works internally, but I find that
a bit confusing as well, so given those two choices, I'd prefer the first
one.
   
> Version C - 2 address cells, 0 size cells (!) : In this version we hide the size component in 
> the intermediate space.  I don't know if that will actually work, but my guess is that it
> probably would.  The intermediate address space is like version A with the omission of the
> offset field.  The intermediate address just specifies the port number and the address type.

My guess is that it doesn't work with the current Linux code that transforms
the addresses. I've just recently seen the code complain about any platform
device whose parent has #size-cells=0.

	Arnd

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-20 19:57                                                                   ` Arnd Bergmann
@ 2012-06-20 20:19                                                                     ` Mitch Bradley
  -1 siblings, 0 replies; 249+ messages in thread
From: Mitch Bradley @ 2012-06-20 20:19 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Thierry Reding, Stephen Warren, Russell King, linux-pci,
	devicetree-discuss, Rob Herring, Jesse Barnes, Colin Cross,
	linux-tegra, linux-arm-kernel

On 6/20/2012 9:57 AM, Arnd Bergmann wrote:
> On Tuesday 19 June 2012, Mitch Bradley wrote:
>
>> Version A - 3 address cells:  In this version, the intermediate address
>> space has 3 cells:  port#, address type, offset.  Address type is
>>     0 : root port
>>     1 : config space
>>     2 : extended config space
>>     3 : I/O
>>     4 : non-prefetchable memory
>>     5 : prefetchable memory.
>>
>> The third cell "offset" is necessary so that the size field has a number
>> space that can include it.
>
> I agree with Stephen that this is a clever way to encode all the address spaces,
> very nice!
>
>> Version B - 2 address cells:  In this first version, the intermediate
>> address space has 2 cells:  port#, offset.  The address type (I/O, mem,
>> etc) is the high digit of in the offset:
>>      Offset 0....... : Root port
>>      Offset 1....... : config
>>      Offset 2....... : extended config
>>      Offset 3....... : I/O
>>      Offset 4....... : non-prefetchable memory
>>      Offset 5....... : prefetchable memory.
>
> This is similar to how the PCI binding works internally, but I find that
> a bit confusing as well, so given those two choices, I'd prefer the first
> one.

Yeah, version A is my preference too.  It's straightforward and clear.  
I did the other two
versions mostly to explore the possibility space.

>
>     
>> Version C - 2 address cells, 0 size cells (!) : In this version we hide the size component in
>> the intermediate space.  I don't know if that will actually work, but my guess is that it
>> probably would.  The intermediate address space is like version A with the omission of the
>> offset field.  The intermediate address just specifies the port number and the address type.
>
> My guess is that it doesn't work with the current Linux code that transforms
> the addresses. I've just recently seen the code complain about any platform
> device whose parent has #size-cells=0.
>
> 	Arnd
>

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-20 20:19                                                                     ` Mitch Bradley
  0 siblings, 0 replies; 249+ messages in thread
From: Mitch Bradley @ 2012-06-20 20:19 UTC (permalink / raw)
  To: linux-arm-kernel

On 6/20/2012 9:57 AM, Arnd Bergmann wrote:
> On Tuesday 19 June 2012, Mitch Bradley wrote:
>
>> Version A - 3 address cells:  In this version, the intermediate address
>> space has 3 cells:  port#, address type, offset.  Address type is
>>     0 : root port
>>     1 : config space
>>     2 : extended config space
>>     3 : I/O
>>     4 : non-prefetchable memory
>>     5 : prefetchable memory.
>>
>> The third cell "offset" is necessary so that the size field has a number
>> space that can include it.
>
> I agree with Stephen that this is a clever way to encode all the address spaces,
> very nice!
>
>> Version B - 2 address cells:  In this first version, the intermediate
>> address space has 2 cells:  port#, offset.  The address type (I/O, mem,
>> etc) is the high digit of in the offset:
>>      Offset 0....... : Root port
>>      Offset 1....... : config
>>      Offset 2....... : extended config
>>      Offset 3....... : I/O
>>      Offset 4....... : non-prefetchable memory
>>      Offset 5....... : prefetchable memory.
>
> This is similar to how the PCI binding works internally, but I find that
> a bit confusing as well, so given those two choices, I'd prefer the first
> one.

Yeah, version A is my preference too.  It's straightforward and clear.  
I did the other two
versions mostly to explore the possibility space.

>
>     
>> Version C - 2 address cells, 0 size cells (!) : In this version we hide the size component in
>> the intermediate space.  I don't know if that will actually work, but my guess is that it
>> probably would.  The intermediate address space is like version A with the omission of the
>> offset field.  The intermediate address just specifies the port number and the address type.
>
> My guess is that it doesn't work with the current Linux code that transforms
> the addresses. I've just recently seen the code complain about any platform
> device whose parent has #size-cells=0.
>
> 	Arnd
>

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-19 21:31                                                                 ` Mitch Bradley
  (?)
@ 2012-06-21  6:47                                                                   ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-21  6:47 UTC (permalink / raw)
  To: Mitch Bradley
  Cc: Russell King, Arnd Bergmann, Stephen Warren, linux-pci,
	devicetree-discuss, Jesse Barnes, Rob Herring, Colin Cross,
	linux-tegra, linux-arm-kernel


[-- Attachment #1.1: Type: text/plain, Size: 10025 bytes --]

On Tue, Jun 19, 2012 at 11:31:39AM -1000, Mitch Bradley wrote:
> On 6/19/2012 3:30 AM, Thierry Reding wrote:
> >On Fri, Jun 15, 2012 at 08:12:36AM +0200, Thierry Reding wrote:
> >>On Thu, Jun 14, 2012 at 01:50:56PM -0600, Stephen Warren wrote:
> >>>On 06/14/2012 01:29 PM, Thierry Reding wrote:
> >>>>On Thu, Jun 14, 2012 at 12:30:50PM -0600, Stephen Warren wrote:
> >>>>>On 06/14/2012 03:19 AM, Thierry Reding wrote:
> >>>...
> >>>>>>#address-cells = <1>; #size-cells = <1>;
> >>>>>>
> >>>>>>pci@80000000 {
> >>>>>
> >>>>>I'm still not convinced that using the address of the port's
> >>>>>registers is the correct way to represent each port. The port
> >>>>>index seems much more useful.
> >>>>>
> >>>>>The main reason here is that there are a lot of registers that
> >>>>>contain fields for each port - far more than the combination of
> >>>>>this node's reg and ctrl-offset (which I assume is an address
> >>>>>offset for just one example of this issue) properties can
> >>>>>describe. The bit position and bit stride of these fields isn't
> >>>>>necessarily the same in each register. Do we want a property like
> >>>>>ctrl-offset for every single type of field in every single shared
> >>>>>register that describes the location of the relevant data, or
> >>>>>just a single "port ID" bit that can be applied to anything?
> >>>>>
> >>>>>(Perhaps this isn't so obvious looking at the TRM since it
> >>>>>doesn't document all registers, and I'm also looking at the
> >>>>>Tegra30 documentation too, which might be more exposed to this -
> >>>>>I haven't correlated all the documentation sources to be sure
> >>>>>though)
> >>>>
> >>>>I agree that maybe adding properties for each bit position or
> >>>>register offset may not work out too well. But I think it still
> >>>>makes sense to use the base address of the port's registers (see
> >>>>below). We could of course add some code to determine the index
> >>>>from the base address at initialization time and reuse the index
> >>>>where appropriate.
> >>>
> >>>To me, working back from address to ID then using the ID to calculate
> >>>some other addresses seems far more icky than just calculating all the
> >>>addresses based off of one ID. But, I suppose this doesn't make a huge
> >>>practical difference.
> >>
> >>This really depends on the device vs. no device decision below. If we can
> >>make it work without needing an extra device for it, then using the index
> >>is certainly better. However, if we instantiate devices from the DT, then
> >>we have the address anyway and adding the index as a property would be
> >>redundant and error prone (what happens if somebody sets the index of the
> >>port at address 0x80000000 to 2?).
> >
> >An additional problem with this is that we'd have to add the following
> >to the pcie-controller node:
> >
> >	#address-cells = <1>;
> >	#size-cells = <0>;
> >
> >This will conflict with the "ranges" property, because suddenly we can
> >no longer map the regions properly. Maybe Mitch can comment on whether
> >this is possible or not?
> >
> >To make it clearer what I'm talking about, here's the DT snippet again
> >(with the compatible property removed from the pci@ nodes because they
> >are no longer probed by a driver, the "simple-bus" removed from the
> >pcie-controller node's compatible property removed and its #address-
> >and #size-cells properties adjusted as described above).
> >
> >	pcie-controller {
> >		compatible = "nvidia,tegra20-pcie";
> >		reg = <0x80003000 0x00000800   /* PADS registers */
> >		       0x80003800 0x00000200   /* AFI registers */
> >		       0x80004000 0x00100000   /* configuration space */
> >		       0x80104000 0x00100000>; /* extended configuration space */
> >		interrupts = <0 98 0x04   /* controller interrupt */
> >			      0 99 0x04>; /* MSI interrupt */
> >		status = "disabled";
> >
> >		ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */
> >			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
> >			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
> >			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
> >
> >		#address-cells = <1>;
> >		#size-cells = <0>;
> >
> >		pci@0 {
> >			reg = <2>;
> >			status = "disabled";
> >
> >			#address-cells = <3>;
> >			#size-cells = <2>;
> >
> >			ranges = <0x81000000 0 0 0x80400000 0 0x00008000   /* I/O */
> >				  0x82000000 0 0 0x90000000 0 0x08000000   /* non-prefetchable memory */
> >				  0xc2000000 0 0 0xa0000000 0 0x08000000>; /* prefetchable memory */
> >
> >			nvidia,ctrl-offset = <0x110>;
> >			nvidia,num-lanes = <2>;
> >		};
> >
> >		pci@1 {
> >			reg = <1>;
> >			status = "disabled";
> >
> >			#address-cells = <3>;
> >			#size-cells = <2>;
> >
> >			ranges = <0x81000000 0 0 0x80408000 0 0x00008000   /* I/O */
> >				  0x82000000 0 0 0x98000000 0 0x08000000   /* non-prefetchable memory */
> >				  0xc2000000 0 0 0xa8000000 0 0x08000000>; /* prefetchable memory */
> >
> >			nvidia,ctrl-offset = <0x118>;
> >			nvidia,num-lanes = <2>;
> >		};
> >	};
> >
> >AIUI none of the ranges properties are valid anymore, because the bus
> >represented by pcie-controller no longer reflects the truth, namely that
> >it translates the CPU address space to the PCI address space.
> >
> 
> I think you can use a small-integer port number as an address by
> defining the intermediate address space properly, and using
> appropriate ranges above and below.  Here's a swag at how that would
> look.
> 
> I present three versions, using different choices for the
> intermediate address space encoding.  The intermediate address space
> may seem somewhat artificial, in that it decouples the "linear pass
> through of ranges" between the lower PCI address space and the upper
> CPU address space.  But in another sense, it accurately reflects
> that fact that the bus bridge "slices and dices" that linear address
> space into non-contiguous pieces.
> 
> Note that I'm also fixing a problem that I neglected to mention
> earlier - namely the fact that config space is part of the child PCI
> address space so it must be passed through.

This doesn't quite match how the Tegra PCIe controller works. Basically,
every access to a device's (extended) configuration space goes through a
single region of memory-mapped registers, independent of which port is
the parent of the device.

Is it okay to pass both configuration spaces via the ranges property but
still list them in the reg property of the controller?

> Version A - 3 address cells:  In this version, the intermediate
> address space has 3 cells:  port#, address type, offset.  Address
> type is
>   0 : root port
>   1 : config space
>   2 : extended config space
>   3 : I/O
>   4 : non-prefetchable memory
>   5 : prefetchable memory.
> 
> The third cell "offset" is necessary so that the size field has a
> number space that can include it.
> 
> 	pcie-controller {
> 		compatible = "nvidia,tegra20-pcie";
> 		reg = <0x80003000 0x00000800   /* PADS registers */
> 		       0x80003800 0x00000200>; /* extended configuration space */
> 		interrupts = <0 98 0x04   /* controller interrupt */
> 			      0 99 0x04>; /* MSI interrupt */
> 		status = "disabled";
> 
> 		ranges = <0 0 0  0x80000000 0x00001000   /* Root port 0 */
> 			  0 1 0  0x80004000 0x00080000   /* Port 0 config space */
> 			  0 2 0  0x80104000 0x00080000   /* Port 0 ext config space *
> 			  0 3 0  0x80400000 0x00008000   /* Port 0 downstream I/O */
> 			  0 4 0  0x90000000 0x08000000   /* Port 0 non-prefetchable memory */
> 			  0 5 0  0xa0000000 0x08000000   /* Port 0 prefetchable memory */
> 
> 			  1 0 0  0x80001000 0x00001000   /* Root port 1 */
> 			  1 1 0  0x80004000 0x00080000   /* Port 1 config space */
> 			  1 2 0  0x80184000 0x00080000   /* Port 1 ext config space */
> 			  1 3 0  0x80408000 0x00010000   /* Port 1 downstream I/O */
> 			  1 4 0  0x98000000 0x08000000   /* Port 1 non-prefetchable memory */
> 			  1 5 0  0xa0000000 0x08000000>; /* Port 1 prefetchable memory */
> 
> 		#address-cells = <3>;
> 		#size-cells = <1>;
> 
> 		pci@0 {
> 			reg = <0 0 0 0x1000>;
> 			status = "disabled";
> 
> 			#address-cells = <3>;
> 			#size-cells = <2>;
> 
> 			ranges = <0x80000000 0 0  0 1 0  0 0x00080000   /* config */
> 				  0x90000000 0 0  0 2 0  0 0x00080000   /* extended config */
> 				  0x81000000 0 0  0 3 0  0 0x00008000   /* I/O */
> 				  0x82000000 0 0  0 4 0  0 0x08000000   /* non-prefetchable memory */
> 				  0xc2000000 0 0  0 5 0  0 0x08000000>; /* prefetchable memory */
> 
> 			nvidia,ctrl-offset = <0x110>;
> 			nvidia,num-lanes = <2>;
> 		};
> 
> 
> 		pci@1 {
> 			reg = <1 0 0 0x1000>;
> 			status = "disabled";
> 
> 			#address-cells = <3>;
> 			#size-cells = <2>;
> 
> 			ranges = <0x80000000 0 0  1 1 0  0 0x00080000   /* config */
> 				  0x90000000 0 0  1 2 0  0 0x00080000   /* extended config */
> 				  0x81000000 0 0  1 3 0  0 0x00008000   /* I/O */
> 				  0x82000000 0 0  1 4 0  0 0x08000000   /* non-prefetchable memory */
> 				  0xc2000000 0 0  1 5 0  0 0x08000000>; /* prefetchable memory */
> 
> 			nvidia,ctrl-offset = <0x118>;
> 			nvidia,num-lanes = <2>;
> 		};

Everybody seems to be happy with this approach, so I'll give it a shot.
There is one thing I'm still unsure about, though. What if somebody uses
the above scheme and maps the registers to the wrong port. The same goes
for the nvidia,ctrl-offset property. It needs to match the register
offset because they are directly related. I suppose we could leave that
property away and look up the register via the port index (which, as
Stephen already said, we'll have to do in other places anyway, unless we
list all bit positions in the DT).

Can we safely ignore such issues and assume the device tree to always be
right? Should we just not care if somebody uses it wrongly?

Thierry

[-- Attachment #1.2: Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

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

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-21  6:47                                                                   ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-21  6:47 UTC (permalink / raw)
  To: Mitch Bradley
  Cc: Stephen Warren, Russell King, linux-pci, devicetree-discuss,
	Rob Herring, Jesse Barnes, Colin Cross, linux-tegra,
	linux-arm-kernel, Arnd Bergmann

[-- Attachment #1: Type: text/plain, Size: 10025 bytes --]

On Tue, Jun 19, 2012 at 11:31:39AM -1000, Mitch Bradley wrote:
> On 6/19/2012 3:30 AM, Thierry Reding wrote:
> >On Fri, Jun 15, 2012 at 08:12:36AM +0200, Thierry Reding wrote:
> >>On Thu, Jun 14, 2012 at 01:50:56PM -0600, Stephen Warren wrote:
> >>>On 06/14/2012 01:29 PM, Thierry Reding wrote:
> >>>>On Thu, Jun 14, 2012 at 12:30:50PM -0600, Stephen Warren wrote:
> >>>>>On 06/14/2012 03:19 AM, Thierry Reding wrote:
> >>>...
> >>>>>>#address-cells = <1>; #size-cells = <1>;
> >>>>>>
> >>>>>>pci@80000000 {
> >>>>>
> >>>>>I'm still not convinced that using the address of the port's
> >>>>>registers is the correct way to represent each port. The port
> >>>>>index seems much more useful.
> >>>>>
> >>>>>The main reason here is that there are a lot of registers that
> >>>>>contain fields for each port - far more than the combination of
> >>>>>this node's reg and ctrl-offset (which I assume is an address
> >>>>>offset for just one example of this issue) properties can
> >>>>>describe. The bit position and bit stride of these fields isn't
> >>>>>necessarily the same in each register. Do we want a property like
> >>>>>ctrl-offset for every single type of field in every single shared
> >>>>>register that describes the location of the relevant data, or
> >>>>>just a single "port ID" bit that can be applied to anything?
> >>>>>
> >>>>>(Perhaps this isn't so obvious looking at the TRM since it
> >>>>>doesn't document all registers, and I'm also looking at the
> >>>>>Tegra30 documentation too, which might be more exposed to this -
> >>>>>I haven't correlated all the documentation sources to be sure
> >>>>>though)
> >>>>
> >>>>I agree that maybe adding properties for each bit position or
> >>>>register offset may not work out too well. But I think it still
> >>>>makes sense to use the base address of the port's registers (see
> >>>>below). We could of course add some code to determine the index
> >>>>from the base address at initialization time and reuse the index
> >>>>where appropriate.
> >>>
> >>>To me, working back from address to ID then using the ID to calculate
> >>>some other addresses seems far more icky than just calculating all the
> >>>addresses based off of one ID. But, I suppose this doesn't make a huge
> >>>practical difference.
> >>
> >>This really depends on the device vs. no device decision below. If we can
> >>make it work without needing an extra device for it, then using the index
> >>is certainly better. However, if we instantiate devices from the DT, then
> >>we have the address anyway and adding the index as a property would be
> >>redundant and error prone (what happens if somebody sets the index of the
> >>port at address 0x80000000 to 2?).
> >
> >An additional problem with this is that we'd have to add the following
> >to the pcie-controller node:
> >
> >	#address-cells = <1>;
> >	#size-cells = <0>;
> >
> >This will conflict with the "ranges" property, because suddenly we can
> >no longer map the regions properly. Maybe Mitch can comment on whether
> >this is possible or not?
> >
> >To make it clearer what I'm talking about, here's the DT snippet again
> >(with the compatible property removed from the pci@ nodes because they
> >are no longer probed by a driver, the "simple-bus" removed from the
> >pcie-controller node's compatible property removed and its #address-
> >and #size-cells properties adjusted as described above).
> >
> >	pcie-controller {
> >		compatible = "nvidia,tegra20-pcie";
> >		reg = <0x80003000 0x00000800   /* PADS registers */
> >		       0x80003800 0x00000200   /* AFI registers */
> >		       0x80004000 0x00100000   /* configuration space */
> >		       0x80104000 0x00100000>; /* extended configuration space */
> >		interrupts = <0 98 0x04   /* controller interrupt */
> >			      0 99 0x04>; /* MSI interrupt */
> >		status = "disabled";
> >
> >		ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */
> >			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
> >			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
> >			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
> >
> >		#address-cells = <1>;
> >		#size-cells = <0>;
> >
> >		pci@0 {
> >			reg = <2>;
> >			status = "disabled";
> >
> >			#address-cells = <3>;
> >			#size-cells = <2>;
> >
> >			ranges = <0x81000000 0 0 0x80400000 0 0x00008000   /* I/O */
> >				  0x82000000 0 0 0x90000000 0 0x08000000   /* non-prefetchable memory */
> >				  0xc2000000 0 0 0xa0000000 0 0x08000000>; /* prefetchable memory */
> >
> >			nvidia,ctrl-offset = <0x110>;
> >			nvidia,num-lanes = <2>;
> >		};
> >
> >		pci@1 {
> >			reg = <1>;
> >			status = "disabled";
> >
> >			#address-cells = <3>;
> >			#size-cells = <2>;
> >
> >			ranges = <0x81000000 0 0 0x80408000 0 0x00008000   /* I/O */
> >				  0x82000000 0 0 0x98000000 0 0x08000000   /* non-prefetchable memory */
> >				  0xc2000000 0 0 0xa8000000 0 0x08000000>; /* prefetchable memory */
> >
> >			nvidia,ctrl-offset = <0x118>;
> >			nvidia,num-lanes = <2>;
> >		};
> >	};
> >
> >AIUI none of the ranges properties are valid anymore, because the bus
> >represented by pcie-controller no longer reflects the truth, namely that
> >it translates the CPU address space to the PCI address space.
> >
> 
> I think you can use a small-integer port number as an address by
> defining the intermediate address space properly, and using
> appropriate ranges above and below.  Here's a swag at how that would
> look.
> 
> I present three versions, using different choices for the
> intermediate address space encoding.  The intermediate address space
> may seem somewhat artificial, in that it decouples the "linear pass
> through of ranges" between the lower PCI address space and the upper
> CPU address space.  But in another sense, it accurately reflects
> that fact that the bus bridge "slices and dices" that linear address
> space into non-contiguous pieces.
> 
> Note that I'm also fixing a problem that I neglected to mention
> earlier - namely the fact that config space is part of the child PCI
> address space so it must be passed through.

This doesn't quite match how the Tegra PCIe controller works. Basically,
every access to a device's (extended) configuration space goes through a
single region of memory-mapped registers, independent of which port is
the parent of the device.

Is it okay to pass both configuration spaces via the ranges property but
still list them in the reg property of the controller?

> Version A - 3 address cells:  In this version, the intermediate
> address space has 3 cells:  port#, address type, offset.  Address
> type is
>   0 : root port
>   1 : config space
>   2 : extended config space
>   3 : I/O
>   4 : non-prefetchable memory
>   5 : prefetchable memory.
> 
> The third cell "offset" is necessary so that the size field has a
> number space that can include it.
> 
> 	pcie-controller {
> 		compatible = "nvidia,tegra20-pcie";
> 		reg = <0x80003000 0x00000800   /* PADS registers */
> 		       0x80003800 0x00000200>; /* extended configuration space */
> 		interrupts = <0 98 0x04   /* controller interrupt */
> 			      0 99 0x04>; /* MSI interrupt */
> 		status = "disabled";
> 
> 		ranges = <0 0 0  0x80000000 0x00001000   /* Root port 0 */
> 			  0 1 0  0x80004000 0x00080000   /* Port 0 config space */
> 			  0 2 0  0x80104000 0x00080000   /* Port 0 ext config space *
> 			  0 3 0  0x80400000 0x00008000   /* Port 0 downstream I/O */
> 			  0 4 0  0x90000000 0x08000000   /* Port 0 non-prefetchable memory */
> 			  0 5 0  0xa0000000 0x08000000   /* Port 0 prefetchable memory */
> 
> 			  1 0 0  0x80001000 0x00001000   /* Root port 1 */
> 			  1 1 0  0x80004000 0x00080000   /* Port 1 config space */
> 			  1 2 0  0x80184000 0x00080000   /* Port 1 ext config space */
> 			  1 3 0  0x80408000 0x00010000   /* Port 1 downstream I/O */
> 			  1 4 0  0x98000000 0x08000000   /* Port 1 non-prefetchable memory */
> 			  1 5 0  0xa0000000 0x08000000>; /* Port 1 prefetchable memory */
> 
> 		#address-cells = <3>;
> 		#size-cells = <1>;
> 
> 		pci@0 {
> 			reg = <0 0 0 0x1000>;
> 			status = "disabled";
> 
> 			#address-cells = <3>;
> 			#size-cells = <2>;
> 
> 			ranges = <0x80000000 0 0  0 1 0  0 0x00080000   /* config */
> 				  0x90000000 0 0  0 2 0  0 0x00080000   /* extended config */
> 				  0x81000000 0 0  0 3 0  0 0x00008000   /* I/O */
> 				  0x82000000 0 0  0 4 0  0 0x08000000   /* non-prefetchable memory */
> 				  0xc2000000 0 0  0 5 0  0 0x08000000>; /* prefetchable memory */
> 
> 			nvidia,ctrl-offset = <0x110>;
> 			nvidia,num-lanes = <2>;
> 		};
> 
> 
> 		pci@1 {
> 			reg = <1 0 0 0x1000>;
> 			status = "disabled";
> 
> 			#address-cells = <3>;
> 			#size-cells = <2>;
> 
> 			ranges = <0x80000000 0 0  1 1 0  0 0x00080000   /* config */
> 				  0x90000000 0 0  1 2 0  0 0x00080000   /* extended config */
> 				  0x81000000 0 0  1 3 0  0 0x00008000   /* I/O */
> 				  0x82000000 0 0  1 4 0  0 0x08000000   /* non-prefetchable memory */
> 				  0xc2000000 0 0  1 5 0  0 0x08000000>; /* prefetchable memory */
> 
> 			nvidia,ctrl-offset = <0x118>;
> 			nvidia,num-lanes = <2>;
> 		};

Everybody seems to be happy with this approach, so I'll give it a shot.
There is one thing I'm still unsure about, though. What if somebody uses
the above scheme and maps the registers to the wrong port. The same goes
for the nvidia,ctrl-offset property. It needs to match the register
offset because they are directly related. I suppose we could leave that
property away and look up the register via the port index (which, as
Stephen already said, we'll have to do in other places anyway, unless we
list all bit positions in the DT).

Can we safely ignore such issues and assume the device tree to always be
right? Should we just not care if somebody uses it wrongly?

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-21  6:47                                                                   ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-21  6:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jun 19, 2012 at 11:31:39AM -1000, Mitch Bradley wrote:
> On 6/19/2012 3:30 AM, Thierry Reding wrote:
> >On Fri, Jun 15, 2012 at 08:12:36AM +0200, Thierry Reding wrote:
> >>On Thu, Jun 14, 2012 at 01:50:56PM -0600, Stephen Warren wrote:
> >>>On 06/14/2012 01:29 PM, Thierry Reding wrote:
> >>>>On Thu, Jun 14, 2012 at 12:30:50PM -0600, Stephen Warren wrote:
> >>>>>On 06/14/2012 03:19 AM, Thierry Reding wrote:
> >>>...
> >>>>>>#address-cells = <1>; #size-cells = <1>;
> >>>>>>
> >>>>>>pci at 80000000 {
> >>>>>
> >>>>>I'm still not convinced that using the address of the port's
> >>>>>registers is the correct way to represent each port. The port
> >>>>>index seems much more useful.
> >>>>>
> >>>>>The main reason here is that there are a lot of registers that
> >>>>>contain fields for each port - far more than the combination of
> >>>>>this node's reg and ctrl-offset (which I assume is an address
> >>>>>offset for just one example of this issue) properties can
> >>>>>describe. The bit position and bit stride of these fields isn't
> >>>>>necessarily the same in each register. Do we want a property like
> >>>>>ctrl-offset for every single type of field in every single shared
> >>>>>register that describes the location of the relevant data, or
> >>>>>just a single "port ID" bit that can be applied to anything?
> >>>>>
> >>>>>(Perhaps this isn't so obvious looking at the TRM since it
> >>>>>doesn't document all registers, and I'm also looking at the
> >>>>>Tegra30 documentation too, which might be more exposed to this -
> >>>>>I haven't correlated all the documentation sources to be sure
> >>>>>though)
> >>>>
> >>>>I agree that maybe adding properties for each bit position or
> >>>>register offset may not work out too well. But I think it still
> >>>>makes sense to use the base address of the port's registers (see
> >>>>below). We could of course add some code to determine the index
> >>>>from the base address at initialization time and reuse the index
> >>>>where appropriate.
> >>>
> >>>To me, working back from address to ID then using the ID to calculate
> >>>some other addresses seems far more icky than just calculating all the
> >>>addresses based off of one ID. But, I suppose this doesn't make a huge
> >>>practical difference.
> >>
> >>This really depends on the device vs. no device decision below. If we can
> >>make it work without needing an extra device for it, then using the index
> >>is certainly better. However, if we instantiate devices from the DT, then
> >>we have the address anyway and adding the index as a property would be
> >>redundant and error prone (what happens if somebody sets the index of the
> >>port at address 0x80000000 to 2?).
> >
> >An additional problem with this is that we'd have to add the following
> >to the pcie-controller node:
> >
> >	#address-cells = <1>;
> >	#size-cells = <0>;
> >
> >This will conflict with the "ranges" property, because suddenly we can
> >no longer map the regions properly. Maybe Mitch can comment on whether
> >this is possible or not?
> >
> >To make it clearer what I'm talking about, here's the DT snippet again
> >(with the compatible property removed from the pci@ nodes because they
> >are no longer probed by a driver, the "simple-bus" removed from the
> >pcie-controller node's compatible property removed and its #address-
> >and #size-cells properties adjusted as described above).
> >
> >	pcie-controller {
> >		compatible = "nvidia,tegra20-pcie";
> >		reg = <0x80003000 0x00000800   /* PADS registers */
> >		       0x80003800 0x00000200   /* AFI registers */
> >		       0x80004000 0x00100000   /* configuration space */
> >		       0x80104000 0x00100000>; /* extended configuration space */
> >		interrupts = <0 98 0x04   /* controller interrupt */
> >			      0 99 0x04>; /* MSI interrupt */
> >		status = "disabled";
> >
> >		ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */
> >			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
> >			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
> >			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
> >
> >		#address-cells = <1>;
> >		#size-cells = <0>;
> >
> >		pci at 0 {
> >			reg = <2>;
> >			status = "disabled";
> >
> >			#address-cells = <3>;
> >			#size-cells = <2>;
> >
> >			ranges = <0x81000000 0 0 0x80400000 0 0x00008000   /* I/O */
> >				  0x82000000 0 0 0x90000000 0 0x08000000   /* non-prefetchable memory */
> >				  0xc2000000 0 0 0xa0000000 0 0x08000000>; /* prefetchable memory */
> >
> >			nvidia,ctrl-offset = <0x110>;
> >			nvidia,num-lanes = <2>;
> >		};
> >
> >		pci at 1 {
> >			reg = <1>;
> >			status = "disabled";
> >
> >			#address-cells = <3>;
> >			#size-cells = <2>;
> >
> >			ranges = <0x81000000 0 0 0x80408000 0 0x00008000   /* I/O */
> >				  0x82000000 0 0 0x98000000 0 0x08000000   /* non-prefetchable memory */
> >				  0xc2000000 0 0 0xa8000000 0 0x08000000>; /* prefetchable memory */
> >
> >			nvidia,ctrl-offset = <0x118>;
> >			nvidia,num-lanes = <2>;
> >		};
> >	};
> >
> >AIUI none of the ranges properties are valid anymore, because the bus
> >represented by pcie-controller no longer reflects the truth, namely that
> >it translates the CPU address space to the PCI address space.
> >
> 
> I think you can use a small-integer port number as an address by
> defining the intermediate address space properly, and using
> appropriate ranges above and below.  Here's a swag at how that would
> look.
> 
> I present three versions, using different choices for the
> intermediate address space encoding.  The intermediate address space
> may seem somewhat artificial, in that it decouples the "linear pass
> through of ranges" between the lower PCI address space and the upper
> CPU address space.  But in another sense, it accurately reflects
> that fact that the bus bridge "slices and dices" that linear address
> space into non-contiguous pieces.
> 
> Note that I'm also fixing a problem that I neglected to mention
> earlier - namely the fact that config space is part of the child PCI
> address space so it must be passed through.

This doesn't quite match how the Tegra PCIe controller works. Basically,
every access to a device's (extended) configuration space goes through a
single region of memory-mapped registers, independent of which port is
the parent of the device.

Is it okay to pass both configuration spaces via the ranges property but
still list them in the reg property of the controller?

> Version A - 3 address cells:  In this version, the intermediate
> address space has 3 cells:  port#, address type, offset.  Address
> type is
>   0 : root port
>   1 : config space
>   2 : extended config space
>   3 : I/O
>   4 : non-prefetchable memory
>   5 : prefetchable memory.
> 
> The third cell "offset" is necessary so that the size field has a
> number space that can include it.
> 
> 	pcie-controller {
> 		compatible = "nvidia,tegra20-pcie";
> 		reg = <0x80003000 0x00000800   /* PADS registers */
> 		       0x80003800 0x00000200>; /* extended configuration space */
> 		interrupts = <0 98 0x04   /* controller interrupt */
> 			      0 99 0x04>; /* MSI interrupt */
> 		status = "disabled";
> 
> 		ranges = <0 0 0  0x80000000 0x00001000   /* Root port 0 */
> 			  0 1 0  0x80004000 0x00080000   /* Port 0 config space */
> 			  0 2 0  0x80104000 0x00080000   /* Port 0 ext config space *
> 			  0 3 0  0x80400000 0x00008000   /* Port 0 downstream I/O */
> 			  0 4 0  0x90000000 0x08000000   /* Port 0 non-prefetchable memory */
> 			  0 5 0  0xa0000000 0x08000000   /* Port 0 prefetchable memory */
> 
> 			  1 0 0  0x80001000 0x00001000   /* Root port 1 */
> 			  1 1 0  0x80004000 0x00080000   /* Port 1 config space */
> 			  1 2 0  0x80184000 0x00080000   /* Port 1 ext config space */
> 			  1 3 0  0x80408000 0x00010000   /* Port 1 downstream I/O */
> 			  1 4 0  0x98000000 0x08000000   /* Port 1 non-prefetchable memory */
> 			  1 5 0  0xa0000000 0x08000000>; /* Port 1 prefetchable memory */
> 
> 		#address-cells = <3>;
> 		#size-cells = <1>;
> 
> 		pci at 0 {
> 			reg = <0 0 0 0x1000>;
> 			status = "disabled";
> 
> 			#address-cells = <3>;
> 			#size-cells = <2>;
> 
> 			ranges = <0x80000000 0 0  0 1 0  0 0x00080000   /* config */
> 				  0x90000000 0 0  0 2 0  0 0x00080000   /* extended config */
> 				  0x81000000 0 0  0 3 0  0 0x00008000   /* I/O */
> 				  0x82000000 0 0  0 4 0  0 0x08000000   /* non-prefetchable memory */
> 				  0xc2000000 0 0  0 5 0  0 0x08000000>; /* prefetchable memory */
> 
> 			nvidia,ctrl-offset = <0x110>;
> 			nvidia,num-lanes = <2>;
> 		};
> 
> 
> 		pci at 1 {
> 			reg = <1 0 0 0x1000>;
> 			status = "disabled";
> 
> 			#address-cells = <3>;
> 			#size-cells = <2>;
> 
> 			ranges = <0x80000000 0 0  1 1 0  0 0x00080000   /* config */
> 				  0x90000000 0 0  1 2 0  0 0x00080000   /* extended config */
> 				  0x81000000 0 0  1 3 0  0 0x00008000   /* I/O */
> 				  0x82000000 0 0  1 4 0  0 0x08000000   /* non-prefetchable memory */
> 				  0xc2000000 0 0  1 5 0  0 0x08000000>; /* prefetchable memory */
> 
> 			nvidia,ctrl-offset = <0x118>;
> 			nvidia,num-lanes = <2>;
> 		};

Everybody seems to be happy with this approach, so I'll give it a shot.
There is one thing I'm still unsure about, though. What if somebody uses
the above scheme and maps the registers to the wrong port. The same goes
for the nvidia,ctrl-offset property. It needs to match the register
offset because they are directly related. I suppose we could leave that
property away and look up the register via the port index (which, as
Stephen already said, we'll have to do in other places anyway, unless we
list all bit positions in the DT).

Can we safely ignore such issues and assume the device tree to always be
right? Should we just not care if somebody uses it wrongly?

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120621/1025714d/attachment.sig>

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

* Re: [PATCH v2 08/10] ARM: tegra: harmony: Initialize regulators from DT
  2012-06-11 15:05   ` Thierry Reding
  (?)
@ 2012-06-21 20:17       ` Stephen Warren
  -1 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-21 20:17 UTC (permalink / raw)
  To: Thierry Reding
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jesse Barnes,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, Grant Likely, Rob Herring,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Russell King,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Colin Cross,
	Olof Johansson

On 06/11/2012 09:05 AM, Thierry Reding wrote:
> Device tree support for the TPS6586x PMU used on Harmony has recently
> been added. This commit adds the required device tree nodes to probe the
> PMU from the device tree.

> diff --git a/arch/arm/boot/dts/tegra-harmony.dts b/arch/arm/boot/dts/tegra-harmony.dts

> +		tps6586x@34 {
> +			compatible = "ti,tps6586x";
> +			reg = <0x34>;
> +			interrupts = <0 88 0x4>;

I believe that should be interrupt 86 not 88.

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

* Re: [PATCH v2 08/10] ARM: tegra: harmony: Initialize regulators from DT
@ 2012-06-21 20:17       ` Stephen Warren
  0 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-21 20:17 UTC (permalink / raw)
  To: Thierry Reding
  Cc: linux-tegra, Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson

On 06/11/2012 09:05 AM, Thierry Reding wrote:
> Device tree support for the TPS6586x PMU used on Harmony has recently
> been added. This commit adds the required device tree nodes to probe the
> PMU from the device tree.

> diff --git a/arch/arm/boot/dts/tegra-harmony.dts b/arch/arm/boot/dts/tegra-harmony.dts

> +		tps6586x@34 {
> +			compatible = "ti,tps6586x";
> +			reg = <0x34>;
> +			interrupts = <0 88 0x4>;

I believe that should be interrupt 86 not 88.

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

* [PATCH v2 08/10] ARM: tegra: harmony: Initialize regulators from DT
@ 2012-06-21 20:17       ` Stephen Warren
  0 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-21 20:17 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/11/2012 09:05 AM, Thierry Reding wrote:
> Device tree support for the TPS6586x PMU used on Harmony has recently
> been added. This commit adds the required device tree nodes to probe the
> PMU from the device tree.

> diff --git a/arch/arm/boot/dts/tegra-harmony.dts b/arch/arm/boot/dts/tegra-harmony.dts

> +		tps6586x at 34 {
> +			compatible = "ti,tps6586x";
> +			reg = <0x34>;
> +			interrupts = <0 88 0x4>;

I believe that should be interrupt 86 not 88.

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

* Re: [PATCH v2 08/10] ARM: tegra: harmony: Initialize regulators from DT
  2012-06-21 20:17       ` Stephen Warren
  (?)
@ 2012-06-22  6:06           ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-22  6:06 UTC (permalink / raw)
  To: Stephen Warren
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jesse Barnes,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, Grant Likely, Rob Herring,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Russell King,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Colin Cross,
	Olof Johansson

[-- Attachment #1: Type: text/plain, Size: 613 bytes --]

On Thu, Jun 21, 2012 at 02:17:32PM -0600, Stephen Warren wrote:
> On 06/11/2012 09:05 AM, Thierry Reding wrote:
> > Device tree support for the TPS6586x PMU used on Harmony has recently
> > been added. This commit adds the required device tree nodes to probe the
> > PMU from the device tree.
> 
> > diff --git a/arch/arm/boot/dts/tegra-harmony.dts b/arch/arm/boot/dts/tegra-harmony.dts
> 
> > +		tps6586x@34 {
> > +			compatible = "ti,tps6586x";
> > +			reg = <0x34>;
> > +			interrupts = <0 88 0x4>;
> 
> I believe that should be interrupt 86 not 88.

Yes, you're absolutely correct.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH v2 08/10] ARM: tegra: harmony: Initialize regulators from DT
@ 2012-06-22  6:06           ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-22  6:06 UTC (permalink / raw)
  To: Stephen Warren
  Cc: linux-tegra, Jesse Barnes, linux-pci, Grant Likely, Rob Herring,
	devicetree-discuss, Russell King, linux-arm-kernel, Colin Cross,
	Olof Johansson

[-- Attachment #1: Type: text/plain, Size: 613 bytes --]

On Thu, Jun 21, 2012 at 02:17:32PM -0600, Stephen Warren wrote:
> On 06/11/2012 09:05 AM, Thierry Reding wrote:
> > Device tree support for the TPS6586x PMU used on Harmony has recently
> > been added. This commit adds the required device tree nodes to probe the
> > PMU from the device tree.
> 
> > diff --git a/arch/arm/boot/dts/tegra-harmony.dts b/arch/arm/boot/dts/tegra-harmony.dts
> 
> > +		tps6586x@34 {
> > +			compatible = "ti,tps6586x";
> > +			reg = <0x34>;
> > +			interrupts = <0 88 0x4>;
> 
> I believe that should be interrupt 86 not 88.

Yes, you're absolutely correct.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

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

* [PATCH v2 08/10] ARM: tegra: harmony: Initialize regulators from DT
@ 2012-06-22  6:06           ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-22  6:06 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jun 21, 2012 at 02:17:32PM -0600, Stephen Warren wrote:
> On 06/11/2012 09:05 AM, Thierry Reding wrote:
> > Device tree support for the TPS6586x PMU used on Harmony has recently
> > been added. This commit adds the required device tree nodes to probe the
> > PMU from the device tree.
> 
> > diff --git a/arch/arm/boot/dts/tegra-harmony.dts b/arch/arm/boot/dts/tegra-harmony.dts
> 
> > +		tps6586x at 34 {
> > +			compatible = "ti,tps6586x";
> > +			reg = <0x34>;
> > +			interrupts = <0 88 0x4>;
> 
> I believe that should be interrupt 86 not 88.

Yes, you're absolutely correct.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120622/4b5c3dc3/attachment.sig>

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-21  6:47                                                                   ` Thierry Reding
  (?)
@ 2012-06-22 10:18                                                                       ` Bjorn Helgaas
  -1 siblings, 0 replies; 249+ messages in thread
From: Bjorn Helgaas @ 2012-06-22 10:18 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Mitch Bradley, Stephen Warren, Russell King,
	linux-pci-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Jesse Barnes, Colin Cross, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Arnd Bergmann

On Thu, Jun 21, 2012 at 12:47 AM, Thierry Reding
<thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org> wrote:
> On Tue, Jun 19, 2012 at 11:31:39AM -1000, Mitch Bradley wrote:

>> Version A - 3 address cells:  In this version, the intermediate
>> address space has 3 cells:  port#, address type, offset.  Address
>> type is
>>   0 : root port
>>   1 : config space
>>   2 : extended config space
>>   3 : I/O
>>   4 : non-prefetchable memory
>>   5 : prefetchable memory.
>>
>> The third cell "offset" is necessary so that the size field has a
>> number space that can include it.
>>
>>       pcie-controller {
>>               compatible = "nvidia,tegra20-pcie";
>>               reg = <0x80003000 0x00000800   /* PADS registers */
>>                      0x80003800 0x00000200>; /* extended configuration space */
>>               interrupts = <0 98 0x04   /* controller interrupt */
>>                             0 99 0x04>; /* MSI interrupt */
>>               status = "disabled";
>>
>>               ranges = <0 0 0  0x80000000 0x00001000   /* Root port 0 */
>>                         0 1 0  0x80004000 0x00080000   /* Port 0 config space */
>>                         0 2 0  0x80104000 0x00080000   /* Port 0 ext config space *
>>                         0 3 0  0x80400000 0x00008000   /* Port 0 downstream I/O */
>>                         0 4 0  0x90000000 0x08000000   /* Port 0 non-prefetchable memory */
>>                         0 5 0  0xa0000000 0x08000000   /* Port 0 prefetchable memory */
>>
>>                         1 0 0  0x80001000 0x00001000   /* Root port 1 */
>>                         1 1 0  0x80004000 0x00080000   /* Port 1 config space */
>>                         1 2 0  0x80184000 0x00080000   /* Port 1 ext config space */
>>                         1 3 0  0x80408000 0x00010000   /* Port 1 downstream I/O */
>>                         1 4 0  0x98000000 0x08000000   /* Port 1 non-prefetchable memory */
>>                         1 5 0  0xa0000000 0x08000000>; /* Port 1 prefetchable memory */
>>
>>               #address-cells = <3>;
>>               #size-cells = <1>;
>>
>>               pci@0 {
>>                       reg = <0 0 0 0x1000>;
>>                       status = "disabled";
>>
>>                       #address-cells = <3>;
>>                       #size-cells = <2>;
>>
>>                       ranges = <0x80000000 0 0  0 1 0  0 0x00080000   /* config */
>>                                 0x90000000 0 0  0 2 0  0 0x00080000   /* extended config */
>>                                 0x81000000 0 0  0 3 0  0 0x00008000   /* I/O */
>>                                 0x82000000 0 0  0 4 0  0 0x08000000   /* non-prefetchable memory */
>>                                 0xc2000000 0 0  0 5 0  0 0x08000000>; /* prefetchable memory */
>>
>>                       nvidia,ctrl-offset = <0x110>;
>>                       nvidia,num-lanes = <2>;
>>               };
>>
>>
>>               pci@1 {
>>                       reg = <1 0 0 0x1000>;
>>                       status = "disabled";
>>
>>                       #address-cells = <3>;
>>                       #size-cells = <2>;
>>
>>                       ranges = <0x80000000 0 0  1 1 0  0 0x00080000   /* config */
>>                                 0x90000000 0 0  1 2 0  0 0x00080000   /* extended config */
>>                                 0x81000000 0 0  1 3 0  0 0x00008000   /* I/O */
>>                                 0x82000000 0 0  1 4 0  0 0x08000000   /* non-prefetchable memory */
>>                                 0xc2000000 0 0  1 5 0  0 0x08000000>; /* prefetchable memory */
>>
>>                       nvidia,ctrl-offset = <0x118>;
>>                       nvidia,num-lanes = <2>;
>>               };

I'm not familiar with device tree, so pardon me if these are stupid
questions.  These seem to be describing PCI host bridges.  I assume
some of these ranges describe MMIO, prefetchable MMIO, and I/O port
apertures that the bridge forwards to the PCI bus.

Is there provision for any address offset applied by the bridge when
it forwards downstream?  (Maybe these bridges don't apply any offset?)
 "0xa0000000 0x08000000" appears for both ports 0 and 1 prefetchable
memory; I don't know if that's an error, an indication that each
bridge applies a different offset, or that both bridges forward the
same aperture (I hope not the latter, because Linux can't really deal
with that).

Is the bus number aperture included somewhere?  How do we know what
bus numbers are available for allocation under each bridge?

I see mention of config space.  Is some of that referring to the ECAM
as in 7.2.2 of the PCIe spec v3.0 (what we refer to as MMCONFIG on
x86)?

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-22 10:18                                                                       ` Bjorn Helgaas
  0 siblings, 0 replies; 249+ messages in thread
From: Bjorn Helgaas @ 2012-06-22 10:18 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Mitch Bradley, Stephen Warren, Russell King, linux-pci,
	devicetree-discuss, Rob Herring, Jesse Barnes, Colin Cross,
	linux-tegra, linux-arm-kernel, Arnd Bergmann

On Thu, Jun 21, 2012 at 12:47 AM, Thierry Reding
<thierry.reding@avionic-design.de> wrote:
> On Tue, Jun 19, 2012 at 11:31:39AM -1000, Mitch Bradley wrote:

>> Version A - 3 address cells:  In this version, the intermediate
>> address space has 3 cells:  port#, address type, offset.  Address
>> type is
>>   0 : root port
>>   1 : config space
>>   2 : extended config space
>>   3 : I/O
>>   4 : non-prefetchable memory
>>   5 : prefetchable memory.
>>
>> The third cell "offset" is necessary so that the size field has a
>> number space that can include it.
>>
>>       pcie-controller {
>>               compatible = "nvidia,tegra20-pcie";
>>               reg = <0x80003000 0x00000800   /* PADS registers */
>>                      0x80003800 0x00000200>; /* extended configuration space */
>>               interrupts = <0 98 0x04   /* controller interrupt */
>>                             0 99 0x04>; /* MSI interrupt */
>>               status = "disabled";
>>
>>               ranges = <0 0 0  0x80000000 0x00001000   /* Root port 0 */
>>                         0 1 0  0x80004000 0x00080000   /* Port 0 config space */
>>                         0 2 0  0x80104000 0x00080000   /* Port 0 ext config space *
>>                         0 3 0  0x80400000 0x00008000   /* Port 0 downstream I/O */
>>                         0 4 0  0x90000000 0x08000000   /* Port 0 non-prefetchable memory */
>>                         0 5 0  0xa0000000 0x08000000   /* Port 0 prefetchable memory */
>>
>>                         1 0 0  0x80001000 0x00001000   /* Root port 1 */
>>                         1 1 0  0x80004000 0x00080000   /* Port 1 config space */
>>                         1 2 0  0x80184000 0x00080000   /* Port 1 ext config space */
>>                         1 3 0  0x80408000 0x00010000   /* Port 1 downstream I/O */
>>                         1 4 0  0x98000000 0x08000000   /* Port 1 non-prefetchable memory */
>>                         1 5 0  0xa0000000 0x08000000>; /* Port 1 prefetchable memory */
>>
>>               #address-cells = <3>;
>>               #size-cells = <1>;
>>
>>               pci@0 {
>>                       reg = <0 0 0 0x1000>;
>>                       status = "disabled";
>>
>>                       #address-cells = <3>;
>>                       #size-cells = <2>;
>>
>>                       ranges = <0x80000000 0 0  0 1 0  0 0x00080000   /* config */
>>                                 0x90000000 0 0  0 2 0  0 0x00080000   /* extended config */
>>                                 0x81000000 0 0  0 3 0  0 0x00008000   /* I/O */
>>                                 0x82000000 0 0  0 4 0  0 0x08000000   /* non-prefetchable memory */
>>                                 0xc2000000 0 0  0 5 0  0 0x08000000>; /* prefetchable memory */
>>
>>                       nvidia,ctrl-offset = <0x110>;
>>                       nvidia,num-lanes = <2>;
>>               };
>>
>>
>>               pci@1 {
>>                       reg = <1 0 0 0x1000>;
>>                       status = "disabled";
>>
>>                       #address-cells = <3>;
>>                       #size-cells = <2>;
>>
>>                       ranges = <0x80000000 0 0  1 1 0  0 0x00080000   /* config */
>>                                 0x90000000 0 0  1 2 0  0 0x00080000   /* extended config */
>>                                 0x81000000 0 0  1 3 0  0 0x00008000   /* I/O */
>>                                 0x82000000 0 0  1 4 0  0 0x08000000   /* non-prefetchable memory */
>>                                 0xc2000000 0 0  1 5 0  0 0x08000000>; /* prefetchable memory */
>>
>>                       nvidia,ctrl-offset = <0x118>;
>>                       nvidia,num-lanes = <2>;
>>               };

I'm not familiar with device tree, so pardon me if these are stupid
questions.  These seem to be describing PCI host bridges.  I assume
some of these ranges describe MMIO, prefetchable MMIO, and I/O port
apertures that the bridge forwards to the PCI bus.

Is there provision for any address offset applied by the bridge when
it forwards downstream?  (Maybe these bridges don't apply any offset?)
 "0xa0000000 0x08000000" appears for both ports 0 and 1 prefetchable
memory; I don't know if that's an error, an indication that each
bridge applies a different offset, or that both bridges forward the
same aperture (I hope not the latter, because Linux can't really deal
with that).

Is the bus number aperture included somewhere?  How do we know what
bus numbers are available for allocation under each bridge?

I see mention of config space.  Is some of that referring to the ECAM
as in 7.2.2 of the PCIe spec v3.0 (what we refer to as MMCONFIG on
x86)?

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-22 10:18                                                                       ` Bjorn Helgaas
  0 siblings, 0 replies; 249+ messages in thread
From: Bjorn Helgaas @ 2012-06-22 10:18 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jun 21, 2012 at 12:47 AM, Thierry Reding
<thierry.reding@avionic-design.de> wrote:
> On Tue, Jun 19, 2012 at 11:31:39AM -1000, Mitch Bradley wrote:

>> Version A - 3 address cells: ?In this version, the intermediate
>> address space has 3 cells: ?port#, address type, offset. ?Address
>> type is
>> ? 0 : root port
>> ? 1 : config space
>> ? 2 : extended config space
>> ? 3 : I/O
>> ? 4 : non-prefetchable memory
>> ? 5 : prefetchable memory.
>>
>> The third cell "offset" is necessary so that the size field has a
>> number space that can include it.
>>
>> ? ? ? pcie-controller {
>> ? ? ? ? ? ? ? compatible = "nvidia,tegra20-pcie";
>> ? ? ? ? ? ? ? reg = <0x80003000 0x00000800 ? /* PADS registers */
>> ? ? ? ? ? ? ? ? ? ? ?0x80003800 0x00000200>; /* extended configuration space */
>> ? ? ? ? ? ? ? interrupts = <0 98 0x04 ? /* controller interrupt */
>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0 99 0x04>; /* MSI interrupt */
>> ? ? ? ? ? ? ? status = "disabled";
>>
>> ? ? ? ? ? ? ? ranges = <0 0 0 ?0x80000000 0x00001000 ? /* Root port 0 */
>> ? ? ? ? ? ? ? ? ? ? ? ? 0 1 0 ?0x80004000 0x00080000 ? /* Port 0 config space */
>> ? ? ? ? ? ? ? ? ? ? ? ? 0 2 0 ?0x80104000 0x00080000 ? /* Port 0 ext config space *
>> ? ? ? ? ? ? ? ? ? ? ? ? 0 3 0 ?0x80400000 0x00008000 ? /* Port 0 downstream I/O */
>> ? ? ? ? ? ? ? ? ? ? ? ? 0 4 0 ?0x90000000 0x08000000 ? /* Port 0 non-prefetchable memory */
>> ? ? ? ? ? ? ? ? ? ? ? ? 0 5 0 ?0xa0000000 0x08000000 ? /* Port 0 prefetchable memory */
>>
>> ? ? ? ? ? ? ? ? ? ? ? ? 1 0 0 ?0x80001000 0x00001000 ? /* Root port 1 */
>> ? ? ? ? ? ? ? ? ? ? ? ? 1 1 0 ?0x80004000 0x00080000 ? /* Port 1 config space */
>> ? ? ? ? ? ? ? ? ? ? ? ? 1 2 0 ?0x80184000 0x00080000 ? /* Port 1 ext config space */
>> ? ? ? ? ? ? ? ? ? ? ? ? 1 3 0 ?0x80408000 0x00010000 ? /* Port 1 downstream I/O */
>> ? ? ? ? ? ? ? ? ? ? ? ? 1 4 0 ?0x98000000 0x08000000 ? /* Port 1 non-prefetchable memory */
>> ? ? ? ? ? ? ? ? ? ? ? ? 1 5 0 ?0xa0000000 0x08000000>; /* Port 1 prefetchable memory */
>>
>> ? ? ? ? ? ? ? #address-cells = <3>;
>> ? ? ? ? ? ? ? #size-cells = <1>;
>>
>> ? ? ? ? ? ? ? pci at 0 {
>> ? ? ? ? ? ? ? ? ? ? ? reg = <0 0 0 0x1000>;
>> ? ? ? ? ? ? ? ? ? ? ? status = "disabled";
>>
>> ? ? ? ? ? ? ? ? ? ? ? #address-cells = <3>;
>> ? ? ? ? ? ? ? ? ? ? ? #size-cells = <2>;
>>
>> ? ? ? ? ? ? ? ? ? ? ? ranges = <0x80000000 0 0 ?0 1 0 ?0 0x00080000 ? /* config */
>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0x90000000 0 0 ?0 2 0 ?0 0x00080000 ? /* extended config */
>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0x81000000 0 0 ?0 3 0 ?0 0x00008000 ? /* I/O */
>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0x82000000 0 0 ?0 4 0 ?0 0x08000000 ? /* non-prefetchable memory */
>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0xc2000000 0 0 ?0 5 0 ?0 0x08000000>; /* prefetchable memory */
>>
>> ? ? ? ? ? ? ? ? ? ? ? nvidia,ctrl-offset = <0x110>;
>> ? ? ? ? ? ? ? ? ? ? ? nvidia,num-lanes = <2>;
>> ? ? ? ? ? ? ? };
>>
>>
>> ? ? ? ? ? ? ? pci at 1 {
>> ? ? ? ? ? ? ? ? ? ? ? reg = <1 0 0 0x1000>;
>> ? ? ? ? ? ? ? ? ? ? ? status = "disabled";
>>
>> ? ? ? ? ? ? ? ? ? ? ? #address-cells = <3>;
>> ? ? ? ? ? ? ? ? ? ? ? #size-cells = <2>;
>>
>> ? ? ? ? ? ? ? ? ? ? ? ranges = <0x80000000 0 0 ?1 1 0 ?0 0x00080000 ? /* config */
>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0x90000000 0 0 ?1 2 0 ?0 0x00080000 ? /* extended config */
>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0x81000000 0 0 ?1 3 0 ?0 0x00008000 ? /* I/O */
>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0x82000000 0 0 ?1 4 0 ?0 0x08000000 ? /* non-prefetchable memory */
>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0xc2000000 0 0 ?1 5 0 ?0 0x08000000>; /* prefetchable memory */
>>
>> ? ? ? ? ? ? ? ? ? ? ? nvidia,ctrl-offset = <0x118>;
>> ? ? ? ? ? ? ? ? ? ? ? nvidia,num-lanes = <2>;
>> ? ? ? ? ? ? ? };

I'm not familiar with device tree, so pardon me if these are stupid
questions.  These seem to be describing PCI host bridges.  I assume
some of these ranges describe MMIO, prefetchable MMIO, and I/O port
apertures that the bridge forwards to the PCI bus.

Is there provision for any address offset applied by the bridge when
it forwards downstream?  (Maybe these bridges don't apply any offset?)
 "0xa0000000 0x08000000" appears for both ports 0 and 1 prefetchable
memory; I don't know if that's an error, an indication that each
bridge applies a different offset, or that both bridges forward the
same aperture (I hope not the latter, because Linux can't really deal
with that).

Is the bus number aperture included somewhere?  How do we know what
bus numbers are available for allocation under each bridge?

I see mention of config space.  Is some of that referring to the ECAM
as in 7.2.2 of the PCIe spec v3.0 (what we refer to as MMCONFIG on
x86)?

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-22 10:18                                                                       ` Bjorn Helgaas
  (?)
@ 2012-06-22 11:00                                                                           ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-22 11:00 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Mitch Bradley, Stephen Warren, Russell King,
	linux-pci-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Jesse Barnes, Colin Cross, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Arnd Bergmann

[-- Attachment #1: Type: text/plain, Size: 8341 bytes --]

On Fri, Jun 22, 2012 at 04:18:05AM -0600, Bjorn Helgaas wrote:
> On Thu, Jun 21, 2012 at 12:47 AM, Thierry Reding
> <thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org> wrote:
> > On Tue, Jun 19, 2012 at 11:31:39AM -1000, Mitch Bradley wrote:
> 
> >> Version A - 3 address cells:  In this version, the intermediate
> >> address space has 3 cells:  port#, address type, offset.  Address
> >> type is
> >>   0 : root port
> >>   1 : config space
> >>   2 : extended config space
> >>   3 : I/O
> >>   4 : non-prefetchable memory
> >>   5 : prefetchable memory.
> >>
> >> The third cell "offset" is necessary so that the size field has a
> >> number space that can include it.
> >>
> >>       pcie-controller {
> >>               compatible = "nvidia,tegra20-pcie";
> >>               reg = <0x80003000 0x00000800   /* PADS registers */
> >>                      0x80003800 0x00000200>; /* extended configuration space */
> >>               interrupts = <0 98 0x04   /* controller interrupt */
> >>                             0 99 0x04>; /* MSI interrupt */
> >>               status = "disabled";
> >>
> >>               ranges = <0 0 0  0x80000000 0x00001000   /* Root port 0 */
> >>                         0 1 0  0x80004000 0x00080000   /* Port 0 config space */
> >>                         0 2 0  0x80104000 0x00080000   /* Port 0 ext config space *
> >>                         0 3 0  0x80400000 0x00008000   /* Port 0 downstream I/O */
> >>                         0 4 0  0x90000000 0x08000000   /* Port 0 non-prefetchable memory */
> >>                         0 5 0  0xa0000000 0x08000000   /* Port 0 prefetchable memory */
> >>
> >>                         1 0 0  0x80001000 0x00001000   /* Root port 1 */
> >>                         1 1 0  0x80004000 0x00080000   /* Port 1 config space */
> >>                         1 2 0  0x80184000 0x00080000   /* Port 1 ext config space */
> >>                         1 3 0  0x80408000 0x00010000   /* Port 1 downstream I/O */
> >>                         1 4 0  0x98000000 0x08000000   /* Port 1 non-prefetchable memory */
> >>                         1 5 0  0xa0000000 0x08000000>; /* Port 1 prefetchable memory */
> >>
> >>               #address-cells = <3>;
> >>               #size-cells = <1>;
> >>
> >>               pci@0 {
> >>                       reg = <0 0 0 0x1000>;
> >>                       status = "disabled";
> >>
> >>                       #address-cells = <3>;
> >>                       #size-cells = <2>;
> >>
> >>                       ranges = <0x80000000 0 0  0 1 0  0 0x00080000   /* config */
> >>                                 0x90000000 0 0  0 2 0  0 0x00080000   /* extended config */
> >>                                 0x81000000 0 0  0 3 0  0 0x00008000   /* I/O */
> >>                                 0x82000000 0 0  0 4 0  0 0x08000000   /* non-prefetchable memory */
> >>                                 0xc2000000 0 0  0 5 0  0 0x08000000>; /* prefetchable memory */
> >>
> >>                       nvidia,ctrl-offset = <0x110>;
> >>                       nvidia,num-lanes = <2>;
> >>               };
> >>
> >>
> >>               pci@1 {
> >>                       reg = <1 0 0 0x1000>;
> >>                       status = "disabled";
> >>
> >>                       #address-cells = <3>;
> >>                       #size-cells = <2>;
> >>
> >>                       ranges = <0x80000000 0 0  1 1 0  0 0x00080000   /* config */
> >>                                 0x90000000 0 0  1 2 0  0 0x00080000   /* extended config */
> >>                                 0x81000000 0 0  1 3 0  0 0x00008000   /* I/O */
> >>                                 0x82000000 0 0  1 4 0  0 0x08000000   /* non-prefetchable memory */
> >>                                 0xc2000000 0 0  1 5 0  0 0x08000000>; /* prefetchable memory */
> >>
> >>                       nvidia,ctrl-offset = <0x118>;
> >>                       nvidia,num-lanes = <2>;
> >>               };
> 
> I'm not familiar with device tree, so pardon me if these are stupid
> questions.  These seem to be describing PCI host bridges.

Yes, correct.

> I assume some of these ranges describe MMIO, prefetchable MMIO, and
> I/O port apertures that the bridge forwards to the PCI bus.

Yes.

> Is there provision for any address offset applied by the bridge when
> it forwards downstream?  (Maybe these bridges don't apply any offset?)
>  "0xa0000000 0x08000000" appears for both ports 0 and 1 prefetchable
> memory; I don't know if that's an error, an indication that each
> bridge applies a different offset, or that both bridges forward the
> same aperture (I hope not the latter, because Linux can't really deal
> with that).

That seems to be a typo. It should have been 0xa8000000 in the second
case. The PCIe controller has registers that are programmed with the
aperture for the configuration and extended configuration spaces, as
well as the downstream I/O, prefetchable and non-prefetchable memory
regions.

The configuration spaces aren't actually forwarded by the bridges, but
are handled only by the controller. The other apertures are programmed
into the bridges using standard PCI registers.

> Is the bus number aperture included somewhere?  How do we know what
> bus numbers are available for allocation under each bridge?

Not yet. I don't think DT imposes a bus number allocation on PCI
bridges. However the matching of DT nodes to PCI bridges is done based
on the bus number. For that you provide a bus-ranges property which
defines the bus aperture of the given PCI bridge. The DT matching code
compares the first cell of this property with the primary bus number of
the bridge.

This is in fact somewhat counter-productive because it requires you to
hard-code the PCI hierarchy within the DT and you loose a lot of the
probing functionality. This is not much of an issue for typical PCI
endpoints (like network cards) but becomes a problem if you have a PCI
endpoint that implements an I2C bus and you want to match I2C slaves on
that bus to device nodes so that the kernel can parse and instantiate
them properly. I guess in the latter cases hard-coding the PCI tree in
DT is not actually a drawback, though.

> I see mention of config space.  Is some of that referring to the ECAM
> as in 7.2.2 of the PCIe spec v3.0 (what we refer to as MMCONFIG on
> x86)?

I only have access to the PCIe 2.0 specification, but it seems to
contain the same 7.2.2 section. In fact it looks as though this
particular controller indeed implements something similar to ECAM. The
address mapping is a little different, though:

	A[(16 + n - 1):16]: bus number
	A[15:11]: device number
	A[10:8]: function number
	A[7:2]: register number
	A[1:0]: unused

That information comes directly from the driver and I have no access to
the corresponding documentation. It seems like the extended
configuration space is accessed using the same mapping but starting at a
different base address.

But now that you mention it, maybe the driver code is buggy here, and
the controller indeed implements ECAM. Furthermore it also seems like
the current code doesn't work for the extended configuration space
because while the correct offset into the extended configuration space
is chosen, the access to registers is done using the same mapping as
above, so instead of the 12 (10) bits required for the register number
only 8 (6) are in fact used.

I wonder whether anyone's actually tested this.

Stephen: can you try to find out whether the Tegra PCIe controller
indeed implements ECAM, or if this scheme is actually just a proprietary
variant?

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-22 11:00                                                                           ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-22 11:00 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Mitch Bradley, Stephen Warren, Russell King, linux-pci,
	devicetree-discuss, Rob Herring, Jesse Barnes, Colin Cross,
	linux-tegra, linux-arm-kernel, Arnd Bergmann

[-- Attachment #1: Type: text/plain, Size: 8309 bytes --]

On Fri, Jun 22, 2012 at 04:18:05AM -0600, Bjorn Helgaas wrote:
> On Thu, Jun 21, 2012 at 12:47 AM, Thierry Reding
> <thierry.reding@avionic-design.de> wrote:
> > On Tue, Jun 19, 2012 at 11:31:39AM -1000, Mitch Bradley wrote:
> 
> >> Version A - 3 address cells:  In this version, the intermediate
> >> address space has 3 cells:  port#, address type, offset.  Address
> >> type is
> >>   0 : root port
> >>   1 : config space
> >>   2 : extended config space
> >>   3 : I/O
> >>   4 : non-prefetchable memory
> >>   5 : prefetchable memory.
> >>
> >> The third cell "offset" is necessary so that the size field has a
> >> number space that can include it.
> >>
> >>       pcie-controller {
> >>               compatible = "nvidia,tegra20-pcie";
> >>               reg = <0x80003000 0x00000800   /* PADS registers */
> >>                      0x80003800 0x00000200>; /* extended configuration space */
> >>               interrupts = <0 98 0x04   /* controller interrupt */
> >>                             0 99 0x04>; /* MSI interrupt */
> >>               status = "disabled";
> >>
> >>               ranges = <0 0 0  0x80000000 0x00001000   /* Root port 0 */
> >>                         0 1 0  0x80004000 0x00080000   /* Port 0 config space */
> >>                         0 2 0  0x80104000 0x00080000   /* Port 0 ext config space *
> >>                         0 3 0  0x80400000 0x00008000   /* Port 0 downstream I/O */
> >>                         0 4 0  0x90000000 0x08000000   /* Port 0 non-prefetchable memory */
> >>                         0 5 0  0xa0000000 0x08000000   /* Port 0 prefetchable memory */
> >>
> >>                         1 0 0  0x80001000 0x00001000   /* Root port 1 */
> >>                         1 1 0  0x80004000 0x00080000   /* Port 1 config space */
> >>                         1 2 0  0x80184000 0x00080000   /* Port 1 ext config space */
> >>                         1 3 0  0x80408000 0x00010000   /* Port 1 downstream I/O */
> >>                         1 4 0  0x98000000 0x08000000   /* Port 1 non-prefetchable memory */
> >>                         1 5 0  0xa0000000 0x08000000>; /* Port 1 prefetchable memory */
> >>
> >>               #address-cells = <3>;
> >>               #size-cells = <1>;
> >>
> >>               pci@0 {
> >>                       reg = <0 0 0 0x1000>;
> >>                       status = "disabled";
> >>
> >>                       #address-cells = <3>;
> >>                       #size-cells = <2>;
> >>
> >>                       ranges = <0x80000000 0 0  0 1 0  0 0x00080000   /* config */
> >>                                 0x90000000 0 0  0 2 0  0 0x00080000   /* extended config */
> >>                                 0x81000000 0 0  0 3 0  0 0x00008000   /* I/O */
> >>                                 0x82000000 0 0  0 4 0  0 0x08000000   /* non-prefetchable memory */
> >>                                 0xc2000000 0 0  0 5 0  0 0x08000000>; /* prefetchable memory */
> >>
> >>                       nvidia,ctrl-offset = <0x110>;
> >>                       nvidia,num-lanes = <2>;
> >>               };
> >>
> >>
> >>               pci@1 {
> >>                       reg = <1 0 0 0x1000>;
> >>                       status = "disabled";
> >>
> >>                       #address-cells = <3>;
> >>                       #size-cells = <2>;
> >>
> >>                       ranges = <0x80000000 0 0  1 1 0  0 0x00080000   /* config */
> >>                                 0x90000000 0 0  1 2 0  0 0x00080000   /* extended config */
> >>                                 0x81000000 0 0  1 3 0  0 0x00008000   /* I/O */
> >>                                 0x82000000 0 0  1 4 0  0 0x08000000   /* non-prefetchable memory */
> >>                                 0xc2000000 0 0  1 5 0  0 0x08000000>; /* prefetchable memory */
> >>
> >>                       nvidia,ctrl-offset = <0x118>;
> >>                       nvidia,num-lanes = <2>;
> >>               };
> 
> I'm not familiar with device tree, so pardon me if these are stupid
> questions.  These seem to be describing PCI host bridges.

Yes, correct.

> I assume some of these ranges describe MMIO, prefetchable MMIO, and
> I/O port apertures that the bridge forwards to the PCI bus.

Yes.

> Is there provision for any address offset applied by the bridge when
> it forwards downstream?  (Maybe these bridges don't apply any offset?)
>  "0xa0000000 0x08000000" appears for both ports 0 and 1 prefetchable
> memory; I don't know if that's an error, an indication that each
> bridge applies a different offset, or that both bridges forward the
> same aperture (I hope not the latter, because Linux can't really deal
> with that).

That seems to be a typo. It should have been 0xa8000000 in the second
case. The PCIe controller has registers that are programmed with the
aperture for the configuration and extended configuration spaces, as
well as the downstream I/O, prefetchable and non-prefetchable memory
regions.

The configuration spaces aren't actually forwarded by the bridges, but
are handled only by the controller. The other apertures are programmed
into the bridges using standard PCI registers.

> Is the bus number aperture included somewhere?  How do we know what
> bus numbers are available for allocation under each bridge?

Not yet. I don't think DT imposes a bus number allocation on PCI
bridges. However the matching of DT nodes to PCI bridges is done based
on the bus number. For that you provide a bus-ranges property which
defines the bus aperture of the given PCI bridge. The DT matching code
compares the first cell of this property with the primary bus number of
the bridge.

This is in fact somewhat counter-productive because it requires you to
hard-code the PCI hierarchy within the DT and you loose a lot of the
probing functionality. This is not much of an issue for typical PCI
endpoints (like network cards) but becomes a problem if you have a PCI
endpoint that implements an I2C bus and you want to match I2C slaves on
that bus to device nodes so that the kernel can parse and instantiate
them properly. I guess in the latter cases hard-coding the PCI tree in
DT is not actually a drawback, though.

> I see mention of config space.  Is some of that referring to the ECAM
> as in 7.2.2 of the PCIe spec v3.0 (what we refer to as MMCONFIG on
> x86)?

I only have access to the PCIe 2.0 specification, but it seems to
contain the same 7.2.2 section. In fact it looks as though this
particular controller indeed implements something similar to ECAM. The
address mapping is a little different, though:

	A[(16 + n - 1):16]: bus number
	A[15:11]: device number
	A[10:8]: function number
	A[7:2]: register number
	A[1:0]: unused

That information comes directly from the driver and I have no access to
the corresponding documentation. It seems like the extended
configuration space is accessed using the same mapping but starting at a
different base address.

But now that you mention it, maybe the driver code is buggy here, and
the controller indeed implements ECAM. Furthermore it also seems like
the current code doesn't work for the extended configuration space
because while the correct offset into the extended configuration space
is chosen, the access to registers is done using the same mapping as
above, so instead of the 12 (10) bits required for the register number
only 8 (6) are in fact used.

I wonder whether anyone's actually tested this.

Stephen: can you try to find out whether the Tegra PCIe controller
indeed implements ECAM, or if this scheme is actually just a proprietary
variant?

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-22 11:00                                                                           ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-22 11:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jun 22, 2012 at 04:18:05AM -0600, Bjorn Helgaas wrote:
> On Thu, Jun 21, 2012 at 12:47 AM, Thierry Reding
> <thierry.reding@avionic-design.de> wrote:
> > On Tue, Jun 19, 2012 at 11:31:39AM -1000, Mitch Bradley wrote:
> 
> >> Version A - 3 address cells: ?In this version, the intermediate
> >> address space has 3 cells: ?port#, address type, offset. ?Address
> >> type is
> >> ? 0 : root port
> >> ? 1 : config space
> >> ? 2 : extended config space
> >> ? 3 : I/O
> >> ? 4 : non-prefetchable memory
> >> ? 5 : prefetchable memory.
> >>
> >> The third cell "offset" is necessary so that the size field has a
> >> number space that can include it.
> >>
> >> ? ? ? pcie-controller {
> >> ? ? ? ? ? ? ? compatible = "nvidia,tegra20-pcie";
> >> ? ? ? ? ? ? ? reg = <0x80003000 0x00000800 ? /* PADS registers */
> >> ? ? ? ? ? ? ? ? ? ? ?0x80003800 0x00000200>; /* extended configuration space */
> >> ? ? ? ? ? ? ? interrupts = <0 98 0x04 ? /* controller interrupt */
> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0 99 0x04>; /* MSI interrupt */
> >> ? ? ? ? ? ? ? status = "disabled";
> >>
> >> ? ? ? ? ? ? ? ranges = <0 0 0 ?0x80000000 0x00001000 ? /* Root port 0 */
> >> ? ? ? ? ? ? ? ? ? ? ? ? 0 1 0 ?0x80004000 0x00080000 ? /* Port 0 config space */
> >> ? ? ? ? ? ? ? ? ? ? ? ? 0 2 0 ?0x80104000 0x00080000 ? /* Port 0 ext config space *
> >> ? ? ? ? ? ? ? ? ? ? ? ? 0 3 0 ?0x80400000 0x00008000 ? /* Port 0 downstream I/O */
> >> ? ? ? ? ? ? ? ? ? ? ? ? 0 4 0 ?0x90000000 0x08000000 ? /* Port 0 non-prefetchable memory */
> >> ? ? ? ? ? ? ? ? ? ? ? ? 0 5 0 ?0xa0000000 0x08000000 ? /* Port 0 prefetchable memory */
> >>
> >> ? ? ? ? ? ? ? ? ? ? ? ? 1 0 0 ?0x80001000 0x00001000 ? /* Root port 1 */
> >> ? ? ? ? ? ? ? ? ? ? ? ? 1 1 0 ?0x80004000 0x00080000 ? /* Port 1 config space */
> >> ? ? ? ? ? ? ? ? ? ? ? ? 1 2 0 ?0x80184000 0x00080000 ? /* Port 1 ext config space */
> >> ? ? ? ? ? ? ? ? ? ? ? ? 1 3 0 ?0x80408000 0x00010000 ? /* Port 1 downstream I/O */
> >> ? ? ? ? ? ? ? ? ? ? ? ? 1 4 0 ?0x98000000 0x08000000 ? /* Port 1 non-prefetchable memory */
> >> ? ? ? ? ? ? ? ? ? ? ? ? 1 5 0 ?0xa0000000 0x08000000>; /* Port 1 prefetchable memory */
> >>
> >> ? ? ? ? ? ? ? #address-cells = <3>;
> >> ? ? ? ? ? ? ? #size-cells = <1>;
> >>
> >> ? ? ? ? ? ? ? pci at 0 {
> >> ? ? ? ? ? ? ? ? ? ? ? reg = <0 0 0 0x1000>;
> >> ? ? ? ? ? ? ? ? ? ? ? status = "disabled";
> >>
> >> ? ? ? ? ? ? ? ? ? ? ? #address-cells = <3>;
> >> ? ? ? ? ? ? ? ? ? ? ? #size-cells = <2>;
> >>
> >> ? ? ? ? ? ? ? ? ? ? ? ranges = <0x80000000 0 0 ?0 1 0 ?0 0x00080000 ? /* config */
> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0x90000000 0 0 ?0 2 0 ?0 0x00080000 ? /* extended config */
> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0x81000000 0 0 ?0 3 0 ?0 0x00008000 ? /* I/O */
> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0x82000000 0 0 ?0 4 0 ?0 0x08000000 ? /* non-prefetchable memory */
> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0xc2000000 0 0 ?0 5 0 ?0 0x08000000>; /* prefetchable memory */
> >>
> >> ? ? ? ? ? ? ? ? ? ? ? nvidia,ctrl-offset = <0x110>;
> >> ? ? ? ? ? ? ? ? ? ? ? nvidia,num-lanes = <2>;
> >> ? ? ? ? ? ? ? };
> >>
> >>
> >> ? ? ? ? ? ? ? pci at 1 {
> >> ? ? ? ? ? ? ? ? ? ? ? reg = <1 0 0 0x1000>;
> >> ? ? ? ? ? ? ? ? ? ? ? status = "disabled";
> >>
> >> ? ? ? ? ? ? ? ? ? ? ? #address-cells = <3>;
> >> ? ? ? ? ? ? ? ? ? ? ? #size-cells = <2>;
> >>
> >> ? ? ? ? ? ? ? ? ? ? ? ranges = <0x80000000 0 0 ?1 1 0 ?0 0x00080000 ? /* config */
> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0x90000000 0 0 ?1 2 0 ?0 0x00080000 ? /* extended config */
> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0x81000000 0 0 ?1 3 0 ?0 0x00008000 ? /* I/O */
> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0x82000000 0 0 ?1 4 0 ?0 0x08000000 ? /* non-prefetchable memory */
> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0xc2000000 0 0 ?1 5 0 ?0 0x08000000>; /* prefetchable memory */
> >>
> >> ? ? ? ? ? ? ? ? ? ? ? nvidia,ctrl-offset = <0x118>;
> >> ? ? ? ? ? ? ? ? ? ? ? nvidia,num-lanes = <2>;
> >> ? ? ? ? ? ? ? };
> 
> I'm not familiar with device tree, so pardon me if these are stupid
> questions.  These seem to be describing PCI host bridges.

Yes, correct.

> I assume some of these ranges describe MMIO, prefetchable MMIO, and
> I/O port apertures that the bridge forwards to the PCI bus.

Yes.

> Is there provision for any address offset applied by the bridge when
> it forwards downstream?  (Maybe these bridges don't apply any offset?)
>  "0xa0000000 0x08000000" appears for both ports 0 and 1 prefetchable
> memory; I don't know if that's an error, an indication that each
> bridge applies a different offset, or that both bridges forward the
> same aperture (I hope not the latter, because Linux can't really deal
> with that).

That seems to be a typo. It should have been 0xa8000000 in the second
case. The PCIe controller has registers that are programmed with the
aperture for the configuration and extended configuration spaces, as
well as the downstream I/O, prefetchable and non-prefetchable memory
regions.

The configuration spaces aren't actually forwarded by the bridges, but
are handled only by the controller. The other apertures are programmed
into the bridges using standard PCI registers.

> Is the bus number aperture included somewhere?  How do we know what
> bus numbers are available for allocation under each bridge?

Not yet. I don't think DT imposes a bus number allocation on PCI
bridges. However the matching of DT nodes to PCI bridges is done based
on the bus number. For that you provide a bus-ranges property which
defines the bus aperture of the given PCI bridge. The DT matching code
compares the first cell of this property with the primary bus number of
the bridge.

This is in fact somewhat counter-productive because it requires you to
hard-code the PCI hierarchy within the DT and you loose a lot of the
probing functionality. This is not much of an issue for typical PCI
endpoints (like network cards) but becomes a problem if you have a PCI
endpoint that implements an I2C bus and you want to match I2C slaves on
that bus to device nodes so that the kernel can parse and instantiate
them properly. I guess in the latter cases hard-coding the PCI tree in
DT is not actually a drawback, though.

> I see mention of config space.  Is some of that referring to the ECAM
> as in 7.2.2 of the PCIe spec v3.0 (what we refer to as MMCONFIG on
> x86)?

I only have access to the PCIe 2.0 specification, but it seems to
contain the same 7.2.2 section. In fact it looks as though this
particular controller indeed implements something similar to ECAM. The
address mapping is a little different, though:

	A[(16 + n - 1):16]: bus number
	A[15:11]: device number
	A[10:8]: function number
	A[7:2]: register number
	A[1:0]: unused

That information comes directly from the driver and I have no access to
the corresponding documentation. It seems like the extended
configuration space is accessed using the same mapping but starting at a
different base address.

But now that you mention it, maybe the driver code is buggy here, and
the controller indeed implements ECAM. Furthermore it also seems like
the current code doesn't work for the extended configuration space
because while the correct offset into the extended configuration space
is chosen, the access to registers is done using the same mapping as
above, so instead of the 12 (10) bits required for the register number
only 8 (6) are in fact used.

I wonder whether anyone's actually tested this.

Stephen: can you try to find out whether the Tegra PCIe controller
indeed implements ECAM, or if this scheme is actually just a proprietary
variant?

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120622/e48a90b3/attachment.sig>

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-19 21:31                                                                 ` Mitch Bradley
@ 2012-06-22 11:04                                                                   ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-22 11:04 UTC (permalink / raw)
  To: Mitch Bradley
  Cc: Stephen Warren, Russell King, linux-pci, devicetree-discuss,
	Rob Herring, Jesse Barnes, Colin Cross, linux-tegra,
	linux-arm-kernel, Arnd Bergmann

[-- Attachment #1: Type: text/plain, Size: 8187 bytes --]

On Tue, Jun 19, 2012 at 11:31:39AM -1000, Mitch Bradley wrote:
> On 6/19/2012 3:30 AM, Thierry Reding wrote:
> >On Fri, Jun 15, 2012 at 08:12:36AM +0200, Thierry Reding wrote:
> >>On Thu, Jun 14, 2012 at 01:50:56PM -0600, Stephen Warren wrote:
> >>>On 06/14/2012 01:29 PM, Thierry Reding wrote:
> >>>>On Thu, Jun 14, 2012 at 12:30:50PM -0600, Stephen Warren wrote:
> >>>>>On 06/14/2012 03:19 AM, Thierry Reding wrote:
> >>>...
> >>>>>>#address-cells = <1>; #size-cells = <1>;
> >>>>>>
> >>>>>>pci@80000000 {
> >>>>>
> >>>>>I'm still not convinced that using the address of the port's
> >>>>>registers is the correct way to represent each port. The port
> >>>>>index seems much more useful.
> >>>>>
> >>>>>The main reason here is that there are a lot of registers that
> >>>>>contain fields for each port - far more than the combination of
> >>>>>this node's reg and ctrl-offset (which I assume is an address
> >>>>>offset for just one example of this issue) properties can
> >>>>>describe. The bit position and bit stride of these fields isn't
> >>>>>necessarily the same in each register. Do we want a property like
> >>>>>ctrl-offset for every single type of field in every single shared
> >>>>>register that describes the location of the relevant data, or
> >>>>>just a single "port ID" bit that can be applied to anything?
> >>>>>
> >>>>>(Perhaps this isn't so obvious looking at the TRM since it
> >>>>>doesn't document all registers, and I'm also looking at the
> >>>>>Tegra30 documentation too, which might be more exposed to this -
> >>>>>I haven't correlated all the documentation sources to be sure
> >>>>>though)
> >>>>
> >>>>I agree that maybe adding properties for each bit position or
> >>>>register offset may not work out too well. But I think it still
> >>>>makes sense to use the base address of the port's registers (see
> >>>>below). We could of course add some code to determine the index
> >>>>from the base address at initialization time and reuse the index
> >>>>where appropriate.
> >>>
> >>>To me, working back from address to ID then using the ID to calculate
> >>>some other addresses seems far more icky than just calculating all the
> >>>addresses based off of one ID. But, I suppose this doesn't make a huge
> >>>practical difference.
> >>
> >>This really depends on the device vs. no device decision below. If we can
> >>make it work without needing an extra device for it, then using the index
> >>is certainly better. However, if we instantiate devices from the DT, then
> >>we have the address anyway and adding the index as a property would be
> >>redundant and error prone (what happens if somebody sets the index of the
> >>port at address 0x80000000 to 2?).
> >
> >An additional problem with this is that we'd have to add the following
> >to the pcie-controller node:
> >
> >	#address-cells = <1>;
> >	#size-cells = <0>;
> >
> >This will conflict with the "ranges" property, because suddenly we can
> >no longer map the regions properly. Maybe Mitch can comment on whether
> >this is possible or not?
> >
> >To make it clearer what I'm talking about, here's the DT snippet again
> >(with the compatible property removed from the pci@ nodes because they
> >are no longer probed by a driver, the "simple-bus" removed from the
> >pcie-controller node's compatible property removed and its #address-
> >and #size-cells properties adjusted as described above).
> >
> >	pcie-controller {
> >		compatible = "nvidia,tegra20-pcie";
> >		reg = <0x80003000 0x00000800   /* PADS registers */
> >		       0x80003800 0x00000200   /* AFI registers */
> >		       0x80004000 0x00100000   /* configuration space */
> >		       0x80104000 0x00100000>; /* extended configuration space */
> >		interrupts = <0 98 0x04   /* controller interrupt */
> >			      0 99 0x04>; /* MSI interrupt */
> >		status = "disabled";
> >
> >		ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */
> >			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
> >			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
> >			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
> >
> >		#address-cells = <1>;
> >		#size-cells = <0>;
> >
> >		pci@0 {
> >			reg = <2>;
> >			status = "disabled";
> >
> >			#address-cells = <3>;
> >			#size-cells = <2>;
> >
> >			ranges = <0x81000000 0 0 0x80400000 0 0x00008000   /* I/O */
> >				  0x82000000 0 0 0x90000000 0 0x08000000   /* non-prefetchable memory */
> >				  0xc2000000 0 0 0xa0000000 0 0x08000000>; /* prefetchable memory */
> >
> >			nvidia,ctrl-offset = <0x110>;
> >			nvidia,num-lanes = <2>;
> >		};
> >
> >		pci@1 {
> >			reg = <1>;
> >			status = "disabled";
> >
> >			#address-cells = <3>;
> >			#size-cells = <2>;
> >
> >			ranges = <0x81000000 0 0 0x80408000 0 0x00008000   /* I/O */
> >				  0x82000000 0 0 0x98000000 0 0x08000000   /* non-prefetchable memory */
> >				  0xc2000000 0 0 0xa8000000 0 0x08000000>; /* prefetchable memory */
> >
> >			nvidia,ctrl-offset = <0x118>;
> >			nvidia,num-lanes = <2>;
> >		};
> >	};
> >
> >AIUI none of the ranges properties are valid anymore, because the bus
> >represented by pcie-controller no longer reflects the truth, namely that
> >it translates the CPU address space to the PCI address space.
> >
> 
> I think you can use a small-integer port number as an address by
> defining the intermediate address space properly, and using
> appropriate ranges above and below.  Here's a swag at how that would
> look.
> 
> I present three versions, using different choices for the
> intermediate address space encoding.  The intermediate address space
> may seem somewhat artificial, in that it decouples the "linear pass
> through of ranges" between the lower PCI address space and the upper
> CPU address space.  But in another sense, it accurately reflects
> that fact that the bus bridge "slices and dices" that linear address
> space into non-contiguous pieces.
> 
> Note that I'm also fixing a problem that I neglected to mention
> earlier - namely the fact that config space is part of the child PCI
> address space so it must be passed through.
> 
> Version A - 3 address cells:  In this version, the intermediate
> address space has 3 cells:  port#, address type, offset.  Address
> type is
>   0 : root port
>   1 : config space
>   2 : extended config space
>   3 : I/O
>   4 : non-prefetchable memory
>   5 : prefetchable memory.
> 
> The third cell "offset" is necessary so that the size field has a
> number space that can include it.
> 
> 	pcie-controller {
> 		compatible = "nvidia,tegra20-pcie";
> 		reg = <0x80003000 0x00000800   /* PADS registers */
> 		       0x80003800 0x00000200>; /* extended configuration space */
> 		interrupts = <0 98 0x04   /* controller interrupt */
> 			      0 99 0x04>; /* MSI interrupt */
> 		status = "disabled";
> 
> 		ranges = <0 0 0  0x80000000 0x00001000   /* Root port 0 */
> 			  0 1 0  0x80004000 0x00080000   /* Port 0 config space */
> 			  0 2 0  0x80104000 0x00080000   /* Port 0 ext config space *
> 			  0 3 0  0x80400000 0x00008000   /* Port 0 downstream I/O */
> 			  0 4 0  0x90000000 0x08000000   /* Port 0 non-prefetchable memory */
> 			  0 5 0  0xa0000000 0x08000000   /* Port 0 prefetchable memory */
> 
> 			  1 0 0  0x80001000 0x00001000   /* Root port 1 */
> 			  1 1 0  0x80004000 0x00080000   /* Port 1 config space */
> 			  1 2 0  0x80184000 0x00080000   /* Port 1 ext config space */
> 			  1 3 0  0x80408000 0x00010000   /* Port 1 downstream I/O */
> 			  1 4 0  0x98000000 0x08000000   /* Port 1 non-prefetchable memory */
> 			  1 5 0  0xa0000000 0x08000000>; /* Port 1 prefetchable memory */
> 
> 		#address-cells = <3>;
> 		#size-cells = <1>;
> 
> 		pci@0 {
> 			reg = <0 0 0 0x1000>;
[...]
> 		};
> 
> 		pci@1 {
> 			reg = <1 0 0 0x1000>;
[...]
> 		};

It seems like this isn't working properly. For some reason both the reg
property of pci@0 and pci@1 are translated to the same parent address
0x80000000. I'll have to investigate where exactly this goes wrong.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-22 11:04                                                                   ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-22 11:04 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jun 19, 2012 at 11:31:39AM -1000, Mitch Bradley wrote:
> On 6/19/2012 3:30 AM, Thierry Reding wrote:
> >On Fri, Jun 15, 2012 at 08:12:36AM +0200, Thierry Reding wrote:
> >>On Thu, Jun 14, 2012 at 01:50:56PM -0600, Stephen Warren wrote:
> >>>On 06/14/2012 01:29 PM, Thierry Reding wrote:
> >>>>On Thu, Jun 14, 2012 at 12:30:50PM -0600, Stephen Warren wrote:
> >>>>>On 06/14/2012 03:19 AM, Thierry Reding wrote:
> >>>...
> >>>>>>#address-cells = <1>; #size-cells = <1>;
> >>>>>>
> >>>>>>pci at 80000000 {
> >>>>>
> >>>>>I'm still not convinced that using the address of the port's
> >>>>>registers is the correct way to represent each port. The port
> >>>>>index seems much more useful.
> >>>>>
> >>>>>The main reason here is that there are a lot of registers that
> >>>>>contain fields for each port - far more than the combination of
> >>>>>this node's reg and ctrl-offset (which I assume is an address
> >>>>>offset for just one example of this issue) properties can
> >>>>>describe. The bit position and bit stride of these fields isn't
> >>>>>necessarily the same in each register. Do we want a property like
> >>>>>ctrl-offset for every single type of field in every single shared
> >>>>>register that describes the location of the relevant data, or
> >>>>>just a single "port ID" bit that can be applied to anything?
> >>>>>
> >>>>>(Perhaps this isn't so obvious looking at the TRM since it
> >>>>>doesn't document all registers, and I'm also looking at the
> >>>>>Tegra30 documentation too, which might be more exposed to this -
> >>>>>I haven't correlated all the documentation sources to be sure
> >>>>>though)
> >>>>
> >>>>I agree that maybe adding properties for each bit position or
> >>>>register offset may not work out too well. But I think it still
> >>>>makes sense to use the base address of the port's registers (see
> >>>>below). We could of course add some code to determine the index
> >>>>from the base address at initialization time and reuse the index
> >>>>where appropriate.
> >>>
> >>>To me, working back from address to ID then using the ID to calculate
> >>>some other addresses seems far more icky than just calculating all the
> >>>addresses based off of one ID. But, I suppose this doesn't make a huge
> >>>practical difference.
> >>
> >>This really depends on the device vs. no device decision below. If we can
> >>make it work without needing an extra device for it, then using the index
> >>is certainly better. However, if we instantiate devices from the DT, then
> >>we have the address anyway and adding the index as a property would be
> >>redundant and error prone (what happens if somebody sets the index of the
> >>port at address 0x80000000 to 2?).
> >
> >An additional problem with this is that we'd have to add the following
> >to the pcie-controller node:
> >
> >	#address-cells = <1>;
> >	#size-cells = <0>;
> >
> >This will conflict with the "ranges" property, because suddenly we can
> >no longer map the regions properly. Maybe Mitch can comment on whether
> >this is possible or not?
> >
> >To make it clearer what I'm talking about, here's the DT snippet again
> >(with the compatible property removed from the pci@ nodes because they
> >are no longer probed by a driver, the "simple-bus" removed from the
> >pcie-controller node's compatible property removed and its #address-
> >and #size-cells properties adjusted as described above).
> >
> >	pcie-controller {
> >		compatible = "nvidia,tegra20-pcie";
> >		reg = <0x80003000 0x00000800   /* PADS registers */
> >		       0x80003800 0x00000200   /* AFI registers */
> >		       0x80004000 0x00100000   /* configuration space */
> >		       0x80104000 0x00100000>; /* extended configuration space */
> >		interrupts = <0 98 0x04   /* controller interrupt */
> >			      0 99 0x04>; /* MSI interrupt */
> >		status = "disabled";
> >
> >		ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */
> >			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
> >			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
> >			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
> >
> >		#address-cells = <1>;
> >		#size-cells = <0>;
> >
> >		pci at 0 {
> >			reg = <2>;
> >			status = "disabled";
> >
> >			#address-cells = <3>;
> >			#size-cells = <2>;
> >
> >			ranges = <0x81000000 0 0 0x80400000 0 0x00008000   /* I/O */
> >				  0x82000000 0 0 0x90000000 0 0x08000000   /* non-prefetchable memory */
> >				  0xc2000000 0 0 0xa0000000 0 0x08000000>; /* prefetchable memory */
> >
> >			nvidia,ctrl-offset = <0x110>;
> >			nvidia,num-lanes = <2>;
> >		};
> >
> >		pci at 1 {
> >			reg = <1>;
> >			status = "disabled";
> >
> >			#address-cells = <3>;
> >			#size-cells = <2>;
> >
> >			ranges = <0x81000000 0 0 0x80408000 0 0x00008000   /* I/O */
> >				  0x82000000 0 0 0x98000000 0 0x08000000   /* non-prefetchable memory */
> >				  0xc2000000 0 0 0xa8000000 0 0x08000000>; /* prefetchable memory */
> >
> >			nvidia,ctrl-offset = <0x118>;
> >			nvidia,num-lanes = <2>;
> >		};
> >	};
> >
> >AIUI none of the ranges properties are valid anymore, because the bus
> >represented by pcie-controller no longer reflects the truth, namely that
> >it translates the CPU address space to the PCI address space.
> >
> 
> I think you can use a small-integer port number as an address by
> defining the intermediate address space properly, and using
> appropriate ranges above and below.  Here's a swag at how that would
> look.
> 
> I present three versions, using different choices for the
> intermediate address space encoding.  The intermediate address space
> may seem somewhat artificial, in that it decouples the "linear pass
> through of ranges" between the lower PCI address space and the upper
> CPU address space.  But in another sense, it accurately reflects
> that fact that the bus bridge "slices and dices" that linear address
> space into non-contiguous pieces.
> 
> Note that I'm also fixing a problem that I neglected to mention
> earlier - namely the fact that config space is part of the child PCI
> address space so it must be passed through.
> 
> Version A - 3 address cells:  In this version, the intermediate
> address space has 3 cells:  port#, address type, offset.  Address
> type is
>   0 : root port
>   1 : config space
>   2 : extended config space
>   3 : I/O
>   4 : non-prefetchable memory
>   5 : prefetchable memory.
> 
> The third cell "offset" is necessary so that the size field has a
> number space that can include it.
> 
> 	pcie-controller {
> 		compatible = "nvidia,tegra20-pcie";
> 		reg = <0x80003000 0x00000800   /* PADS registers */
> 		       0x80003800 0x00000200>; /* extended configuration space */
> 		interrupts = <0 98 0x04   /* controller interrupt */
> 			      0 99 0x04>; /* MSI interrupt */
> 		status = "disabled";
> 
> 		ranges = <0 0 0  0x80000000 0x00001000   /* Root port 0 */
> 			  0 1 0  0x80004000 0x00080000   /* Port 0 config space */
> 			  0 2 0  0x80104000 0x00080000   /* Port 0 ext config space *
> 			  0 3 0  0x80400000 0x00008000   /* Port 0 downstream I/O */
> 			  0 4 0  0x90000000 0x08000000   /* Port 0 non-prefetchable memory */
> 			  0 5 0  0xa0000000 0x08000000   /* Port 0 prefetchable memory */
> 
> 			  1 0 0  0x80001000 0x00001000   /* Root port 1 */
> 			  1 1 0  0x80004000 0x00080000   /* Port 1 config space */
> 			  1 2 0  0x80184000 0x00080000   /* Port 1 ext config space */
> 			  1 3 0  0x80408000 0x00010000   /* Port 1 downstream I/O */
> 			  1 4 0  0x98000000 0x08000000   /* Port 1 non-prefetchable memory */
> 			  1 5 0  0xa0000000 0x08000000>; /* Port 1 prefetchable memory */
> 
> 		#address-cells = <3>;
> 		#size-cells = <1>;
> 
> 		pci at 0 {
> 			reg = <0 0 0 0x1000>;
[...]
> 		};
> 
> 		pci at 1 {
> 			reg = <1 0 0 0x1000>;
[...]
> 		};

It seems like this isn't working properly. For some reason both the reg
property of pci at 0 and pci at 1 are translated to the same parent address
0x80000000. I'll have to investigate where exactly this goes wrong.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120622/a9e3ca1d/attachment-0001.sig>

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-22 11:00                                                                           ` Thierry Reding
@ 2012-06-22 11:46                                                                             ` Bjorn Helgaas
  -1 siblings, 0 replies; 249+ messages in thread
From: Bjorn Helgaas @ 2012-06-22 11:46 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Mitch Bradley, Stephen Warren, Russell King, linux-pci,
	devicetree-discuss, Rob Herring, Jesse Barnes, Colin Cross,
	linux-tegra, linux-arm-kernel, Arnd Bergmann

On Fri, Jun 22, 2012 at 5:00 AM, Thierry Reding
<thierry.reding@avionic-design.de> wrote:
> On Fri, Jun 22, 2012 at 04:18:05AM -0600, Bjorn Helgaas wrote:
>> On Thu, Jun 21, 2012 at 12:47 AM, Thierry Reding
>> <thierry.reding@avionic-design.de> wrote:
>> > On Tue, Jun 19, 2012 at 11:31:39AM -1000, Mitch Bradley wrote:
>>
>> >> Version A - 3 address cells:  In this version, the intermediate
>> >> address space has 3 cells:  port#, address type, offset.  Address
>> >> type is
>> >>   0 : root port
>> >>   1 : config space
>> >>   2 : extended config space
>> >>   3 : I/O
>> >>   4 : non-prefetchable memory
>> >>   5 : prefetchable memory.
>> >>
>> >> The third cell "offset" is necessary so that the size field has a
>> >> number space that can include it.
>> >>
>> >>       pcie-controller {
>> >>               compatible = "nvidia,tegra20-pcie";
>> >>               reg = <0x80003000 0x00000800   /* PADS registers */
>> >>                      0x80003800 0x00000200>; /* extended configuration space */
>> >>               interrupts = <0 98 0x04   /* controller interrupt */
>> >>                             0 99 0x04>; /* MSI interrupt */
>> >>               status = "disabled";
>> >>
>> >>               ranges = <0 0 0  0x80000000 0x00001000   /* Root port 0 */
>> >>                         0 1 0  0x80004000 0x00080000   /* Port 0 config space */
>> >>                         0 2 0  0x80104000 0x00080000   /* Port 0 ext config space *
>> >>                         0 3 0  0x80400000 0x00008000   /* Port 0 downstream I/O */
>> >>                         0 4 0  0x90000000 0x08000000   /* Port 0 non-prefetchable memory */
>> >>                         0 5 0  0xa0000000 0x08000000   /* Port 0 prefetchable memory */
>> >>
>> >>                         1 0 0  0x80001000 0x00001000   /* Root port 1 */
>> >>                         1 1 0  0x80004000 0x00080000   /* Port 1 config space */
>> >>                         1 2 0  0x80184000 0x00080000   /* Port 1 ext config space */
>> >>                         1 3 0  0x80408000 0x00010000   /* Port 1 downstream I/O */
>> >>                         1 4 0  0x98000000 0x08000000   /* Port 1 non-prefetchable memory */
>> >>                         1 5 0  0xa0000000 0x08000000>; /* Port 1 prefetchable memory */
>> >>
>> >>               #address-cells = <3>;
>> >>               #size-cells = <1>;
>> >>
>> >>               pci@0 {
>> >>                       reg = <0 0 0 0x1000>;
>> >>                       status = "disabled";
>> >>
>> >>                       #address-cells = <3>;
>> >>                       #size-cells = <2>;
>> >>
>> >>                       ranges = <0x80000000 0 0  0 1 0  0 0x00080000   /* config */
>> >>                                 0x90000000 0 0  0 2 0  0 0x00080000   /* extended config */
>> >>                                 0x81000000 0 0  0 3 0  0 0x00008000   /* I/O */
>> >>                                 0x82000000 0 0  0 4 0  0 0x08000000   /* non-prefetchable memory */
>> >>                                 0xc2000000 0 0  0 5 0  0 0x08000000>; /* prefetchable memory */
>> >>
>> >>                       nvidia,ctrl-offset = <0x110>;
>> >>                       nvidia,num-lanes = <2>;
>> >>               };
>> >>
>> >>
>> >>               pci@1 {
>> >>                       reg = <1 0 0 0x1000>;
>> >>                       status = "disabled";
>> >>
>> >>                       #address-cells = <3>;
>> >>                       #size-cells = <2>;
>> >>
>> >>                       ranges = <0x80000000 0 0  1 1 0  0 0x00080000   /* config */
>> >>                                 0x90000000 0 0  1 2 0  0 0x00080000   /* extended config */
>> >>                                 0x81000000 0 0  1 3 0  0 0x00008000   /* I/O */
>> >>                                 0x82000000 0 0  1 4 0  0 0x08000000   /* non-prefetchable memory */
>> >>                                 0xc2000000 0 0  1 5 0  0 0x08000000>; /* prefetchable memory */
>> >>
>> >>                       nvidia,ctrl-offset = <0x118>;
>> >>                       nvidia,num-lanes = <2>;
>> >>               };
>>
>> I'm not familiar with device tree, so pardon me if these are stupid
>> questions.  These seem to be describing PCI host bridges.
>
> Yes, correct.
>
>> I assume some of these ranges describe MMIO, prefetchable MMIO, and
>> I/O port apertures that the bridge forwards to the PCI bus.
>
> Yes.
>
>> Is there provision for any address offset applied by the bridge when
>> it forwards downstream?  (Maybe these bridges don't apply any offset?)
>>  "0xa0000000 0x08000000" appears for both ports 0 and 1 prefetchable
>> memory; I don't know if that's an error, an indication that each
>> bridge applies a different offset, or that both bridges forward the
>> same aperture (I hope not the latter, because Linux can't really deal
>> with that).
>
> That seems to be a typo. It should have been 0xa8000000 in the second
> case. The PCIe controller has registers that are programmed with the
> aperture for the configuration and extended configuration spaces, as
> well as the downstream I/O, prefetchable and non-prefetchable memory
> regions.
>
> The configuration spaces aren't actually forwarded by the bridges, but
> are handled only by the controller.

Right.  The host bridge (controller) would convert memory accesses on
the upstream side into PCI config accesses on its downstream PCI
interface.

> The other apertures are programmed
> into the bridges using standard PCI registers.

If you're talking about programming host bridge apertures, there are
no "standard PCI registers" to do that.  The programming model of the
host bridge itself is not part of the PCI spec.  PCI-to-PCI bridge
apertures *are* specified by the PCI Bridge spec, so those are
standard.

>> Is the bus number aperture included somewhere?  How do we know what
>> bus numbers are available for allocation under each bridge?
>
> Not yet. I don't think DT imposes a bus number allocation on PCI
> bridges. However the matching of DT nodes to PCI bridges is done based
> on the bus number. For that you provide a bus-ranges property which
> defines the bus aperture of the given PCI bridge. The DT matching code
> compares the first cell of this property with the primary bus number of
> the bridge.

I don't fully understand this, but I can tell you that things don't
work very well if we don't know the aperture.  We can make
assumptions, like the root bus is 00, and then enumerate everything
reachable from there.  But then all we know is the largest bus number
actually reachable from bus 00, which is usually smaller then the end
of the aperture.  We don't know how many unused bus numbers there are
in the aperture, so we can't safely allocate any for hot-added
devices.

> This is in fact somewhat counter-productive because it requires you to
> hard-code the PCI hierarchy within the DT and you loose a lot of the
> probing functionality. This is not much of an issue for typical PCI
> endpoints (like network cards) but becomes a problem if you have a PCI
> endpoint that implements an I2C bus and you want to match I2C slaves on
> that bus to device nodes so that the kernel can parse and instantiate
> them properly. I guess in the latter cases hard-coding the PCI tree in
> DT is not actually a drawback, though.
>
>> I see mention of config space.  Is some of that referring to the ECAM
>> as in 7.2.2 of the PCIe spec v3.0 (what we refer to as MMCONFIG on
>> x86)?
>
> I only have access to the PCIe 2.0 specification, but it seems to
> contain the same 7.2.2 section. In fact it looks as though this
> particular controller indeed implements something similar to ECAM. The
> address mapping is a little different, though:
>
>        A[(16 + n - 1):16]: bus number
>        A[15:11]: device number
>        A[10:8]: function number
>        A[7:2]: register number
>        A[1:0]: unused
>
> That information comes directly from the driver and I have no access to
> the corresponding documentation. It seems like the extended
> configuration space is accessed using the same mapping but starting at a
> different base address.
>
> But now that you mention it, maybe the driver code is buggy here, and
> the controller indeed implements ECAM. Furthermore it also seems like
> the current code doesn't work for the extended configuration space
> because while the correct offset into the extended configuration space
> is chosen, the access to registers is done using the same mapping as
> above, so instead of the 12 (10) bits required for the register number
> only 8 (6) are in fact used.
>
> I wonder whether anyone's actually tested this.
>
> Stephen: can you try to find out whether the Tegra PCIe controller
> indeed implements ECAM, or if this scheme is actually just a proprietary
> variant?

It'd be a real shame if they made up a proprietary scheme when ECAM
seems to be required by the spec.  I'm interested because the current
MMCONFIG code seems unnecessarily x86-specific, and I expect every
arch with PCIe would want to use ECAM, so maybe there's some chance
for a generic implementation.

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-22 11:46                                                                             ` Bjorn Helgaas
  0 siblings, 0 replies; 249+ messages in thread
From: Bjorn Helgaas @ 2012-06-22 11:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jun 22, 2012 at 5:00 AM, Thierry Reding
<thierry.reding@avionic-design.de> wrote:
> On Fri, Jun 22, 2012 at 04:18:05AM -0600, Bjorn Helgaas wrote:
>> On Thu, Jun 21, 2012 at 12:47 AM, Thierry Reding
>> <thierry.reding@avionic-design.de> wrote:
>> > On Tue, Jun 19, 2012 at 11:31:39AM -1000, Mitch Bradley wrote:
>>
>> >> Version A - 3 address cells: ?In this version, the intermediate
>> >> address space has 3 cells: ?port#, address type, offset. ?Address
>> >> type is
>> >> ? 0 : root port
>> >> ? 1 : config space
>> >> ? 2 : extended config space
>> >> ? 3 : I/O
>> >> ? 4 : non-prefetchable memory
>> >> ? 5 : prefetchable memory.
>> >>
>> >> The third cell "offset" is necessary so that the size field has a
>> >> number space that can include it.
>> >>
>> >> ? ? ? pcie-controller {
>> >> ? ? ? ? ? ? ? compatible = "nvidia,tegra20-pcie";
>> >> ? ? ? ? ? ? ? reg = <0x80003000 0x00000800 ? /* PADS registers */
>> >> ? ? ? ? ? ? ? ? ? ? ?0x80003800 0x00000200>; /* extended configuration space */
>> >> ? ? ? ? ? ? ? interrupts = <0 98 0x04 ? /* controller interrupt */
>> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0 99 0x04>; /* MSI interrupt */
>> >> ? ? ? ? ? ? ? status = "disabled";
>> >>
>> >> ? ? ? ? ? ? ? ranges = <0 0 0 ?0x80000000 0x00001000 ? /* Root port 0 */
>> >> ? ? ? ? ? ? ? ? ? ? ? ? 0 1 0 ?0x80004000 0x00080000 ? /* Port 0 config space */
>> >> ? ? ? ? ? ? ? ? ? ? ? ? 0 2 0 ?0x80104000 0x00080000 ? /* Port 0 ext config space *
>> >> ? ? ? ? ? ? ? ? ? ? ? ? 0 3 0 ?0x80400000 0x00008000 ? /* Port 0 downstream I/O */
>> >> ? ? ? ? ? ? ? ? ? ? ? ? 0 4 0 ?0x90000000 0x08000000 ? /* Port 0 non-prefetchable memory */
>> >> ? ? ? ? ? ? ? ? ? ? ? ? 0 5 0 ?0xa0000000 0x08000000 ? /* Port 0 prefetchable memory */
>> >>
>> >> ? ? ? ? ? ? ? ? ? ? ? ? 1 0 0 ?0x80001000 0x00001000 ? /* Root port 1 */
>> >> ? ? ? ? ? ? ? ? ? ? ? ? 1 1 0 ?0x80004000 0x00080000 ? /* Port 1 config space */
>> >> ? ? ? ? ? ? ? ? ? ? ? ? 1 2 0 ?0x80184000 0x00080000 ? /* Port 1 ext config space */
>> >> ? ? ? ? ? ? ? ? ? ? ? ? 1 3 0 ?0x80408000 0x00010000 ? /* Port 1 downstream I/O */
>> >> ? ? ? ? ? ? ? ? ? ? ? ? 1 4 0 ?0x98000000 0x08000000 ? /* Port 1 non-prefetchable memory */
>> >> ? ? ? ? ? ? ? ? ? ? ? ? 1 5 0 ?0xa0000000 0x08000000>; /* Port 1 prefetchable memory */
>> >>
>> >> ? ? ? ? ? ? ? #address-cells = <3>;
>> >> ? ? ? ? ? ? ? #size-cells = <1>;
>> >>
>> >> ? ? ? ? ? ? ? pci at 0 {
>> >> ? ? ? ? ? ? ? ? ? ? ? reg = <0 0 0 0x1000>;
>> >> ? ? ? ? ? ? ? ? ? ? ? status = "disabled";
>> >>
>> >> ? ? ? ? ? ? ? ? ? ? ? #address-cells = <3>;
>> >> ? ? ? ? ? ? ? ? ? ? ? #size-cells = <2>;
>> >>
>> >> ? ? ? ? ? ? ? ? ? ? ? ranges = <0x80000000 0 0 ?0 1 0 ?0 0x00080000 ? /* config */
>> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0x90000000 0 0 ?0 2 0 ?0 0x00080000 ? /* extended config */
>> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0x81000000 0 0 ?0 3 0 ?0 0x00008000 ? /* I/O */
>> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0x82000000 0 0 ?0 4 0 ?0 0x08000000 ? /* non-prefetchable memory */
>> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0xc2000000 0 0 ?0 5 0 ?0 0x08000000>; /* prefetchable memory */
>> >>
>> >> ? ? ? ? ? ? ? ? ? ? ? nvidia,ctrl-offset = <0x110>;
>> >> ? ? ? ? ? ? ? ? ? ? ? nvidia,num-lanes = <2>;
>> >> ? ? ? ? ? ? ? };
>> >>
>> >>
>> >> ? ? ? ? ? ? ? pci at 1 {
>> >> ? ? ? ? ? ? ? ? ? ? ? reg = <1 0 0 0x1000>;
>> >> ? ? ? ? ? ? ? ? ? ? ? status = "disabled";
>> >>
>> >> ? ? ? ? ? ? ? ? ? ? ? #address-cells = <3>;
>> >> ? ? ? ? ? ? ? ? ? ? ? #size-cells = <2>;
>> >>
>> >> ? ? ? ? ? ? ? ? ? ? ? ranges = <0x80000000 0 0 ?1 1 0 ?0 0x00080000 ? /* config */
>> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0x90000000 0 0 ?1 2 0 ?0 0x00080000 ? /* extended config */
>> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0x81000000 0 0 ?1 3 0 ?0 0x00008000 ? /* I/O */
>> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0x82000000 0 0 ?1 4 0 ?0 0x08000000 ? /* non-prefetchable memory */
>> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0xc2000000 0 0 ?1 5 0 ?0 0x08000000>; /* prefetchable memory */
>> >>
>> >> ? ? ? ? ? ? ? ? ? ? ? nvidia,ctrl-offset = <0x118>;
>> >> ? ? ? ? ? ? ? ? ? ? ? nvidia,num-lanes = <2>;
>> >> ? ? ? ? ? ? ? };
>>
>> I'm not familiar with device tree, so pardon me if these are stupid
>> questions. ?These seem to be describing PCI host bridges.
>
> Yes, correct.
>
>> I assume some of these ranges describe MMIO, prefetchable MMIO, and
>> I/O port apertures that the bridge forwards to the PCI bus.
>
> Yes.
>
>> Is there provision for any address offset applied by the bridge when
>> it forwards downstream? ?(Maybe these bridges don't apply any offset?)
>> ?"0xa0000000 0x08000000" appears for both ports 0 and 1 prefetchable
>> memory; I don't know if that's an error, an indication that each
>> bridge applies a different offset, or that both bridges forward the
>> same aperture (I hope not the latter, because Linux can't really deal
>> with that).
>
> That seems to be a typo. It should have been 0xa8000000 in the second
> case. The PCIe controller has registers that are programmed with the
> aperture for the configuration and extended configuration spaces, as
> well as the downstream I/O, prefetchable and non-prefetchable memory
> regions.
>
> The configuration spaces aren't actually forwarded by the bridges, but
> are handled only by the controller.

Right.  The host bridge (controller) would convert memory accesses on
the upstream side into PCI config accesses on its downstream PCI
interface.

> The other apertures are programmed
> into the bridges using standard PCI registers.

If you're talking about programming host bridge apertures, there are
no "standard PCI registers" to do that.  The programming model of the
host bridge itself is not part of the PCI spec.  PCI-to-PCI bridge
apertures *are* specified by the PCI Bridge spec, so those are
standard.

>> Is the bus number aperture included somewhere? ?How do we know what
>> bus numbers are available for allocation under each bridge?
>
> Not yet. I don't think DT imposes a bus number allocation on PCI
> bridges. However the matching of DT nodes to PCI bridges is done based
> on the bus number. For that you provide a bus-ranges property which
> defines the bus aperture of the given PCI bridge. The DT matching code
> compares the first cell of this property with the primary bus number of
> the bridge.

I don't fully understand this, but I can tell you that things don't
work very well if we don't know the aperture.  We can make
assumptions, like the root bus is 00, and then enumerate everything
reachable from there.  But then all we know is the largest bus number
actually reachable from bus 00, which is usually smaller then the end
of the aperture.  We don't know how many unused bus numbers there are
in the aperture, so we can't safely allocate any for hot-added
devices.

> This is in fact somewhat counter-productive because it requires you to
> hard-code the PCI hierarchy within the DT and you loose a lot of the
> probing functionality. This is not much of an issue for typical PCI
> endpoints (like network cards) but becomes a problem if you have a PCI
> endpoint that implements an I2C bus and you want to match I2C slaves on
> that bus to device nodes so that the kernel can parse and instantiate
> them properly. I guess in the latter cases hard-coding the PCI tree in
> DT is not actually a drawback, though.
>
>> I see mention of config space. ?Is some of that referring to the ECAM
>> as in 7.2.2 of the PCIe spec v3.0 (what we refer to as MMCONFIG on
>> x86)?
>
> I only have access to the PCIe 2.0 specification, but it seems to
> contain the same 7.2.2 section. In fact it looks as though this
> particular controller indeed implements something similar to ECAM. The
> address mapping is a little different, though:
>
> ? ? ? ?A[(16 + n - 1):16]: bus number
> ? ? ? ?A[15:11]: device number
> ? ? ? ?A[10:8]: function number
> ? ? ? ?A[7:2]: register number
> ? ? ? ?A[1:0]: unused
>
> That information comes directly from the driver and I have no access to
> the corresponding documentation. It seems like the extended
> configuration space is accessed using the same mapping but starting at a
> different base address.
>
> But now that you mention it, maybe the driver code is buggy here, and
> the controller indeed implements ECAM. Furthermore it also seems like
> the current code doesn't work for the extended configuration space
> because while the correct offset into the extended configuration space
> is chosen, the access to registers is done using the same mapping as
> above, so instead of the 12 (10) bits required for the register number
> only 8 (6) are in fact used.
>
> I wonder whether anyone's actually tested this.
>
> Stephen: can you try to find out whether the Tegra PCIe controller
> indeed implements ECAM, or if this scheme is actually just a proprietary
> variant?

It'd be a real shame if they made up a proprietary scheme when ECAM
seems to be required by the spec.  I'm interested because the current
MMCONFIG code seems unnecessarily x86-specific, and I expect every
arch with PCIe would want to use ECAM, so maybe there's some chance
for a generic implementation.

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-22 11:46                                                                             ` Bjorn Helgaas
@ 2012-06-22 12:43                                                                               ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-22 12:43 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Mitch Bradley, Stephen Warren, Russell King, linux-pci,
	devicetree-discuss, Rob Herring, Jesse Barnes, Colin Cross,
	linux-tegra, linux-arm-kernel, Arnd Bergmann

[-- Attachment #1: Type: text/plain, Size: 11129 bytes --]

On Fri, Jun 22, 2012 at 05:46:52AM -0600, Bjorn Helgaas wrote:
> On Fri, Jun 22, 2012 at 5:00 AM, Thierry Reding
> <thierry.reding@avionic-design.de> wrote:
> > On Fri, Jun 22, 2012 at 04:18:05AM -0600, Bjorn Helgaas wrote:
> >> On Thu, Jun 21, 2012 at 12:47 AM, Thierry Reding
> >> <thierry.reding@avionic-design.de> wrote:
> >> > On Tue, Jun 19, 2012 at 11:31:39AM -1000, Mitch Bradley wrote:
> >>
> >> >> Version A - 3 address cells:  In this version, the intermediate
> >> >> address space has 3 cells:  port#, address type, offset.  Address
> >> >> type is
> >> >>   0 : root port
> >> >>   1 : config space
> >> >>   2 : extended config space
> >> >>   3 : I/O
> >> >>   4 : non-prefetchable memory
> >> >>   5 : prefetchable memory.
> >> >>
> >> >> The third cell "offset" is necessary so that the size field has a
> >> >> number space that can include it.
> >> >>
> >> >>       pcie-controller {
> >> >>               compatible = "nvidia,tegra20-pcie";
> >> >>               reg = <0x80003000 0x00000800   /* PADS registers */
> >> >>                      0x80003800 0x00000200>; /* extended configuration space */
> >> >>               interrupts = <0 98 0x04   /* controller interrupt */
> >> >>                             0 99 0x04>; /* MSI interrupt */
> >> >>               status = "disabled";
> >> >>
> >> >>               ranges = <0 0 0  0x80000000 0x00001000   /* Root port 0 */
> >> >>                         0 1 0  0x80004000 0x00080000   /* Port 0 config space */
> >> >>                         0 2 0  0x80104000 0x00080000   /* Port 0 ext config space *
> >> >>                         0 3 0  0x80400000 0x00008000   /* Port 0 downstream I/O */
> >> >>                         0 4 0  0x90000000 0x08000000   /* Port 0 non-prefetchable memory */
> >> >>                         0 5 0  0xa0000000 0x08000000   /* Port 0 prefetchable memory */
> >> >>
> >> >>                         1 0 0  0x80001000 0x00001000   /* Root port 1 */
> >> >>                         1 1 0  0x80004000 0x00080000   /* Port 1 config space */
> >> >>                         1 2 0  0x80184000 0x00080000   /* Port 1 ext config space */
> >> >>                         1 3 0  0x80408000 0x00010000   /* Port 1 downstream I/O */
> >> >>                         1 4 0  0x98000000 0x08000000   /* Port 1 non-prefetchable memory */
> >> >>                         1 5 0  0xa0000000 0x08000000>; /* Port 1 prefetchable memory */
> >> >>
> >> >>               #address-cells = <3>;
> >> >>               #size-cells = <1>;
> >> >>
> >> >>               pci@0 {
> >> >>                       reg = <0 0 0 0x1000>;
> >> >>                       status = "disabled";
> >> >>
> >> >>                       #address-cells = <3>;
> >> >>                       #size-cells = <2>;
> >> >>
> >> >>                       ranges = <0x80000000 0 0  0 1 0  0 0x00080000   /* config */
> >> >>                                 0x90000000 0 0  0 2 0  0 0x00080000   /* extended config */
> >> >>                                 0x81000000 0 0  0 3 0  0 0x00008000   /* I/O */
> >> >>                                 0x82000000 0 0  0 4 0  0 0x08000000   /* non-prefetchable memory */
> >> >>                                 0xc2000000 0 0  0 5 0  0 0x08000000>; /* prefetchable memory */
> >> >>
> >> >>                       nvidia,ctrl-offset = <0x110>;
> >> >>                       nvidia,num-lanes = <2>;
> >> >>               };
> >> >>
> >> >>
> >> >>               pci@1 {
> >> >>                       reg = <1 0 0 0x1000>;
> >> >>                       status = "disabled";
> >> >>
> >> >>                       #address-cells = <3>;
> >> >>                       #size-cells = <2>;
> >> >>
> >> >>                       ranges = <0x80000000 0 0  1 1 0  0 0x00080000   /* config */
> >> >>                                 0x90000000 0 0  1 2 0  0 0x00080000   /* extended config */
> >> >>                                 0x81000000 0 0  1 3 0  0 0x00008000   /* I/O */
> >> >>                                 0x82000000 0 0  1 4 0  0 0x08000000   /* non-prefetchable memory */
> >> >>                                 0xc2000000 0 0  1 5 0  0 0x08000000>; /* prefetchable memory */
> >> >>
> >> >>                       nvidia,ctrl-offset = <0x118>;
> >> >>                       nvidia,num-lanes = <2>;
> >> >>               };
> >>
> >> I'm not familiar with device tree, so pardon me if these are stupid
> >> questions.  These seem to be describing PCI host bridges.
> >
> > Yes, correct.
> >
> >> I assume some of these ranges describe MMIO, prefetchable MMIO, and
> >> I/O port apertures that the bridge forwards to the PCI bus.
> >
> > Yes.
> >
> >> Is there provision for any address offset applied by the bridge when
> >> it forwards downstream?  (Maybe these bridges don't apply any offset?)
> >>  "0xa0000000 0x08000000" appears for both ports 0 and 1 prefetchable
> >> memory; I don't know if that's an error, an indication that each
> >> bridge applies a different offset, or that both bridges forward the
> >> same aperture (I hope not the latter, because Linux can't really deal
> >> with that).
> >
> > That seems to be a typo. It should have been 0xa8000000 in the second
> > case. The PCIe controller has registers that are programmed with the
> > aperture for the configuration and extended configuration spaces, as
> > well as the downstream I/O, prefetchable and non-prefetchable memory
> > regions.
> >
> > The configuration spaces aren't actually forwarded by the bridges, but
> > are handled only by the controller.
> 
> Right.  The host bridge (controller) would convert memory accesses on
> the upstream side into PCI config accesses on its downstream PCI
> interface.
> 
> > The other apertures are programmed
> > into the bridges using standard PCI registers.
> 
> If you're talking about programming host bridge apertures, there are
> no "standard PCI registers" to do that.  The programming model of the
> host bridge itself is not part of the PCI spec.  PCI-to-PCI bridge
> apertures *are* specified by the PCI Bridge spec, so those are
> standard.

Each of the root ports has a PCI-compatible set of configuration
registers, so I guess what is meant is that the apertures a programmed
according to the PCI bridge specification.

> >> Is the bus number aperture included somewhere?  How do we know what
> >> bus numbers are available for allocation under each bridge?
> >
> > Not yet. I don't think DT imposes a bus number allocation on PCI
> > bridges. However the matching of DT nodes to PCI bridges is done based
> > on the bus number. For that you provide a bus-ranges property which
> > defines the bus aperture of the given PCI bridge. The DT matching code
> > compares the first cell of this property with the primary bus number of
> > the bridge.
> 
> I don't fully understand this, but I can tell you that things don't
> work very well if we don't know the aperture.  We can make
> assumptions, like the root bus is 00, and then enumerate everything
> reachable from there.  But then all we know is the largest bus number
> actually reachable from bus 00, which is usually smaller then the end
> of the aperture.  We don't know how many unused bus numbers there are
> in the aperture, so we can't safely allocate any for hot-added
> devices.

I think DT support for PCI is lacking in a lot of areas. PowerPC seems
to be the only architecture actively setting up busses according to the
bus-range property specified in the DT. All other architectures seem to
not pre-allocate bus apertures and go with the default instead. From
what you say that means hot-plugging is out. Although I don't think the
Tegra PCIe controller even supports hot-plugging.

> > This is in fact somewhat counter-productive because it requires you to
> > hard-code the PCI hierarchy within the DT and you loose a lot of the
> > probing functionality. This is not much of an issue for typical PCI
> > endpoints (like network cards) but becomes a problem if you have a PCI
> > endpoint that implements an I2C bus and you want to match I2C slaves on
> > that bus to device nodes so that the kernel can parse and instantiate
> > them properly. I guess in the latter cases hard-coding the PCI tree in
> > DT is not actually a drawback, though.
> >
> >> I see mention of config space.  Is some of that referring to the ECAM
> >> as in 7.2.2 of the PCIe spec v3.0 (what we refer to as MMCONFIG on
> >> x86)?
> >
> > I only have access to the PCIe 2.0 specification, but it seems to
> > contain the same 7.2.2 section. In fact it looks as though this
> > particular controller indeed implements something similar to ECAM. The
> > address mapping is a little different, though:
> >
> >        A[(16 + n - 1):16]: bus number
> >        A[15:11]: device number
> >        A[10:8]: function number
> >        A[7:2]: register number
> >        A[1:0]: unused
> >
> > That information comes directly from the driver and I have no access to
> > the corresponding documentation. It seems like the extended
> > configuration space is accessed using the same mapping but starting at a
> > different base address.
> >
> > But now that you mention it, maybe the driver code is buggy here, and
> > the controller indeed implements ECAM. Furthermore it also seems like
> > the current code doesn't work for the extended configuration space
> > because while the correct offset into the extended configuration space
> > is chosen, the access to registers is done using the same mapping as
> > above, so instead of the 12 (10) bits required for the register number
> > only 8 (6) are in fact used.
> >
> > I wonder whether anyone's actually tested this.
> >
> > Stephen: can you try to find out whether the Tegra PCIe controller
> > indeed implements ECAM, or if this scheme is actually just a proprietary
> > variant?
> 
> It'd be a real shame if they made up a proprietary scheme when ECAM
> seems to be required by the spec.  I'm interested because the current
> MMCONFIG code seems unnecessarily x86-specific, and I expect every
> arch with PCIe would want to use ECAM, so maybe there's some chance
> for a generic implementation.

Since this is pretty well specified by PCIe, a generic implementation
should be possible. We'll have to wait for some better documentation on
Tegra to know whether this is actually ECAM or not.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-22 12:43                                                                               ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-22 12:43 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jun 22, 2012 at 05:46:52AM -0600, Bjorn Helgaas wrote:
> On Fri, Jun 22, 2012 at 5:00 AM, Thierry Reding
> <thierry.reding@avionic-design.de> wrote:
> > On Fri, Jun 22, 2012 at 04:18:05AM -0600, Bjorn Helgaas wrote:
> >> On Thu, Jun 21, 2012 at 12:47 AM, Thierry Reding
> >> <thierry.reding@avionic-design.de> wrote:
> >> > On Tue, Jun 19, 2012 at 11:31:39AM -1000, Mitch Bradley wrote:
> >>
> >> >> Version A - 3 address cells: ?In this version, the intermediate
> >> >> address space has 3 cells: ?port#, address type, offset. ?Address
> >> >> type is
> >> >> ? 0 : root port
> >> >> ? 1 : config space
> >> >> ? 2 : extended config space
> >> >> ? 3 : I/O
> >> >> ? 4 : non-prefetchable memory
> >> >> ? 5 : prefetchable memory.
> >> >>
> >> >> The third cell "offset" is necessary so that the size field has a
> >> >> number space that can include it.
> >> >>
> >> >> ? ? ? pcie-controller {
> >> >> ? ? ? ? ? ? ? compatible = "nvidia,tegra20-pcie";
> >> >> ? ? ? ? ? ? ? reg = <0x80003000 0x00000800 ? /* PADS registers */
> >> >> ? ? ? ? ? ? ? ? ? ? ?0x80003800 0x00000200>; /* extended configuration space */
> >> >> ? ? ? ? ? ? ? interrupts = <0 98 0x04 ? /* controller interrupt */
> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0 99 0x04>; /* MSI interrupt */
> >> >> ? ? ? ? ? ? ? status = "disabled";
> >> >>
> >> >> ? ? ? ? ? ? ? ranges = <0 0 0 ?0x80000000 0x00001000 ? /* Root port 0 */
> >> >> ? ? ? ? ? ? ? ? ? ? ? ? 0 1 0 ?0x80004000 0x00080000 ? /* Port 0 config space */
> >> >> ? ? ? ? ? ? ? ? ? ? ? ? 0 2 0 ?0x80104000 0x00080000 ? /* Port 0 ext config space *
> >> >> ? ? ? ? ? ? ? ? ? ? ? ? 0 3 0 ?0x80400000 0x00008000 ? /* Port 0 downstream I/O */
> >> >> ? ? ? ? ? ? ? ? ? ? ? ? 0 4 0 ?0x90000000 0x08000000 ? /* Port 0 non-prefetchable memory */
> >> >> ? ? ? ? ? ? ? ? ? ? ? ? 0 5 0 ?0xa0000000 0x08000000 ? /* Port 0 prefetchable memory */
> >> >>
> >> >> ? ? ? ? ? ? ? ? ? ? ? ? 1 0 0 ?0x80001000 0x00001000 ? /* Root port 1 */
> >> >> ? ? ? ? ? ? ? ? ? ? ? ? 1 1 0 ?0x80004000 0x00080000 ? /* Port 1 config space */
> >> >> ? ? ? ? ? ? ? ? ? ? ? ? 1 2 0 ?0x80184000 0x00080000 ? /* Port 1 ext config space */
> >> >> ? ? ? ? ? ? ? ? ? ? ? ? 1 3 0 ?0x80408000 0x00010000 ? /* Port 1 downstream I/O */
> >> >> ? ? ? ? ? ? ? ? ? ? ? ? 1 4 0 ?0x98000000 0x08000000 ? /* Port 1 non-prefetchable memory */
> >> >> ? ? ? ? ? ? ? ? ? ? ? ? 1 5 0 ?0xa0000000 0x08000000>; /* Port 1 prefetchable memory */
> >> >>
> >> >> ? ? ? ? ? ? ? #address-cells = <3>;
> >> >> ? ? ? ? ? ? ? #size-cells = <1>;
> >> >>
> >> >> ? ? ? ? ? ? ? pci at 0 {
> >> >> ? ? ? ? ? ? ? ? ? ? ? reg = <0 0 0 0x1000>;
> >> >> ? ? ? ? ? ? ? ? ? ? ? status = "disabled";
> >> >>
> >> >> ? ? ? ? ? ? ? ? ? ? ? #address-cells = <3>;
> >> >> ? ? ? ? ? ? ? ? ? ? ? #size-cells = <2>;
> >> >>
> >> >> ? ? ? ? ? ? ? ? ? ? ? ranges = <0x80000000 0 0 ?0 1 0 ?0 0x00080000 ? /* config */
> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0x90000000 0 0 ?0 2 0 ?0 0x00080000 ? /* extended config */
> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0x81000000 0 0 ?0 3 0 ?0 0x00008000 ? /* I/O */
> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0x82000000 0 0 ?0 4 0 ?0 0x08000000 ? /* non-prefetchable memory */
> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0xc2000000 0 0 ?0 5 0 ?0 0x08000000>; /* prefetchable memory */
> >> >>
> >> >> ? ? ? ? ? ? ? ? ? ? ? nvidia,ctrl-offset = <0x110>;
> >> >> ? ? ? ? ? ? ? ? ? ? ? nvidia,num-lanes = <2>;
> >> >> ? ? ? ? ? ? ? };
> >> >>
> >> >>
> >> >> ? ? ? ? ? ? ? pci at 1 {
> >> >> ? ? ? ? ? ? ? ? ? ? ? reg = <1 0 0 0x1000>;
> >> >> ? ? ? ? ? ? ? ? ? ? ? status = "disabled";
> >> >>
> >> >> ? ? ? ? ? ? ? ? ? ? ? #address-cells = <3>;
> >> >> ? ? ? ? ? ? ? ? ? ? ? #size-cells = <2>;
> >> >>
> >> >> ? ? ? ? ? ? ? ? ? ? ? ranges = <0x80000000 0 0 ?1 1 0 ?0 0x00080000 ? /* config */
> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0x90000000 0 0 ?1 2 0 ?0 0x00080000 ? /* extended config */
> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0x81000000 0 0 ?1 3 0 ?0 0x00008000 ? /* I/O */
> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0x82000000 0 0 ?1 4 0 ?0 0x08000000 ? /* non-prefetchable memory */
> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0xc2000000 0 0 ?1 5 0 ?0 0x08000000>; /* prefetchable memory */
> >> >>
> >> >> ? ? ? ? ? ? ? ? ? ? ? nvidia,ctrl-offset = <0x118>;
> >> >> ? ? ? ? ? ? ? ? ? ? ? nvidia,num-lanes = <2>;
> >> >> ? ? ? ? ? ? ? };
> >>
> >> I'm not familiar with device tree, so pardon me if these are stupid
> >> questions. ?These seem to be describing PCI host bridges.
> >
> > Yes, correct.
> >
> >> I assume some of these ranges describe MMIO, prefetchable MMIO, and
> >> I/O port apertures that the bridge forwards to the PCI bus.
> >
> > Yes.
> >
> >> Is there provision for any address offset applied by the bridge when
> >> it forwards downstream? ?(Maybe these bridges don't apply any offset?)
> >> ?"0xa0000000 0x08000000" appears for both ports 0 and 1 prefetchable
> >> memory; I don't know if that's an error, an indication that each
> >> bridge applies a different offset, or that both bridges forward the
> >> same aperture (I hope not the latter, because Linux can't really deal
> >> with that).
> >
> > That seems to be a typo. It should have been 0xa8000000 in the second
> > case. The PCIe controller has registers that are programmed with the
> > aperture for the configuration and extended configuration spaces, as
> > well as the downstream I/O, prefetchable and non-prefetchable memory
> > regions.
> >
> > The configuration spaces aren't actually forwarded by the bridges, but
> > are handled only by the controller.
> 
> Right.  The host bridge (controller) would convert memory accesses on
> the upstream side into PCI config accesses on its downstream PCI
> interface.
> 
> > The other apertures are programmed
> > into the bridges using standard PCI registers.
> 
> If you're talking about programming host bridge apertures, there are
> no "standard PCI registers" to do that.  The programming model of the
> host bridge itself is not part of the PCI spec.  PCI-to-PCI bridge
> apertures *are* specified by the PCI Bridge spec, so those are
> standard.

Each of the root ports has a PCI-compatible set of configuration
registers, so I guess what is meant is that the apertures a programmed
according to the PCI bridge specification.

> >> Is the bus number aperture included somewhere? ?How do we know what
> >> bus numbers are available for allocation under each bridge?
> >
> > Not yet. I don't think DT imposes a bus number allocation on PCI
> > bridges. However the matching of DT nodes to PCI bridges is done based
> > on the bus number. For that you provide a bus-ranges property which
> > defines the bus aperture of the given PCI bridge. The DT matching code
> > compares the first cell of this property with the primary bus number of
> > the bridge.
> 
> I don't fully understand this, but I can tell you that things don't
> work very well if we don't know the aperture.  We can make
> assumptions, like the root bus is 00, and then enumerate everything
> reachable from there.  But then all we know is the largest bus number
> actually reachable from bus 00, which is usually smaller then the end
> of the aperture.  We don't know how many unused bus numbers there are
> in the aperture, so we can't safely allocate any for hot-added
> devices.

I think DT support for PCI is lacking in a lot of areas. PowerPC seems
to be the only architecture actively setting up busses according to the
bus-range property specified in the DT. All other architectures seem to
not pre-allocate bus apertures and go with the default instead. From
what you say that means hot-plugging is out. Although I don't think the
Tegra PCIe controller even supports hot-plugging.

> > This is in fact somewhat counter-productive because it requires you to
> > hard-code the PCI hierarchy within the DT and you loose a lot of the
> > probing functionality. This is not much of an issue for typical PCI
> > endpoints (like network cards) but becomes a problem if you have a PCI
> > endpoint that implements an I2C bus and you want to match I2C slaves on
> > that bus to device nodes so that the kernel can parse and instantiate
> > them properly. I guess in the latter cases hard-coding the PCI tree in
> > DT is not actually a drawback, though.
> >
> >> I see mention of config space. ?Is some of that referring to the ECAM
> >> as in 7.2.2 of the PCIe spec v3.0 (what we refer to as MMCONFIG on
> >> x86)?
> >
> > I only have access to the PCIe 2.0 specification, but it seems to
> > contain the same 7.2.2 section. In fact it looks as though this
> > particular controller indeed implements something similar to ECAM. The
> > address mapping is a little different, though:
> >
> > ? ? ? ?A[(16 + n - 1):16]: bus number
> > ? ? ? ?A[15:11]: device number
> > ? ? ? ?A[10:8]: function number
> > ? ? ? ?A[7:2]: register number
> > ? ? ? ?A[1:0]: unused
> >
> > That information comes directly from the driver and I have no access to
> > the corresponding documentation. It seems like the extended
> > configuration space is accessed using the same mapping but starting at a
> > different base address.
> >
> > But now that you mention it, maybe the driver code is buggy here, and
> > the controller indeed implements ECAM. Furthermore it also seems like
> > the current code doesn't work for the extended configuration space
> > because while the correct offset into the extended configuration space
> > is chosen, the access to registers is done using the same mapping as
> > above, so instead of the 12 (10) bits required for the register number
> > only 8 (6) are in fact used.
> >
> > I wonder whether anyone's actually tested this.
> >
> > Stephen: can you try to find out whether the Tegra PCIe controller
> > indeed implements ECAM, or if this scheme is actually just a proprietary
> > variant?
> 
> It'd be a real shame if they made up a proprietary scheme when ECAM
> seems to be required by the spec.  I'm interested because the current
> MMCONFIG code seems unnecessarily x86-specific, and I expect every
> arch with PCIe would want to use ECAM, so maybe there's some chance
> for a generic implementation.

Since this is pretty well specified by PCIe, a generic implementation
should be possible. We'll have to wait for some better documentation on
Tegra to know whether this is actually ECAM or not.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120622/92ed485b/attachment-0001.sig>

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-22 12:43                                                                               ` Thierry Reding
@ 2012-06-22 13:03                                                                                 ` Arnd Bergmann
  -1 siblings, 0 replies; 249+ messages in thread
From: Arnd Bergmann @ 2012-06-22 13:03 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Bjorn Helgaas, Mitch Bradley, Stephen Warren, Russell King,
	linux-pci, devicetree-discuss, Rob Herring, Jesse Barnes,
	Colin Cross, linux-tegra, linux-arm-kernel

On Friday 22 June 2012, Thierry Reding wrote:
> On Fri, Jun 22, 2012 at 05:46:52AM -0600, Bjorn Helgaas wrote:
> > On Fri, Jun 22, 2012 at 5:00 AM, Thierry Reding
> > <thierry.reding@avionic-design.de> wrote:
> > >> Is the bus number aperture included somewhere?  How do we know what
> > >> bus numbers are available for allocation under each bridge?
> > >
> > > Not yet. I don't think DT imposes a bus number allocation on PCI
> > > bridges. However the matching of DT nodes to PCI bridges is done based
> > > on the bus number. For that you provide a bus-ranges property which
> > > defines the bus aperture of the given PCI bridge. The DT matching code
> > > compares the first cell of this property with the primary bus number of
> > > the bridge.
> > 
> > I don't fully understand this, but I can tell you that things don't
> > work very well if we don't know the aperture.  We can make
> > assumptions, like the root bus is 00, and then enumerate everything
> > reachable from there.  But then all we know is the largest bus number
> > actually reachable from bus 00, which is usually smaller then the end
> > of the aperture.  We don't know how many unused bus numbers there are
> > in the aperture, so we can't safely allocate any for hot-added
> > devices.

I believe the assumption today is that all bus numbers are ok on each
root port, which is usually the case. There was something about a Power
Mac that faked a single PCI bus number space across both an AGP and
a PCIe domain in pmac_pci_fixup_u4_of_node(), but I think that is the
exception.

Is there any requirement to use a bus aperture on non-PC hardware?
 
> I think DT support for PCI is lacking in a lot of areas. PowerPC seems
> to be the only architecture actively setting up busses according to the
> bus-range property specified in the DT. All other architectures seem to
> not pre-allocate bus apertures and go with the default instead. From
> what you say that means hot-plugging is out. Although I don't think the
> Tegra PCIe controller even supports hot-plugging.

If the default is allowing any bus numbers, and that matches the
hardware capabilities, I think hot-plugging would work.

	Arnd

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-22 13:03                                                                                 ` Arnd Bergmann
  0 siblings, 0 replies; 249+ messages in thread
From: Arnd Bergmann @ 2012-06-22 13:03 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 22 June 2012, Thierry Reding wrote:
> On Fri, Jun 22, 2012 at 05:46:52AM -0600, Bjorn Helgaas wrote:
> > On Fri, Jun 22, 2012 at 5:00 AM, Thierry Reding
> > <thierry.reding@avionic-design.de> wrote:
> > >> Is the bus number aperture included somewhere?  How do we know what
> > >> bus numbers are available for allocation under each bridge?
> > >
> > > Not yet. I don't think DT imposes a bus number allocation on PCI
> > > bridges. However the matching of DT nodes to PCI bridges is done based
> > > on the bus number. For that you provide a bus-ranges property which
> > > defines the bus aperture of the given PCI bridge. The DT matching code
> > > compares the first cell of this property with the primary bus number of
> > > the bridge.
> > 
> > I don't fully understand this, but I can tell you that things don't
> > work very well if we don't know the aperture.  We can make
> > assumptions, like the root bus is 00, and then enumerate everything
> > reachable from there.  But then all we know is the largest bus number
> > actually reachable from bus 00, which is usually smaller then the end
> > of the aperture.  We don't know how many unused bus numbers there are
> > in the aperture, so we can't safely allocate any for hot-added
> > devices.

I believe the assumption today is that all bus numbers are ok on each
root port, which is usually the case. There was something about a Power
Mac that faked a single PCI bus number space across both an AGP and
a PCIe domain in pmac_pci_fixup_u4_of_node(), but I think that is the
exception.

Is there any requirement to use a bus aperture on non-PC hardware?
 
> I think DT support for PCI is lacking in a lot of areas. PowerPC seems
> to be the only architecture actively setting up busses according to the
> bus-range property specified in the DT. All other architectures seem to
> not pre-allocate bus apertures and go with the default instead. From
> what you say that means hot-plugging is out. Although I don't think the
> Tegra PCIe controller even supports hot-plugging.

If the default is allowing any bus numbers, and that matches the
hardware capabilities, I think hot-plugging would work.

	Arnd

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-22 11:04                                                                   ` Thierry Reding
  (?)
@ 2012-06-22 13:22                                                                       ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-22 13:22 UTC (permalink / raw)
  To: Mitch Bradley
  Cc: Stephen Warren, Russell King, linux-pci-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Jesse Barnes, Colin Cross, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Arnd Bergmann

[-- Attachment #1: Type: text/plain, Size: 9098 bytes --]

On Fri, Jun 22, 2012 at 01:04:03PM +0200, Thierry Reding wrote:
> On Tue, Jun 19, 2012 at 11:31:39AM -1000, Mitch Bradley wrote:
> > On 6/19/2012 3:30 AM, Thierry Reding wrote:
> > >On Fri, Jun 15, 2012 at 08:12:36AM +0200, Thierry Reding wrote:
> > >>On Thu, Jun 14, 2012 at 01:50:56PM -0600, Stephen Warren wrote:
> > >>>On 06/14/2012 01:29 PM, Thierry Reding wrote:
> > >>>>On Thu, Jun 14, 2012 at 12:30:50PM -0600, Stephen Warren wrote:
> > >>>>>On 06/14/2012 03:19 AM, Thierry Reding wrote:
> > >>>...
> > >>>>>>#address-cells = <1>; #size-cells = <1>;
> > >>>>>>
> > >>>>>>pci@80000000 {
> > >>>>>
> > >>>>>I'm still not convinced that using the address of the port's
> > >>>>>registers is the correct way to represent each port. The port
> > >>>>>index seems much more useful.
> > >>>>>
> > >>>>>The main reason here is that there are a lot of registers that
> > >>>>>contain fields for each port - far more than the combination of
> > >>>>>this node's reg and ctrl-offset (which I assume is an address
> > >>>>>offset for just one example of this issue) properties can
> > >>>>>describe. The bit position and bit stride of these fields isn't
> > >>>>>necessarily the same in each register. Do we want a property like
> > >>>>>ctrl-offset for every single type of field in every single shared
> > >>>>>register that describes the location of the relevant data, or
> > >>>>>just a single "port ID" bit that can be applied to anything?
> > >>>>>
> > >>>>>(Perhaps this isn't so obvious looking at the TRM since it
> > >>>>>doesn't document all registers, and I'm also looking at the
> > >>>>>Tegra30 documentation too, which might be more exposed to this -
> > >>>>>I haven't correlated all the documentation sources to be sure
> > >>>>>though)
> > >>>>
> > >>>>I agree that maybe adding properties for each bit position or
> > >>>>register offset may not work out too well. But I think it still
> > >>>>makes sense to use the base address of the port's registers (see
> > >>>>below). We could of course add some code to determine the index
> > >>>>from the base address at initialization time and reuse the index
> > >>>>where appropriate.
> > >>>
> > >>>To me, working back from address to ID then using the ID to calculate
> > >>>some other addresses seems far more icky than just calculating all the
> > >>>addresses based off of one ID. But, I suppose this doesn't make a huge
> > >>>practical difference.
> > >>
> > >>This really depends on the device vs. no device decision below. If we can
> > >>make it work without needing an extra device for it, then using the index
> > >>is certainly better. However, if we instantiate devices from the DT, then
> > >>we have the address anyway and adding the index as a property would be
> > >>redundant and error prone (what happens if somebody sets the index of the
> > >>port at address 0x80000000 to 2?).
> > >
> > >An additional problem with this is that we'd have to add the following
> > >to the pcie-controller node:
> > >
> > >	#address-cells = <1>;
> > >	#size-cells = <0>;
> > >
> > >This will conflict with the "ranges" property, because suddenly we can
> > >no longer map the regions properly. Maybe Mitch can comment on whether
> > >this is possible or not?
> > >
> > >To make it clearer what I'm talking about, here's the DT snippet again
> > >(with the compatible property removed from the pci@ nodes because they
> > >are no longer probed by a driver, the "simple-bus" removed from the
> > >pcie-controller node's compatible property removed and its #address-
> > >and #size-cells properties adjusted as described above).
> > >
> > >	pcie-controller {
> > >		compatible = "nvidia,tegra20-pcie";
> > >		reg = <0x80003000 0x00000800   /* PADS registers */
> > >		       0x80003800 0x00000200   /* AFI registers */
> > >		       0x80004000 0x00100000   /* configuration space */
> > >		       0x80104000 0x00100000>; /* extended configuration space */
> > >		interrupts = <0 98 0x04   /* controller interrupt */
> > >			      0 99 0x04>; /* MSI interrupt */
> > >		status = "disabled";
> > >
> > >		ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */
> > >			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
> > >			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
> > >			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
> > >
> > >		#address-cells = <1>;
> > >		#size-cells = <0>;
> > >
> > >		pci@0 {
> > >			reg = <2>;
> > >			status = "disabled";
> > >
> > >			#address-cells = <3>;
> > >			#size-cells = <2>;
> > >
> > >			ranges = <0x81000000 0 0 0x80400000 0 0x00008000   /* I/O */
> > >				  0x82000000 0 0 0x90000000 0 0x08000000   /* non-prefetchable memory */
> > >				  0xc2000000 0 0 0xa0000000 0 0x08000000>; /* prefetchable memory */
> > >
> > >			nvidia,ctrl-offset = <0x110>;
> > >			nvidia,num-lanes = <2>;
> > >		};
> > >
> > >		pci@1 {
> > >			reg = <1>;
> > >			status = "disabled";
> > >
> > >			#address-cells = <3>;
> > >			#size-cells = <2>;
> > >
> > >			ranges = <0x81000000 0 0 0x80408000 0 0x00008000   /* I/O */
> > >				  0x82000000 0 0 0x98000000 0 0x08000000   /* non-prefetchable memory */
> > >				  0xc2000000 0 0 0xa8000000 0 0x08000000>; /* prefetchable memory */
> > >
> > >			nvidia,ctrl-offset = <0x118>;
> > >			nvidia,num-lanes = <2>;
> > >		};
> > >	};
> > >
> > >AIUI none of the ranges properties are valid anymore, because the bus
> > >represented by pcie-controller no longer reflects the truth, namely that
> > >it translates the CPU address space to the PCI address space.
> > >
> > 
> > I think you can use a small-integer port number as an address by
> > defining the intermediate address space properly, and using
> > appropriate ranges above and below.  Here's a swag at how that would
> > look.
> > 
> > I present three versions, using different choices for the
> > intermediate address space encoding.  The intermediate address space
> > may seem somewhat artificial, in that it decouples the "linear pass
> > through of ranges" between the lower PCI address space and the upper
> > CPU address space.  But in another sense, it accurately reflects
> > that fact that the bus bridge "slices and dices" that linear address
> > space into non-contiguous pieces.
> > 
> > Note that I'm also fixing a problem that I neglected to mention
> > earlier - namely the fact that config space is part of the child PCI
> > address space so it must be passed through.
> > 
> > Version A - 3 address cells:  In this version, the intermediate
> > address space has 3 cells:  port#, address type, offset.  Address
> > type is
> >   0 : root port
> >   1 : config space
> >   2 : extended config space
> >   3 : I/O
> >   4 : non-prefetchable memory
> >   5 : prefetchable memory.
> > 
> > The third cell "offset" is necessary so that the size field has a
> > number space that can include it.
> > 
> > 	pcie-controller {
> > 		compatible = "nvidia,tegra20-pcie";
> > 		reg = <0x80003000 0x00000800   /* PADS registers */
> > 		       0x80003800 0x00000200>; /* extended configuration space */
> > 		interrupts = <0 98 0x04   /* controller interrupt */
> > 			      0 99 0x04>; /* MSI interrupt */
> > 		status = "disabled";
> > 
> > 		ranges = <0 0 0  0x80000000 0x00001000   /* Root port 0 */
> > 			  0 1 0  0x80004000 0x00080000   /* Port 0 config space */
> > 			  0 2 0  0x80104000 0x00080000   /* Port 0 ext config space *
> > 			  0 3 0  0x80400000 0x00008000   /* Port 0 downstream I/O */
> > 			  0 4 0  0x90000000 0x08000000   /* Port 0 non-prefetchable memory */
> > 			  0 5 0  0xa0000000 0x08000000   /* Port 0 prefetchable memory */
> > 
> > 			  1 0 0  0x80001000 0x00001000   /* Root port 1 */
> > 			  1 1 0  0x80004000 0x00080000   /* Port 1 config space */
> > 			  1 2 0  0x80184000 0x00080000   /* Port 1 ext config space */
> > 			  1 3 0  0x80408000 0x00010000   /* Port 1 downstream I/O */
> > 			  1 4 0  0x98000000 0x08000000   /* Port 1 non-prefetchable memory */
> > 			  1 5 0  0xa0000000 0x08000000>; /* Port 1 prefetchable memory */
> > 
> > 		#address-cells = <3>;
> > 		#size-cells = <1>;
> > 
> > 		pci@0 {
> > 			reg = <0 0 0 0x1000>;
> [...]
> > 		};
> > 
> > 		pci@1 {
> > 			reg = <1 0 0 0x1000>;
> [...]
> > 		};
> 
> It seems like this isn't working properly. For some reason both the reg
> property of pci@0 and pci@1 are translated to the same parent address
> 0x80000000. I'll have to investigate where exactly this goes wrong.

So it turns out that while of_read_number() can actually read any number
of cells, only the two least significant are kept because it returns a
u64. Since of_bus_default_map() uses of_read_number() the addresses
<0 0 0> and <1 0 0> are in fact the same. I'm not sure how best to solve
this. I'm not aware of a 128 bit integer type in the kernel, so I guess
the better alternative would be to fix of_bus_default_map() to cope with
#address-cells > 2 properly.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-22 13:22                                                                       ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-22 13:22 UTC (permalink / raw)
  To: Mitch Bradley
  Cc: Stephen Warren, Russell King, linux-pci, devicetree-discuss,
	Rob Herring, Jesse Barnes, Colin Cross, linux-tegra,
	linux-arm-kernel, Arnd Bergmann

[-- Attachment #1: Type: text/plain, Size: 9098 bytes --]

On Fri, Jun 22, 2012 at 01:04:03PM +0200, Thierry Reding wrote:
> On Tue, Jun 19, 2012 at 11:31:39AM -1000, Mitch Bradley wrote:
> > On 6/19/2012 3:30 AM, Thierry Reding wrote:
> > >On Fri, Jun 15, 2012 at 08:12:36AM +0200, Thierry Reding wrote:
> > >>On Thu, Jun 14, 2012 at 01:50:56PM -0600, Stephen Warren wrote:
> > >>>On 06/14/2012 01:29 PM, Thierry Reding wrote:
> > >>>>On Thu, Jun 14, 2012 at 12:30:50PM -0600, Stephen Warren wrote:
> > >>>>>On 06/14/2012 03:19 AM, Thierry Reding wrote:
> > >>>...
> > >>>>>>#address-cells = <1>; #size-cells = <1>;
> > >>>>>>
> > >>>>>>pci@80000000 {
> > >>>>>
> > >>>>>I'm still not convinced that using the address of the port's
> > >>>>>registers is the correct way to represent each port. The port
> > >>>>>index seems much more useful.
> > >>>>>
> > >>>>>The main reason here is that there are a lot of registers that
> > >>>>>contain fields for each port - far more than the combination of
> > >>>>>this node's reg and ctrl-offset (which I assume is an address
> > >>>>>offset for just one example of this issue) properties can
> > >>>>>describe. The bit position and bit stride of these fields isn't
> > >>>>>necessarily the same in each register. Do we want a property like
> > >>>>>ctrl-offset for every single type of field in every single shared
> > >>>>>register that describes the location of the relevant data, or
> > >>>>>just a single "port ID" bit that can be applied to anything?
> > >>>>>
> > >>>>>(Perhaps this isn't so obvious looking at the TRM since it
> > >>>>>doesn't document all registers, and I'm also looking at the
> > >>>>>Tegra30 documentation too, which might be more exposed to this -
> > >>>>>I haven't correlated all the documentation sources to be sure
> > >>>>>though)
> > >>>>
> > >>>>I agree that maybe adding properties for each bit position or
> > >>>>register offset may not work out too well. But I think it still
> > >>>>makes sense to use the base address of the port's registers (see
> > >>>>below). We could of course add some code to determine the index
> > >>>>from the base address at initialization time and reuse the index
> > >>>>where appropriate.
> > >>>
> > >>>To me, working back from address to ID then using the ID to calculate
> > >>>some other addresses seems far more icky than just calculating all the
> > >>>addresses based off of one ID. But, I suppose this doesn't make a huge
> > >>>practical difference.
> > >>
> > >>This really depends on the device vs. no device decision below. If we can
> > >>make it work without needing an extra device for it, then using the index
> > >>is certainly better. However, if we instantiate devices from the DT, then
> > >>we have the address anyway and adding the index as a property would be
> > >>redundant and error prone (what happens if somebody sets the index of the
> > >>port at address 0x80000000 to 2?).
> > >
> > >An additional problem with this is that we'd have to add the following
> > >to the pcie-controller node:
> > >
> > >	#address-cells = <1>;
> > >	#size-cells = <0>;
> > >
> > >This will conflict with the "ranges" property, because suddenly we can
> > >no longer map the regions properly. Maybe Mitch can comment on whether
> > >this is possible or not?
> > >
> > >To make it clearer what I'm talking about, here's the DT snippet again
> > >(with the compatible property removed from the pci@ nodes because they
> > >are no longer probed by a driver, the "simple-bus" removed from the
> > >pcie-controller node's compatible property removed and its #address-
> > >and #size-cells properties adjusted as described above).
> > >
> > >	pcie-controller {
> > >		compatible = "nvidia,tegra20-pcie";
> > >		reg = <0x80003000 0x00000800   /* PADS registers */
> > >		       0x80003800 0x00000200   /* AFI registers */
> > >		       0x80004000 0x00100000   /* configuration space */
> > >		       0x80104000 0x00100000>; /* extended configuration space */
> > >		interrupts = <0 98 0x04   /* controller interrupt */
> > >			      0 99 0x04>; /* MSI interrupt */
> > >		status = "disabled";
> > >
> > >		ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */
> > >			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
> > >			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
> > >			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
> > >
> > >		#address-cells = <1>;
> > >		#size-cells = <0>;
> > >
> > >		pci@0 {
> > >			reg = <2>;
> > >			status = "disabled";
> > >
> > >			#address-cells = <3>;
> > >			#size-cells = <2>;
> > >
> > >			ranges = <0x81000000 0 0 0x80400000 0 0x00008000   /* I/O */
> > >				  0x82000000 0 0 0x90000000 0 0x08000000   /* non-prefetchable memory */
> > >				  0xc2000000 0 0 0xa0000000 0 0x08000000>; /* prefetchable memory */
> > >
> > >			nvidia,ctrl-offset = <0x110>;
> > >			nvidia,num-lanes = <2>;
> > >		};
> > >
> > >		pci@1 {
> > >			reg = <1>;
> > >			status = "disabled";
> > >
> > >			#address-cells = <3>;
> > >			#size-cells = <2>;
> > >
> > >			ranges = <0x81000000 0 0 0x80408000 0 0x00008000   /* I/O */
> > >				  0x82000000 0 0 0x98000000 0 0x08000000   /* non-prefetchable memory */
> > >				  0xc2000000 0 0 0xa8000000 0 0x08000000>; /* prefetchable memory */
> > >
> > >			nvidia,ctrl-offset = <0x118>;
> > >			nvidia,num-lanes = <2>;
> > >		};
> > >	};
> > >
> > >AIUI none of the ranges properties are valid anymore, because the bus
> > >represented by pcie-controller no longer reflects the truth, namely that
> > >it translates the CPU address space to the PCI address space.
> > >
> > 
> > I think you can use a small-integer port number as an address by
> > defining the intermediate address space properly, and using
> > appropriate ranges above and below.  Here's a swag at how that would
> > look.
> > 
> > I present three versions, using different choices for the
> > intermediate address space encoding.  The intermediate address space
> > may seem somewhat artificial, in that it decouples the "linear pass
> > through of ranges" between the lower PCI address space and the upper
> > CPU address space.  But in another sense, it accurately reflects
> > that fact that the bus bridge "slices and dices" that linear address
> > space into non-contiguous pieces.
> > 
> > Note that I'm also fixing a problem that I neglected to mention
> > earlier - namely the fact that config space is part of the child PCI
> > address space so it must be passed through.
> > 
> > Version A - 3 address cells:  In this version, the intermediate
> > address space has 3 cells:  port#, address type, offset.  Address
> > type is
> >   0 : root port
> >   1 : config space
> >   2 : extended config space
> >   3 : I/O
> >   4 : non-prefetchable memory
> >   5 : prefetchable memory.
> > 
> > The third cell "offset" is necessary so that the size field has a
> > number space that can include it.
> > 
> > 	pcie-controller {
> > 		compatible = "nvidia,tegra20-pcie";
> > 		reg = <0x80003000 0x00000800   /* PADS registers */
> > 		       0x80003800 0x00000200>; /* extended configuration space */
> > 		interrupts = <0 98 0x04   /* controller interrupt */
> > 			      0 99 0x04>; /* MSI interrupt */
> > 		status = "disabled";
> > 
> > 		ranges = <0 0 0  0x80000000 0x00001000   /* Root port 0 */
> > 			  0 1 0  0x80004000 0x00080000   /* Port 0 config space */
> > 			  0 2 0  0x80104000 0x00080000   /* Port 0 ext config space *
> > 			  0 3 0  0x80400000 0x00008000   /* Port 0 downstream I/O */
> > 			  0 4 0  0x90000000 0x08000000   /* Port 0 non-prefetchable memory */
> > 			  0 5 0  0xa0000000 0x08000000   /* Port 0 prefetchable memory */
> > 
> > 			  1 0 0  0x80001000 0x00001000   /* Root port 1 */
> > 			  1 1 0  0x80004000 0x00080000   /* Port 1 config space */
> > 			  1 2 0  0x80184000 0x00080000   /* Port 1 ext config space */
> > 			  1 3 0  0x80408000 0x00010000   /* Port 1 downstream I/O */
> > 			  1 4 0  0x98000000 0x08000000   /* Port 1 non-prefetchable memory */
> > 			  1 5 0  0xa0000000 0x08000000>; /* Port 1 prefetchable memory */
> > 
> > 		#address-cells = <3>;
> > 		#size-cells = <1>;
> > 
> > 		pci@0 {
> > 			reg = <0 0 0 0x1000>;
> [...]
> > 		};
> > 
> > 		pci@1 {
> > 			reg = <1 0 0 0x1000>;
> [...]
> > 		};
> 
> It seems like this isn't working properly. For some reason both the reg
> property of pci@0 and pci@1 are translated to the same parent address
> 0x80000000. I'll have to investigate where exactly this goes wrong.

So it turns out that while of_read_number() can actually read any number
of cells, only the two least significant are kept because it returns a
u64. Since of_bus_default_map() uses of_read_number() the addresses
<0 0 0> and <1 0 0> are in fact the same. I'm not sure how best to solve
this. I'm not aware of a 128 bit integer type in the kernel, so I guess
the better alternative would be to fix of_bus_default_map() to cope with
#address-cells > 2 properly.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-22 13:22                                                                       ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-22 13:22 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jun 22, 2012 at 01:04:03PM +0200, Thierry Reding wrote:
> On Tue, Jun 19, 2012 at 11:31:39AM -1000, Mitch Bradley wrote:
> > On 6/19/2012 3:30 AM, Thierry Reding wrote:
> > >On Fri, Jun 15, 2012 at 08:12:36AM +0200, Thierry Reding wrote:
> > >>On Thu, Jun 14, 2012 at 01:50:56PM -0600, Stephen Warren wrote:
> > >>>On 06/14/2012 01:29 PM, Thierry Reding wrote:
> > >>>>On Thu, Jun 14, 2012 at 12:30:50PM -0600, Stephen Warren wrote:
> > >>>>>On 06/14/2012 03:19 AM, Thierry Reding wrote:
> > >>>...
> > >>>>>>#address-cells = <1>; #size-cells = <1>;
> > >>>>>>
> > >>>>>>pci at 80000000 {
> > >>>>>
> > >>>>>I'm still not convinced that using the address of the port's
> > >>>>>registers is the correct way to represent each port. The port
> > >>>>>index seems much more useful.
> > >>>>>
> > >>>>>The main reason here is that there are a lot of registers that
> > >>>>>contain fields for each port - far more than the combination of
> > >>>>>this node's reg and ctrl-offset (which I assume is an address
> > >>>>>offset for just one example of this issue) properties can
> > >>>>>describe. The bit position and bit stride of these fields isn't
> > >>>>>necessarily the same in each register. Do we want a property like
> > >>>>>ctrl-offset for every single type of field in every single shared
> > >>>>>register that describes the location of the relevant data, or
> > >>>>>just a single "port ID" bit that can be applied to anything?
> > >>>>>
> > >>>>>(Perhaps this isn't so obvious looking at the TRM since it
> > >>>>>doesn't document all registers, and I'm also looking at the
> > >>>>>Tegra30 documentation too, which might be more exposed to this -
> > >>>>>I haven't correlated all the documentation sources to be sure
> > >>>>>though)
> > >>>>
> > >>>>I agree that maybe adding properties for each bit position or
> > >>>>register offset may not work out too well. But I think it still
> > >>>>makes sense to use the base address of the port's registers (see
> > >>>>below). We could of course add some code to determine the index
> > >>>>from the base address at initialization time and reuse the index
> > >>>>where appropriate.
> > >>>
> > >>>To me, working back from address to ID then using the ID to calculate
> > >>>some other addresses seems far more icky than just calculating all the
> > >>>addresses based off of one ID. But, I suppose this doesn't make a huge
> > >>>practical difference.
> > >>
> > >>This really depends on the device vs. no device decision below. If we can
> > >>make it work without needing an extra device for it, then using the index
> > >>is certainly better. However, if we instantiate devices from the DT, then
> > >>we have the address anyway and adding the index as a property would be
> > >>redundant and error prone (what happens if somebody sets the index of the
> > >>port at address 0x80000000 to 2?).
> > >
> > >An additional problem with this is that we'd have to add the following
> > >to the pcie-controller node:
> > >
> > >	#address-cells = <1>;
> > >	#size-cells = <0>;
> > >
> > >This will conflict with the "ranges" property, because suddenly we can
> > >no longer map the regions properly. Maybe Mitch can comment on whether
> > >this is possible or not?
> > >
> > >To make it clearer what I'm talking about, here's the DT snippet again
> > >(with the compatible property removed from the pci@ nodes because they
> > >are no longer probed by a driver, the "simple-bus" removed from the
> > >pcie-controller node's compatible property removed and its #address-
> > >and #size-cells properties adjusted as described above).
> > >
> > >	pcie-controller {
> > >		compatible = "nvidia,tegra20-pcie";
> > >		reg = <0x80003000 0x00000800   /* PADS registers */
> > >		       0x80003800 0x00000200   /* AFI registers */
> > >		       0x80004000 0x00100000   /* configuration space */
> > >		       0x80104000 0x00100000>; /* extended configuration space */
> > >		interrupts = <0 98 0x04   /* controller interrupt */
> > >			      0 99 0x04>; /* MSI interrupt */
> > >		status = "disabled";
> > >
> > >		ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */
> > >			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
> > >			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
> > >			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
> > >
> > >		#address-cells = <1>;
> > >		#size-cells = <0>;
> > >
> > >		pci at 0 {
> > >			reg = <2>;
> > >			status = "disabled";
> > >
> > >			#address-cells = <3>;
> > >			#size-cells = <2>;
> > >
> > >			ranges = <0x81000000 0 0 0x80400000 0 0x00008000   /* I/O */
> > >				  0x82000000 0 0 0x90000000 0 0x08000000   /* non-prefetchable memory */
> > >				  0xc2000000 0 0 0xa0000000 0 0x08000000>; /* prefetchable memory */
> > >
> > >			nvidia,ctrl-offset = <0x110>;
> > >			nvidia,num-lanes = <2>;
> > >		};
> > >
> > >		pci at 1 {
> > >			reg = <1>;
> > >			status = "disabled";
> > >
> > >			#address-cells = <3>;
> > >			#size-cells = <2>;
> > >
> > >			ranges = <0x81000000 0 0 0x80408000 0 0x00008000   /* I/O */
> > >				  0x82000000 0 0 0x98000000 0 0x08000000   /* non-prefetchable memory */
> > >				  0xc2000000 0 0 0xa8000000 0 0x08000000>; /* prefetchable memory */
> > >
> > >			nvidia,ctrl-offset = <0x118>;
> > >			nvidia,num-lanes = <2>;
> > >		};
> > >	};
> > >
> > >AIUI none of the ranges properties are valid anymore, because the bus
> > >represented by pcie-controller no longer reflects the truth, namely that
> > >it translates the CPU address space to the PCI address space.
> > >
> > 
> > I think you can use a small-integer port number as an address by
> > defining the intermediate address space properly, and using
> > appropriate ranges above and below.  Here's a swag at how that would
> > look.
> > 
> > I present three versions, using different choices for the
> > intermediate address space encoding.  The intermediate address space
> > may seem somewhat artificial, in that it decouples the "linear pass
> > through of ranges" between the lower PCI address space and the upper
> > CPU address space.  But in another sense, it accurately reflects
> > that fact that the bus bridge "slices and dices" that linear address
> > space into non-contiguous pieces.
> > 
> > Note that I'm also fixing a problem that I neglected to mention
> > earlier - namely the fact that config space is part of the child PCI
> > address space so it must be passed through.
> > 
> > Version A - 3 address cells:  In this version, the intermediate
> > address space has 3 cells:  port#, address type, offset.  Address
> > type is
> >   0 : root port
> >   1 : config space
> >   2 : extended config space
> >   3 : I/O
> >   4 : non-prefetchable memory
> >   5 : prefetchable memory.
> > 
> > The third cell "offset" is necessary so that the size field has a
> > number space that can include it.
> > 
> > 	pcie-controller {
> > 		compatible = "nvidia,tegra20-pcie";
> > 		reg = <0x80003000 0x00000800   /* PADS registers */
> > 		       0x80003800 0x00000200>; /* extended configuration space */
> > 		interrupts = <0 98 0x04   /* controller interrupt */
> > 			      0 99 0x04>; /* MSI interrupt */
> > 		status = "disabled";
> > 
> > 		ranges = <0 0 0  0x80000000 0x00001000   /* Root port 0 */
> > 			  0 1 0  0x80004000 0x00080000   /* Port 0 config space */
> > 			  0 2 0  0x80104000 0x00080000   /* Port 0 ext config space *
> > 			  0 3 0  0x80400000 0x00008000   /* Port 0 downstream I/O */
> > 			  0 4 0  0x90000000 0x08000000   /* Port 0 non-prefetchable memory */
> > 			  0 5 0  0xa0000000 0x08000000   /* Port 0 prefetchable memory */
> > 
> > 			  1 0 0  0x80001000 0x00001000   /* Root port 1 */
> > 			  1 1 0  0x80004000 0x00080000   /* Port 1 config space */
> > 			  1 2 0  0x80184000 0x00080000   /* Port 1 ext config space */
> > 			  1 3 0  0x80408000 0x00010000   /* Port 1 downstream I/O */
> > 			  1 4 0  0x98000000 0x08000000   /* Port 1 non-prefetchable memory */
> > 			  1 5 0  0xa0000000 0x08000000>; /* Port 1 prefetchable memory */
> > 
> > 		#address-cells = <3>;
> > 		#size-cells = <1>;
> > 
> > 		pci at 0 {
> > 			reg = <0 0 0 0x1000>;
> [...]
> > 		};
> > 
> > 		pci at 1 {
> > 			reg = <1 0 0 0x1000>;
> [...]
> > 		};
> 
> It seems like this isn't working properly. For some reason both the reg
> property of pci at 0 and pci at 1 are translated to the same parent address
> 0x80000000. I'll have to investigate where exactly this goes wrong.

So it turns out that while of_read_number() can actually read any number
of cells, only the two least significant are kept because it returns a
u64. Since of_bus_default_map() uses of_read_number() the addresses
<0 0 0> and <1 0 0> are in fact the same. I'm not sure how best to solve
this. I'm not aware of a 128 bit integer type in the kernel, so I guess
the better alternative would be to fix of_bus_default_map() to cope with
#address-cells > 2 properly.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120622/ce370014/attachment.sig>

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-22 13:22                                                                       ` Thierry Reding
  (?)
@ 2012-06-22 13:48                                                                           ` Arnd Bergmann
  -1 siblings, 0 replies; 249+ messages in thread
From: Arnd Bergmann @ 2012-06-22 13:48 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Mitch Bradley, Stephen Warren, Russell King,
	linux-pci-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Jesse Barnes, Colin Cross, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Friday 22 June 2012, Thierry Reding wrote:
> > It seems like this isn't working properly. For some reason both the reg
> > property of pci@0 and pci@1 are translated to the same parent address
> > 0x80000000. I'll have to investigate where exactly this goes wrong.
> 
> So it turns out that while of_read_number() can actually read any number
> of cells, only the two least significant are kept because it returns a
> u64. Since of_bus_default_map() uses of_read_number() the addresses
> <0 0 0> and <1 0 0> are in fact the same. I'm not sure how best to solve
> this. I'm not aware of a 128 bit integer type in the kernel, so I guess
> the better alternative would be to fix of_bus_default_map() to cope with
> #address-cells > 2 properly.

of_translate_address should get it right. Which codes uses of_read_number()?
Can it be converted to use of_translate_address()?

	Arnd

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-22 13:48                                                                           ` Arnd Bergmann
  0 siblings, 0 replies; 249+ messages in thread
From: Arnd Bergmann @ 2012-06-22 13:48 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Mitch Bradley, Stephen Warren, Russell King, linux-pci,
	devicetree-discuss, Rob Herring, Jesse Barnes, Colin Cross,
	linux-tegra, linux-arm-kernel

On Friday 22 June 2012, Thierry Reding wrote:
> > It seems like this isn't working properly. For some reason both the reg
> > property of pci@0 and pci@1 are translated to the same parent address
> > 0x80000000. I'll have to investigate where exactly this goes wrong.
> 
> So it turns out that while of_read_number() can actually read any number
> of cells, only the two least significant are kept because it returns a
> u64. Since of_bus_default_map() uses of_read_number() the addresses
> <0 0 0> and <1 0 0> are in fact the same. I'm not sure how best to solve
> this. I'm not aware of a 128 bit integer type in the kernel, so I guess
> the better alternative would be to fix of_bus_default_map() to cope with
> #address-cells > 2 properly.

of_translate_address should get it right. Which codes uses of_read_number()?
Can it be converted to use of_translate_address()?

	Arnd

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-22 13:48                                                                           ` Arnd Bergmann
  0 siblings, 0 replies; 249+ messages in thread
From: Arnd Bergmann @ 2012-06-22 13:48 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 22 June 2012, Thierry Reding wrote:
> > It seems like this isn't working properly. For some reason both the reg
> > property of pci at 0 and pci at 1 are translated to the same parent address
> > 0x80000000. I'll have to investigate where exactly this goes wrong.
> 
> So it turns out that while of_read_number() can actually read any number
> of cells, only the two least significant are kept because it returns a
> u64. Since of_bus_default_map() uses of_read_number() the addresses
> <0 0 0> and <1 0 0> are in fact the same. I'm not sure how best to solve
> this. I'm not aware of a 128 bit integer type in the kernel, so I guess
> the better alternative would be to fix of_bus_default_map() to cope with
> #address-cells > 2 properly.

of_translate_address should get it right. Which codes uses of_read_number()?
Can it be converted to use of_translate_address()?

	Arnd

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-22 13:48                                                                           ` Arnd Bergmann
  (?)
@ 2012-06-22 14:02                                                                               ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-22 14:02 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Mitch Bradley, Stephen Warren, Russell King,
	linux-pci-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Jesse Barnes, Colin Cross, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

[-- Attachment #1: Type: text/plain, Size: 1296 bytes --]

On Fri, Jun 22, 2012 at 01:48:39PM +0000, Arnd Bergmann wrote:
> On Friday 22 June 2012, Thierry Reding wrote:
> > > It seems like this isn't working properly. For some reason both the reg
> > > property of pci@0 and pci@1 are translated to the same parent address
> > > 0x80000000. I'll have to investigate where exactly this goes wrong.
> > 
> > So it turns out that while of_read_number() can actually read any number
> > of cells, only the two least significant are kept because it returns a
> > u64. Since of_bus_default_map() uses of_read_number() the addresses
> > <0 0 0> and <1 0 0> are in fact the same. I'm not sure how best to solve
> > this. I'm not aware of a 128 bit integer type in the kernel, so I guess
> > the better alternative would be to fix of_bus_default_map() to cope with
> > #address-cells > 2 properly.
> 
> of_translate_address should get it right. Which codes uses of_read_number()?
> Can it be converted to use of_translate_address()?

Actually this is from of_translate_address(). The calling sequence looks
like this:

	of_address_to_resource()
	  __of_address_to_resource()
	    of_translate_address()
	      __of_translate_address()
	        of_translate_one()
	          of_bus_default_map()
	            of_read_number()

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-22 14:02                                                                               ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-22 14:02 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Mitch Bradley, Stephen Warren, Russell King, linux-pci,
	devicetree-discuss, Rob Herring, Jesse Barnes, Colin Cross,
	linux-tegra, linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 1296 bytes --]

On Fri, Jun 22, 2012 at 01:48:39PM +0000, Arnd Bergmann wrote:
> On Friday 22 June 2012, Thierry Reding wrote:
> > > It seems like this isn't working properly. For some reason both the reg
> > > property of pci@0 and pci@1 are translated to the same parent address
> > > 0x80000000. I'll have to investigate where exactly this goes wrong.
> > 
> > So it turns out that while of_read_number() can actually read any number
> > of cells, only the two least significant are kept because it returns a
> > u64. Since of_bus_default_map() uses of_read_number() the addresses
> > <0 0 0> and <1 0 0> are in fact the same. I'm not sure how best to solve
> > this. I'm not aware of a 128 bit integer type in the kernel, so I guess
> > the better alternative would be to fix of_bus_default_map() to cope with
> > #address-cells > 2 properly.
> 
> of_translate_address should get it right. Which codes uses of_read_number()?
> Can it be converted to use of_translate_address()?

Actually this is from of_translate_address(). The calling sequence looks
like this:

	of_address_to_resource()
	  __of_address_to_resource()
	    of_translate_address()
	      __of_translate_address()
	        of_translate_one()
	          of_bus_default_map()
	            of_read_number()

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-22 14:02                                                                               ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-22 14:02 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jun 22, 2012 at 01:48:39PM +0000, Arnd Bergmann wrote:
> On Friday 22 June 2012, Thierry Reding wrote:
> > > It seems like this isn't working properly. For some reason both the reg
> > > property of pci at 0 and pci at 1 are translated to the same parent address
> > > 0x80000000. I'll have to investigate where exactly this goes wrong.
> > 
> > So it turns out that while of_read_number() can actually read any number
> > of cells, only the two least significant are kept because it returns a
> > u64. Since of_bus_default_map() uses of_read_number() the addresses
> > <0 0 0> and <1 0 0> are in fact the same. I'm not sure how best to solve
> > this. I'm not aware of a 128 bit integer type in the kernel, so I guess
> > the better alternative would be to fix of_bus_default_map() to cope with
> > #address-cells > 2 properly.
> 
> of_translate_address should get it right. Which codes uses of_read_number()?
> Can it be converted to use of_translate_address()?

Actually this is from of_translate_address(). The calling sequence looks
like this:

	of_address_to_resource()
	  __of_address_to_resource()
	    of_translate_address()
	      __of_translate_address()
	        of_translate_one()
	          of_bus_default_map()
	            of_read_number()

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120622/96546a0c/attachment.sig>

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-21  6:47                                                                   ` Thierry Reding
  (?)
@ 2012-06-22 16:20                                                                       ` Stephen Warren
  -1 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-22 16:20 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Mitch Bradley, Russell King, linux-pci-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Jesse Barnes, Colin Cross, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Arnd Bergmann

On 06/21/2012 12:47 AM, Thierry Reding wrote:
...
> Everybody seems to be happy with this approach, so I'll give it a
> shot. There is one thing I'm still unsure about, though. What if
> somebody uses the above scheme and maps the registers to the wrong
> port. The same goes for the nvidia,ctrl-offset property. It needs
> to match the register offset because they are directly related. I
> suppose we could leave that property away and look up the register
> via the port index (which, as Stephen already said, we'll have to
> do in other places anyway, unless we list all bit positions in the
> DT).
> 
> Can we safely ignore such issues and assume the device tree to
> always be right? Should we just not care if somebody uses it
> wrongly?

I think that's pretty much the same thing as plain putting the wrong
reg property into any node - the value is wrong, so it doesn't work.
There's not too much you can do about it.

I'd be happy to remove the nvidia,ctrl-offset property to avoid the
need to specify basically the same information multiple times though;
nothing wrong with making it easier to write the correct DT content.

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-22 16:20                                                                       ` Stephen Warren
  0 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-22 16:20 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Mitch Bradley, Russell King, linux-pci, devicetree-discuss,
	Rob Herring, Jesse Barnes, Colin Cross, linux-tegra,
	linux-arm-kernel, Arnd Bergmann

On 06/21/2012 12:47 AM, Thierry Reding wrote:
...
> Everybody seems to be happy with this approach, so I'll give it a
> shot. There is one thing I'm still unsure about, though. What if
> somebody uses the above scheme and maps the registers to the wrong
> port. The same goes for the nvidia,ctrl-offset property. It needs
> to match the register offset because they are directly related. I
> suppose we could leave that property away and look up the register
> via the port index (which, as Stephen already said, we'll have to
> do in other places anyway, unless we list all bit positions in the
> DT).
> 
> Can we safely ignore such issues and assume the device tree to
> always be right? Should we just not care if somebody uses it
> wrongly?

I think that's pretty much the same thing as plain putting the wrong
reg property into any node - the value is wrong, so it doesn't work.
There's not too much you can do about it.

I'd be happy to remove the nvidia,ctrl-offset property to avoid the
need to specify basically the same information multiple times though;
nothing wrong with making it easier to write the correct DT content.

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-22 16:20                                                                       ` Stephen Warren
  0 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-22 16:20 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/21/2012 12:47 AM, Thierry Reding wrote:
...
> Everybody seems to be happy with this approach, so I'll give it a
> shot. There is one thing I'm still unsure about, though. What if
> somebody uses the above scheme and maps the registers to the wrong
> port. The same goes for the nvidia,ctrl-offset property. It needs
> to match the register offset because they are directly related. I
> suppose we could leave that property away and look up the register
> via the port index (which, as Stephen already said, we'll have to
> do in other places anyway, unless we list all bit positions in the
> DT).
> 
> Can we safely ignore such issues and assume the device tree to
> always be right? Should we just not care if somebody uses it
> wrongly?

I think that's pretty much the same thing as plain putting the wrong
reg property into any node - the value is wrong, so it doesn't work.
There's not too much you can do about it.

I'd be happy to remove the nvidia,ctrl-offset property to avoid the
need to specify basically the same information multiple times though;
nothing wrong with making it easier to write the correct DT content.

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-22 14:02                                                                               ` Thierry Reding
  (?)
@ 2012-06-22 16:40                                                                                   ` Arnd Bergmann
  -1 siblings, 0 replies; 249+ messages in thread
From: Arnd Bergmann @ 2012-06-22 16:40 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Russell King, linux-pci-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jesse Barnes, Colin Cross,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Friday 22 June 2012, Thierry Reding wrote:
> Actually this is from of_translate_address(). The calling sequence looks
> like this:
> 
>         of_address_to_resource()
>           __of_address_to_resource()
>             of_translate_address()
>               __of_translate_address()
>                 of_translate_one()
>                   of_bus_default_map()
>                     of_read_number()

Ok, I see.

This looks like a problem in of_bus_default_map, which expects to
see only 64 bit addresses at most. of_bus_pci_map by comparison
handles the pci addresses with three cells.

If I read this correctly, this fix is to make sure we compare the
upper cells of the address in of_bus_default_map:

static u64 of_bus_default_map(u32 *addr, const __be32 *range,
                int na, int ns, int pna)
{
        u64 cp, s, da;

        cp = of_read_number(range, na);
        s  = of_read_number(range + na + pna, ns);
        da = of_read_number(addr, na);

        pr_debug("OF: default map, cp=%llx, s=%llx, da=%llx\n",
                 (unsigned long long)cp, (unsigned long long)s,
                 (unsigned long long)da);

        if (da < cp || da >= (cp + s))
                return OF_BAD_ADDR;
        return da - cp;
}

How about adding code like:

	if ((na > 2) && memcmp(range, addr, na * 4) != 0)
		return OF_BAD_ADDR;

This won't handle entries with #size-cells>2 or those that
span a 64-bit boundary, but I think it will work for all
relevant cases.

	Arnd

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-22 16:40                                                                                   ` Arnd Bergmann
  0 siblings, 0 replies; 249+ messages in thread
From: Arnd Bergmann @ 2012-06-22 16:40 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Mitch Bradley, Stephen Warren, Russell King, linux-pci,
	devicetree-discuss, Rob Herring, Jesse Barnes, Colin Cross,
	linux-tegra, linux-arm-kernel

On Friday 22 June 2012, Thierry Reding wrote:
> Actually this is from of_translate_address(). The calling sequence looks
> like this:
> 
>         of_address_to_resource()
>           __of_address_to_resource()
>             of_translate_address()
>               __of_translate_address()
>                 of_translate_one()
>                   of_bus_default_map()
>                     of_read_number()

Ok, I see.

This looks like a problem in of_bus_default_map, which expects to
see only 64 bit addresses at most. of_bus_pci_map by comparison
handles the pci addresses with three cells.

If I read this correctly, this fix is to make sure we compare the
upper cells of the address in of_bus_default_map:

static u64 of_bus_default_map(u32 *addr, const __be32 *range,
                int na, int ns, int pna)
{
        u64 cp, s, da;

        cp = of_read_number(range, na);
        s  = of_read_number(range + na + pna, ns);
        da = of_read_number(addr, na);

        pr_debug("OF: default map, cp=%llx, s=%llx, da=%llx\n",
                 (unsigned long long)cp, (unsigned long long)s,
                 (unsigned long long)da);

        if (da < cp || da >= (cp + s))
                return OF_BAD_ADDR;
        return da - cp;
}

How about adding code like:

	if ((na > 2) && memcmp(range, addr, na * 4) != 0)
		return OF_BAD_ADDR;

This won't handle entries with #size-cells>2 or those that
span a 64-bit boundary, but I think it will work for all
relevant cases.

	Arnd

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-22 16:40                                                                                   ` Arnd Bergmann
  0 siblings, 0 replies; 249+ messages in thread
From: Arnd Bergmann @ 2012-06-22 16:40 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 22 June 2012, Thierry Reding wrote:
> Actually this is from of_translate_address(). The calling sequence looks
> like this:
> 
>         of_address_to_resource()
>           __of_address_to_resource()
>             of_translate_address()
>               __of_translate_address()
>                 of_translate_one()
>                   of_bus_default_map()
>                     of_read_number()

Ok, I see.

This looks like a problem in of_bus_default_map, which expects to
see only 64 bit addresses at most. of_bus_pci_map by comparison
handles the pci addresses with three cells.

If I read this correctly, this fix is to make sure we compare the
upper cells of the address in of_bus_default_map:

static u64 of_bus_default_map(u32 *addr, const __be32 *range,
                int na, int ns, int pna)
{
        u64 cp, s, da;

        cp = of_read_number(range, na);
        s  = of_read_number(range + na + pna, ns);
        da = of_read_number(addr, na);

        pr_debug("OF: default map, cp=%llx, s=%llx, da=%llx\n",
                 (unsigned long long)cp, (unsigned long long)s,
                 (unsigned long long)da);

        if (da < cp || da >= (cp + s))
                return OF_BAD_ADDR;
        return da - cp;
}

How about adding code like:

	if ((na > 2) && memcmp(range, addr, na * 4) != 0)
		return OF_BAD_ADDR;

This won't handle entries with #size-cells>2 or those that
span a 64-bit boundary, but I think it will work for all
relevant cases.

	Arnd

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-22 13:03                                                                                 ` Arnd Bergmann
  (?)
@ 2012-06-22 16:49                                                                                     ` Bjorn Helgaas
  -1 siblings, 0 replies; 249+ messages in thread
From: Bjorn Helgaas @ 2012-06-22 16:49 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Thierry Reding, Mitch Bradley, Stephen Warren, Russell King,
	linux-pci-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Jesse Barnes, Colin Cross, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Yinghai Lu

On Fri, Jun 22, 2012 at 7:03 AM, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
> On Friday 22 June 2012, Thierry Reding wrote:
>> On Fri, Jun 22, 2012 at 05:46:52AM -0600, Bjorn Helgaas wrote:
>> > On Fri, Jun 22, 2012 at 5:00 AM, Thierry Reding
>> > <thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org> wrote:
>> > >> Is the bus number aperture included somewhere?  How do we know what
>> > >> bus numbers are available for allocation under each bridge?
>> > >
>> > > Not yet. I don't think DT imposes a bus number allocation on PCI
>> > > bridges. However the matching of DT nodes to PCI bridges is done based
>> > > on the bus number. For that you provide a bus-ranges property which
>> > > defines the bus aperture of the given PCI bridge. The DT matching code
>> > > compares the first cell of this property with the primary bus number of
>> > > the bridge.
>> >
>> > I don't fully understand this, but I can tell you that things don't
>> > work very well if we don't know the aperture.  We can make
>> > assumptions, like the root bus is 00, and then enumerate everything
>> > reachable from there.  But then all we know is the largest bus number
>> > actually reachable from bus 00, which is usually smaller then the end
>> > of the aperture.  We don't know how many unused bus numbers there are
>> > in the aperture, so we can't safely allocate any for hot-added
>> > devices.
>
> I believe the assumption today is that all bus numbers are ok on each
> root port, which is usually the case. There was something about a Power
> Mac that faked a single PCI bus number space across both an AGP and
> a PCIe domain in pmac_pci_fixup_u4_of_node(), but I think that is the
> exception.
>
> Is there any requirement to use a bus aperture on non-PC hardware?

The requirement (if there is one) isn't anything related to PC-ness.
I just don't understand how things can actually work if two host
bridges both claim the same bus number.  If we do a config read to
that bus, both bridges should claim it and turn it into config cycles
on their respective root buses, and we should get two responses.  I
would expect the second response to cause an "unexpected response"
machine check or similar.

Beyond that, Yinghai's recent "busn-alloc" work (now in my -next
branch) tracks bus number assignments using a struct resource tree,
and that obviously won't work with overlaps.  Here's one of the
relevant commits:
http://git.kernel.org/?p=linux/kernel/git/helgaas/pci.git;a=commitdiff;h=5cc62c202211096ec26309722ec27455d52c8726

>> I think DT support for PCI is lacking in a lot of areas. PowerPC seems
>> to be the only architecture actively setting up busses according to the
>> bus-range property specified in the DT. All other architectures seem to
>> not pre-allocate bus apertures and go with the default instead. From
>> what you say that means hot-plugging is out. Although I don't think the
>> Tegra PCIe controller even supports hot-plugging.
>
> If the default is allowing any bus numbers, and that matches the
> hardware capabilities, I think hot-plugging would work.
>
>        Arnd

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-22 16:49                                                                                     ` Bjorn Helgaas
  0 siblings, 0 replies; 249+ messages in thread
From: Bjorn Helgaas @ 2012-06-22 16:49 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Thierry Reding, Mitch Bradley, Stephen Warren, Russell King,
	linux-pci, devicetree-discuss, Rob Herring, Jesse Barnes,
	Colin Cross, linux-tegra, linux-arm-kernel, Yinghai Lu

On Fri, Jun 22, 2012 at 7:03 AM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Friday 22 June 2012, Thierry Reding wrote:
>> On Fri, Jun 22, 2012 at 05:46:52AM -0600, Bjorn Helgaas wrote:
>> > On Fri, Jun 22, 2012 at 5:00 AM, Thierry Reding
>> > <thierry.reding@avionic-design.de> wrote:
>> > >> Is the bus number aperture included somewhere?  How do we know what
>> > >> bus numbers are available for allocation under each bridge?
>> > >
>> > > Not yet. I don't think DT imposes a bus number allocation on PCI
>> > > bridges. However the matching of DT nodes to PCI bridges is done based
>> > > on the bus number. For that you provide a bus-ranges property which
>> > > defines the bus aperture of the given PCI bridge. The DT matching code
>> > > compares the first cell of this property with the primary bus number of
>> > > the bridge.
>> >
>> > I don't fully understand this, but I can tell you that things don't
>> > work very well if we don't know the aperture.  We can make
>> > assumptions, like the root bus is 00, and then enumerate everything
>> > reachable from there.  But then all we know is the largest bus number
>> > actually reachable from bus 00, which is usually smaller then the end
>> > of the aperture.  We don't know how many unused bus numbers there are
>> > in the aperture, so we can't safely allocate any for hot-added
>> > devices.
>
> I believe the assumption today is that all bus numbers are ok on each
> root port, which is usually the case. There was something about a Power
> Mac that faked a single PCI bus number space across both an AGP and
> a PCIe domain in pmac_pci_fixup_u4_of_node(), but I think that is the
> exception.
>
> Is there any requirement to use a bus aperture on non-PC hardware?

The requirement (if there is one) isn't anything related to PC-ness.
I just don't understand how things can actually work if two host
bridges both claim the same bus number.  If we do a config read to
that bus, both bridges should claim it and turn it into config cycles
on their respective root buses, and we should get two responses.  I
would expect the second response to cause an "unexpected response"
machine check or similar.

Beyond that, Yinghai's recent "busn-alloc" work (now in my -next
branch) tracks bus number assignments using a struct resource tree,
and that obviously won't work with overlaps.  Here's one of the
relevant commits:
http://git.kernel.org/?p=linux/kernel/git/helgaas/pci.git;a=commitdiff;h=5cc62c202211096ec26309722ec27455d52c8726

>> I think DT support for PCI is lacking in a lot of areas. PowerPC seems
>> to be the only architecture actively setting up busses according to the
>> bus-range property specified in the DT. All other architectures seem to
>> not pre-allocate bus apertures and go with the default instead. From
>> what you say that means hot-plugging is out. Although I don't think the
>> Tegra PCIe controller even supports hot-plugging.
>
> If the default is allowing any bus numbers, and that matches the
> hardware capabilities, I think hot-plugging would work.
>
>        Arnd

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-22 16:49                                                                                     ` Bjorn Helgaas
  0 siblings, 0 replies; 249+ messages in thread
From: Bjorn Helgaas @ 2012-06-22 16:49 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jun 22, 2012 at 7:03 AM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Friday 22 June 2012, Thierry Reding wrote:
>> On Fri, Jun 22, 2012 at 05:46:52AM -0600, Bjorn Helgaas wrote:
>> > On Fri, Jun 22, 2012 at 5:00 AM, Thierry Reding
>> > <thierry.reding@avionic-design.de> wrote:
>> > >> Is the bus number aperture included somewhere? ?How do we know what
>> > >> bus numbers are available for allocation under each bridge?
>> > >
>> > > Not yet. I don't think DT imposes a bus number allocation on PCI
>> > > bridges. However the matching of DT nodes to PCI bridges is done based
>> > > on the bus number. For that you provide a bus-ranges property which
>> > > defines the bus aperture of the given PCI bridge. The DT matching code
>> > > compares the first cell of this property with the primary bus number of
>> > > the bridge.
>> >
>> > I don't fully understand this, but I can tell you that things don't
>> > work very well if we don't know the aperture. ?We can make
>> > assumptions, like the root bus is 00, and then enumerate everything
>> > reachable from there. ?But then all we know is the largest bus number
>> > actually reachable from bus 00, which is usually smaller then the end
>> > of the aperture. ?We don't know how many unused bus numbers there are
>> > in the aperture, so we can't safely allocate any for hot-added
>> > devices.
>
> I believe the assumption today is that all bus numbers are ok on each
> root port, which is usually the case. There was something about a Power
> Mac that faked a single PCI bus number space across both an AGP and
> a PCIe domain in pmac_pci_fixup_u4_of_node(), but I think that is the
> exception.
>
> Is there any requirement to use a bus aperture on non-PC hardware?

The requirement (if there is one) isn't anything related to PC-ness.
I just don't understand how things can actually work if two host
bridges both claim the same bus number.  If we do a config read to
that bus, both bridges should claim it and turn it into config cycles
on their respective root buses, and we should get two responses.  I
would expect the second response to cause an "unexpected response"
machine check or similar.

Beyond that, Yinghai's recent "busn-alloc" work (now in my -next
branch) tracks bus number assignments using a struct resource tree,
and that obviously won't work with overlaps.  Here's one of the
relevant commits:
http://git.kernel.org/?p=linux/kernel/git/helgaas/pci.git;a=commitdiff;h=5cc62c202211096ec26309722ec27455d52c8726

>> I think DT support for PCI is lacking in a lot of areas. PowerPC seems
>> to be the only architecture actively setting up busses according to the
>> bus-range property specified in the DT. All other architectures seem to
>> not pre-allocate bus apertures and go with the default instead. From
>> what you say that means hot-plugging is out. Although I don't think the
>> Tegra PCIe controller even supports hot-plugging.
>
> If the default is allowing any bus numbers, and that matches the
> hardware capabilities, I think hot-plugging would work.
>
> ? ? ? ?Arnd

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-22 16:49                                                                                     ` Bjorn Helgaas
  (?)
@ 2012-06-22 16:53                                                                                         ` Arnd Bergmann
  -1 siblings, 0 replies; 249+ messages in thread
From: Arnd Bergmann @ 2012-06-22 16:53 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Thierry Reding, Mitch Bradley, Stephen Warren, Russell King,
	linux-pci-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Jesse Barnes, Colin Cross, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Yinghai Lu

On Friday 22 June 2012, Bjorn Helgaas wrote:
> The requirement (if there is one) isn't anything related to PC-ness.
> I just don't understand how things can actually work if two host
> bridges both claim the same bus number.  If we do a config read to
> that bus, both bridges should claim it and turn it into config cycles
> on their respective root buses, and we should get two responses.  I
> would expect the second response to cause an "unexpected response"
> machine check or similar.

But each PCI domain has its own config space, so if you do a config
read for one bus, it's always relative to the domain.

The part that is specific to PCs is that they don't have PCI domains
normally.

	Arnd

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-22 16:53                                                                                         ` Arnd Bergmann
  0 siblings, 0 replies; 249+ messages in thread
From: Arnd Bergmann @ 2012-06-22 16:53 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Thierry Reding, Mitch Bradley, Stephen Warren, Russell King,
	linux-pci, devicetree-discuss, Rob Herring, Jesse Barnes,
	Colin Cross, linux-tegra, linux-arm-kernel, Yinghai Lu

On Friday 22 June 2012, Bjorn Helgaas wrote:
> The requirement (if there is one) isn't anything related to PC-ness.
> I just don't understand how things can actually work if two host
> bridges both claim the same bus number.  If we do a config read to
> that bus, both bridges should claim it and turn it into config cycles
> on their respective root buses, and we should get two responses.  I
> would expect the second response to cause an "unexpected response"
> machine check or similar.

But each PCI domain has its own config space, so if you do a config
read for one bus, it's always relative to the domain.

The part that is specific to PCs is that they don't have PCI domains
normally.

	Arnd

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-22 16:53                                                                                         ` Arnd Bergmann
  0 siblings, 0 replies; 249+ messages in thread
From: Arnd Bergmann @ 2012-06-22 16:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 22 June 2012, Bjorn Helgaas wrote:
> The requirement (if there is one) isn't anything related to PC-ness.
> I just don't understand how things can actually work if two host
> bridges both claim the same bus number.  If we do a config read to
> that bus, both bridges should claim it and turn it into config cycles
> on their respective root buses, and we should get two responses.  I
> would expect the second response to cause an "unexpected response"
> machine check or similar.

But each PCI domain has its own config space, so if you do a config
read for one bus, it's always relative to the domain.

The part that is specific to PCs is that they don't have PCI domains
normally.

	Arnd

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-22 11:00                                                                           ` Thierry Reding
@ 2012-06-22 17:00                                                                             ` Stephen Warren
  -1 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-22 17:00 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Bjorn Helgaas, Mitch Bradley, Russell King, linux-pci,
	devicetree-discuss, Rob Herring, Jesse Barnes, Colin Cross,
	linux-tegra, linux-arm-kernel, Arnd Bergmann

On 06/22/2012 05:00 AM, Thierry Reding wrote:
...
> Stephen: can you try to find out whether the Tegra PCIe controller 
> indeed implements ECAM, or if this scheme is actually just a
> proprietary variant?

Sure. I have added this request to the bug I filed requesting more
complete PCIe host documentation.

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-22 17:00                                                                             ` Stephen Warren
  0 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-22 17:00 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/22/2012 05:00 AM, Thierry Reding wrote:
...
> Stephen: can you try to find out whether the Tegra PCIe controller 
> indeed implements ECAM, or if this scheme is actually just a
> proprietary variant?

Sure. I have added this request to the bug I filed requesting more
complete PCIe host documentation.

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-21  6:47                                                                   ` Thierry Reding
  (?)
@ 2012-06-22 17:09                                                                       ` Mitch Bradley
  -1 siblings, 0 replies; 249+ messages in thread
From: Mitch Bradley @ 2012-06-22 17:09 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Stephen Warren, Russell King, linux-pci-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Jesse Barnes, Colin Cross, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Arnd Bergmann

On 6/20/2012 8:47 PM, Thierry Reding wrote:
> On Tue, Jun 19, 2012 at 11:31:39AM -1000, Mitch Bradley wrote:
>> On 6/19/2012 3:30 AM, Thierry Reding wrote:
>>> On Fri, Jun 15, 2012 at 08:12:36AM +0200, Thierry Reding wrote:
>>>> On Thu, Jun 14, 2012 at 01:50:56PM -0600, Stephen Warren wrote:
>>>>> On 06/14/2012 01:29 PM, Thierry Reding wrote:
>>>>>> On Thu, Jun 14, 2012 at 12:30:50PM -0600, Stephen Warren wrote:
>>>>>>> On 06/14/2012 03:19 AM, Thierry Reding wrote:
>>>>> ...
>>>>>>>> #address-cells = <1>; #size-cells = <1>;
>>>>>>>>
>>>>>>>> pci@80000000 {
>>>>>>>
>>>>>>> I'm still not convinced that using the address of the port's
>>>>>>> registers is the correct way to represent each port. The port
>>>>>>> index seems much more useful.
>>>>>>>
>>>>>>> The main reason here is that there are a lot of registers that
>>>>>>> contain fields for each port - far more than the combination of
>>>>>>> this node's reg and ctrl-offset (which I assume is an address
>>>>>>> offset for just one example of this issue) properties can
>>>>>>> describe. The bit position and bit stride of these fields isn't
>>>>>>> necessarily the same in each register. Do we want a property like
>>>>>>> ctrl-offset for every single type of field in every single shared
>>>>>>> register that describes the location of the relevant data, or
>>>>>>> just a single "port ID" bit that can be applied to anything?
>>>>>>>
>>>>>>> (Perhaps this isn't so obvious looking at the TRM since it
>>>>>>> doesn't document all registers, and I'm also looking at the
>>>>>>> Tegra30 documentation too, which might be more exposed to this -
>>>>>>> I haven't correlated all the documentation sources to be sure
>>>>>>> though)
>>>>>>
>>>>>> I agree that maybe adding properties for each bit position or
>>>>>> register offset may not work out too well. But I think it still
>>>>>> makes sense to use the base address of the port's registers (see
>>>>>> below). We could of course add some code to determine the index
>>>>> >from the base address at initialization time and reuse the index
>>>>>> where appropriate.
>>>>>
>>>>> To me, working back from address to ID then using the ID to calculate
>>>>> some other addresses seems far more icky than just calculating all the
>>>>> addresses based off of one ID. But, I suppose this doesn't make a huge
>>>>> practical difference.
>>>>
>>>> This really depends on the device vs. no device decision below. If we can
>>>> make it work without needing an extra device for it, then using the index
>>>> is certainly better. However, if we instantiate devices from the DT, then
>>>> we have the address anyway and adding the index as a property would be
>>>> redundant and error prone (what happens if somebody sets the index of the
>>>> port at address 0x80000000 to 2?).
>>>
>>> An additional problem with this is that we'd have to add the following
>>> to the pcie-controller node:
>>>
>>> 	#address-cells = <1>;
>>> 	#size-cells = <0>;
>>>
>>> This will conflict with the "ranges" property, because suddenly we can
>>> no longer map the regions properly. Maybe Mitch can comment on whether
>>> this is possible or not?
>>>
>>> To make it clearer what I'm talking about, here's the DT snippet again
>>> (with the compatible property removed from the pci@ nodes because they
>>> are no longer probed by a driver, the "simple-bus" removed from the
>>> pcie-controller node's compatible property removed and its #address-
>>> and #size-cells properties adjusted as described above).
>>>
>>> 	pcie-controller {
>>> 		compatible = "nvidia,tegra20-pcie";
>>> 		reg = <0x80003000 0x00000800   /* PADS registers */
>>> 		       0x80003800 0x00000200   /* AFI registers */
>>> 		       0x80004000 0x00100000   /* configuration space */
>>> 		       0x80104000 0x00100000>; /* extended configuration space */
>>> 		interrupts = <0 98 0x04   /* controller interrupt */
>>> 			      0 99 0x04>; /* MSI interrupt */
>>> 		status = "disabled";
>>>
>>> 		ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */
>>> 			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
>>> 			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
>>> 			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
>>>
>>> 		#address-cells = <1>;
>>> 		#size-cells = <0>;
>>>
>>> 		pci@0 {
>>> 			reg = <2>;
>>> 			status = "disabled";
>>>
>>> 			#address-cells = <3>;
>>> 			#size-cells = <2>;
>>>
>>> 			ranges = <0x81000000 0 0 0x80400000 0 0x00008000   /* I/O */
>>> 				  0x82000000 0 0 0x90000000 0 0x08000000   /* non-prefetchable memory */
>>> 				  0xc2000000 0 0 0xa0000000 0 0x08000000>; /* prefetchable memory */
>>>
>>> 			nvidia,ctrl-offset = <0x110>;
>>> 			nvidia,num-lanes = <2>;
>>> 		};
>>>
>>> 		pci@1 {
>>> 			reg = <1>;
>>> 			status = "disabled";
>>>
>>> 			#address-cells = <3>;
>>> 			#size-cells = <2>;
>>>
>>> 			ranges = <0x81000000 0 0 0x80408000 0 0x00008000   /* I/O */
>>> 				  0x82000000 0 0 0x98000000 0 0x08000000   /* non-prefetchable memory */
>>> 				  0xc2000000 0 0 0xa8000000 0 0x08000000>; /* prefetchable memory */
>>>
>>> 			nvidia,ctrl-offset = <0x118>;
>>> 			nvidia,num-lanes = <2>;
>>> 		};
>>> 	};
>>>
>>> AIUI none of the ranges properties are valid anymore, because the bus
>>> represented by pcie-controller no longer reflects the truth, namely that
>>> it translates the CPU address space to the PCI address space.
>>>
>>
>> I think you can use a small-integer port number as an address by
>> defining the intermediate address space properly, and using
>> appropriate ranges above and below.  Here's a swag at how that would
>> look.
>>
>> I present three versions, using different choices for the
>> intermediate address space encoding.  The intermediate address space
>> may seem somewhat artificial, in that it decouples the "linear pass
>> through of ranges" between the lower PCI address space and the upper
>> CPU address space.  But in another sense, it accurately reflects
>> that fact that the bus bridge "slices and dices" that linear address
>> space into non-contiguous pieces.
>>
>> Note that I'm also fixing a problem that I neglected to mention
>> earlier - namely the fact that config space is part of the child PCI
>> address space so it must be passed through.
>
> This doesn't quite match how the Tegra PCIe controller works. Basically,
> every access to a device's (extended) configuration space goes through a
> single region of memory-mapped registers, independent of which port is
> the parent of the device.
>
> Is it okay to pass both configuration spaces via the ranges property but
> still list them in the reg property of the controller?


It's a small hierarchy violation, but I expect that it would work in 
practice.

>
>> Version A - 3 address cells:  In this version, the intermediate
>> address space has 3 cells:  port#, address type, offset.  Address
>> type is
>>    0 : root port
>>    1 : config space
>>    2 : extended config space
>>    3 : I/O
>>    4 : non-prefetchable memory
>>    5 : prefetchable memory.
>>
>> The third cell "offset" is necessary so that the size field has a
>> number space that can include it.
>>
>> 	pcie-controller {
>> 		compatible = "nvidia,tegra20-pcie";
>> 		reg = <0x80003000 0x00000800   /* PADS registers */
>> 		       0x80003800 0x00000200>; /* extended configuration space */
>> 		interrupts = <0 98 0x04   /* controller interrupt */
>> 			      0 99 0x04>; /* MSI interrupt */
>> 		status = "disabled";
>>
>> 		ranges = <0 0 0  0x80000000 0x00001000   /* Root port 0 */
>> 			  0 1 0  0x80004000 0x00080000   /* Port 0 config space */
>> 			  0 2 0  0x80104000 0x00080000   /* Port 0 ext config space *
>> 			  0 3 0  0x80400000 0x00008000   /* Port 0 downstream I/O */
>> 			  0 4 0  0x90000000 0x08000000   /* Port 0 non-prefetchable memory */
>> 			  0 5 0  0xa0000000 0x08000000   /* Port 0 prefetchable memory */
>>
>> 			  1 0 0  0x80001000 0x00001000   /* Root port 1 */
>> 			  1 1 0  0x80004000 0x00080000   /* Port 1 config space */
>> 			  1 2 0  0x80184000 0x00080000   /* Port 1 ext config space */
>> 			  1 3 0  0x80408000 0x00010000   /* Port 1 downstream I/O */
>> 			  1 4 0  0x98000000 0x08000000   /* Port 1 non-prefetchable memory */
>> 			  1 5 0  0xa0000000 0x08000000>; /* Port 1 prefetchable memory */
>>
>> 		#address-cells = <3>;
>> 		#size-cells = <1>;
>>
>> 		pci@0 {
>> 			reg = <0 0 0 0x1000>;
>> 			status = "disabled";
>>
>> 			#address-cells = <3>;
>> 			#size-cells = <2>;
>>
>> 			ranges = <0x80000000 0 0  0 1 0  0 0x00080000   /* config */
>> 				  0x90000000 0 0  0 2 0  0 0x00080000   /* extended config */
>> 				  0x81000000 0 0  0 3 0  0 0x00008000   /* I/O */
>> 				  0x82000000 0 0  0 4 0  0 0x08000000   /* non-prefetchable memory */
>> 				  0xc2000000 0 0  0 5 0  0 0x08000000>; /* prefetchable memory */
>>
>> 			nvidia,ctrl-offset = <0x110>;
>> 			nvidia,num-lanes = <2>;
>> 		};
>>
>>
>> 		pci@1 {
>> 			reg = <1 0 0 0x1000>;
>> 			status = "disabled";
>>
>> 			#address-cells = <3>;
>> 			#size-cells = <2>;
>>
>> 			ranges = <0x80000000 0 0  1 1 0  0 0x00080000   /* config */
>> 				  0x90000000 0 0  1 2 0  0 0x00080000   /* extended config */
>> 				  0x81000000 0 0  1 3 0  0 0x00008000   /* I/O */
>> 				  0x82000000 0 0  1 4 0  0 0x08000000   /* non-prefetchable memory */
>> 				  0xc2000000 0 0  1 5 0  0 0x08000000>; /* prefetchable memory */
>>
>> 			nvidia,ctrl-offset = <0x118>;
>> 			nvidia,num-lanes = <2>;
>> 		};
>
> Everybody seems to be happy with this approach, so I'll give it a shot.
> There is one thing I'm still unsure about, though. What if somebody uses
> the above scheme and maps the registers to the wrong port. The same goes
> for the nvidia,ctrl-offset property. It needs to match the register
> offset because they are directly related. I suppose we could leave that
> property away and look up the register via the port index (which, as
> Stephen already said, we'll have to do in other places anyway, unless we
> list all bit positions in the DT).
>
> Can we safely ignore such issues and assume the device tree to always be
> right? Should we just not care if somebody uses it wrongly?


To the extent that the device tree is the definitive answer about the 
system addressing, if you get it wrong, either the system will not work 
or the OS isn't paying attention to that part of the device tree, 
hardcoding the right answer.

>
> Thierry
>

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-22 17:09                                                                       ` Mitch Bradley
  0 siblings, 0 replies; 249+ messages in thread
From: Mitch Bradley @ 2012-06-22 17:09 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Stephen Warren, Russell King, linux-pci, devicetree-discuss,
	Rob Herring, Jesse Barnes, Colin Cross, linux-tegra,
	linux-arm-kernel, Arnd Bergmann

On 6/20/2012 8:47 PM, Thierry Reding wrote:
> On Tue, Jun 19, 2012 at 11:31:39AM -1000, Mitch Bradley wrote:
>> On 6/19/2012 3:30 AM, Thierry Reding wrote:
>>> On Fri, Jun 15, 2012 at 08:12:36AM +0200, Thierry Reding wrote:
>>>> On Thu, Jun 14, 2012 at 01:50:56PM -0600, Stephen Warren wrote:
>>>>> On 06/14/2012 01:29 PM, Thierry Reding wrote:
>>>>>> On Thu, Jun 14, 2012 at 12:30:50PM -0600, Stephen Warren wrote:
>>>>>>> On 06/14/2012 03:19 AM, Thierry Reding wrote:
>>>>> ...
>>>>>>>> #address-cells = <1>; #size-cells = <1>;
>>>>>>>>
>>>>>>>> pci@80000000 {
>>>>>>>
>>>>>>> I'm still not convinced that using the address of the port's
>>>>>>> registers is the correct way to represent each port. The port
>>>>>>> index seems much more useful.
>>>>>>>
>>>>>>> The main reason here is that there are a lot of registers that
>>>>>>> contain fields for each port - far more than the combination of
>>>>>>> this node's reg and ctrl-offset (which I assume is an address
>>>>>>> offset for just one example of this issue) properties can
>>>>>>> describe. The bit position and bit stride of these fields isn't
>>>>>>> necessarily the same in each register. Do we want a property like
>>>>>>> ctrl-offset for every single type of field in every single shared
>>>>>>> register that describes the location of the relevant data, or
>>>>>>> just a single "port ID" bit that can be applied to anything?
>>>>>>>
>>>>>>> (Perhaps this isn't so obvious looking at the TRM since it
>>>>>>> doesn't document all registers, and I'm also looking at the
>>>>>>> Tegra30 documentation too, which might be more exposed to this -
>>>>>>> I haven't correlated all the documentation sources to be sure
>>>>>>> though)
>>>>>>
>>>>>> I agree that maybe adding properties for each bit position or
>>>>>> register offset may not work out too well. But I think it still
>>>>>> makes sense to use the base address of the port's registers (see
>>>>>> below). We could of course add some code to determine the index
>>>>> >from the base address at initialization time and reuse the index
>>>>>> where appropriate.
>>>>>
>>>>> To me, working back from address to ID then using the ID to calculate
>>>>> some other addresses seems far more icky than just calculating all the
>>>>> addresses based off of one ID. But, I suppose this doesn't make a huge
>>>>> practical difference.
>>>>
>>>> This really depends on the device vs. no device decision below. If we can
>>>> make it work without needing an extra device for it, then using the index
>>>> is certainly better. However, if we instantiate devices from the DT, then
>>>> we have the address anyway and adding the index as a property would be
>>>> redundant and error prone (what happens if somebody sets the index of the
>>>> port at address 0x80000000 to 2?).
>>>
>>> An additional problem with this is that we'd have to add the following
>>> to the pcie-controller node:
>>>
>>> 	#address-cells = <1>;
>>> 	#size-cells = <0>;
>>>
>>> This will conflict with the "ranges" property, because suddenly we can
>>> no longer map the regions properly. Maybe Mitch can comment on whether
>>> this is possible or not?
>>>
>>> To make it clearer what I'm talking about, here's the DT snippet again
>>> (with the compatible property removed from the pci@ nodes because they
>>> are no longer probed by a driver, the "simple-bus" removed from the
>>> pcie-controller node's compatible property removed and its #address-
>>> and #size-cells properties adjusted as described above).
>>>
>>> 	pcie-controller {
>>> 		compatible = "nvidia,tegra20-pcie";
>>> 		reg = <0x80003000 0x00000800   /* PADS registers */
>>> 		       0x80003800 0x00000200   /* AFI registers */
>>> 		       0x80004000 0x00100000   /* configuration space */
>>> 		       0x80104000 0x00100000>; /* extended configuration space */
>>> 		interrupts = <0 98 0x04   /* controller interrupt */
>>> 			      0 99 0x04>; /* MSI interrupt */
>>> 		status = "disabled";
>>>
>>> 		ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */
>>> 			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
>>> 			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
>>> 			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
>>>
>>> 		#address-cells = <1>;
>>> 		#size-cells = <0>;
>>>
>>> 		pci@0 {
>>> 			reg = <2>;
>>> 			status = "disabled";
>>>
>>> 			#address-cells = <3>;
>>> 			#size-cells = <2>;
>>>
>>> 			ranges = <0x81000000 0 0 0x80400000 0 0x00008000   /* I/O */
>>> 				  0x82000000 0 0 0x90000000 0 0x08000000   /* non-prefetchable memory */
>>> 				  0xc2000000 0 0 0xa0000000 0 0x08000000>; /* prefetchable memory */
>>>
>>> 			nvidia,ctrl-offset = <0x110>;
>>> 			nvidia,num-lanes = <2>;
>>> 		};
>>>
>>> 		pci@1 {
>>> 			reg = <1>;
>>> 			status = "disabled";
>>>
>>> 			#address-cells = <3>;
>>> 			#size-cells = <2>;
>>>
>>> 			ranges = <0x81000000 0 0 0x80408000 0 0x00008000   /* I/O */
>>> 				  0x82000000 0 0 0x98000000 0 0x08000000   /* non-prefetchable memory */
>>> 				  0xc2000000 0 0 0xa8000000 0 0x08000000>; /* prefetchable memory */
>>>
>>> 			nvidia,ctrl-offset = <0x118>;
>>> 			nvidia,num-lanes = <2>;
>>> 		};
>>> 	};
>>>
>>> AIUI none of the ranges properties are valid anymore, because the bus
>>> represented by pcie-controller no longer reflects the truth, namely that
>>> it translates the CPU address space to the PCI address space.
>>>
>>
>> I think you can use a small-integer port number as an address by
>> defining the intermediate address space properly, and using
>> appropriate ranges above and below.  Here's a swag at how that would
>> look.
>>
>> I present three versions, using different choices for the
>> intermediate address space encoding.  The intermediate address space
>> may seem somewhat artificial, in that it decouples the "linear pass
>> through of ranges" between the lower PCI address space and the upper
>> CPU address space.  But in another sense, it accurately reflects
>> that fact that the bus bridge "slices and dices" that linear address
>> space into non-contiguous pieces.
>>
>> Note that I'm also fixing a problem that I neglected to mention
>> earlier - namely the fact that config space is part of the child PCI
>> address space so it must be passed through.
>
> This doesn't quite match how the Tegra PCIe controller works. Basically,
> every access to a device's (extended) configuration space goes through a
> single region of memory-mapped registers, independent of which port is
> the parent of the device.
>
> Is it okay to pass both configuration spaces via the ranges property but
> still list them in the reg property of the controller?


It's a small hierarchy violation, but I expect that it would work in 
practice.

>
>> Version A - 3 address cells:  In this version, the intermediate
>> address space has 3 cells:  port#, address type, offset.  Address
>> type is
>>    0 : root port
>>    1 : config space
>>    2 : extended config space
>>    3 : I/O
>>    4 : non-prefetchable memory
>>    5 : prefetchable memory.
>>
>> The third cell "offset" is necessary so that the size field has a
>> number space that can include it.
>>
>> 	pcie-controller {
>> 		compatible = "nvidia,tegra20-pcie";
>> 		reg = <0x80003000 0x00000800   /* PADS registers */
>> 		       0x80003800 0x00000200>; /* extended configuration space */
>> 		interrupts = <0 98 0x04   /* controller interrupt */
>> 			      0 99 0x04>; /* MSI interrupt */
>> 		status = "disabled";
>>
>> 		ranges = <0 0 0  0x80000000 0x00001000   /* Root port 0 */
>> 			  0 1 0  0x80004000 0x00080000   /* Port 0 config space */
>> 			  0 2 0  0x80104000 0x00080000   /* Port 0 ext config space *
>> 			  0 3 0  0x80400000 0x00008000   /* Port 0 downstream I/O */
>> 			  0 4 0  0x90000000 0x08000000   /* Port 0 non-prefetchable memory */
>> 			  0 5 0  0xa0000000 0x08000000   /* Port 0 prefetchable memory */
>>
>> 			  1 0 0  0x80001000 0x00001000   /* Root port 1 */
>> 			  1 1 0  0x80004000 0x00080000   /* Port 1 config space */
>> 			  1 2 0  0x80184000 0x00080000   /* Port 1 ext config space */
>> 			  1 3 0  0x80408000 0x00010000   /* Port 1 downstream I/O */
>> 			  1 4 0  0x98000000 0x08000000   /* Port 1 non-prefetchable memory */
>> 			  1 5 0  0xa0000000 0x08000000>; /* Port 1 prefetchable memory */
>>
>> 		#address-cells = <3>;
>> 		#size-cells = <1>;
>>
>> 		pci@0 {
>> 			reg = <0 0 0 0x1000>;
>> 			status = "disabled";
>>
>> 			#address-cells = <3>;
>> 			#size-cells = <2>;
>>
>> 			ranges = <0x80000000 0 0  0 1 0  0 0x00080000   /* config */
>> 				  0x90000000 0 0  0 2 0  0 0x00080000   /* extended config */
>> 				  0x81000000 0 0  0 3 0  0 0x00008000   /* I/O */
>> 				  0x82000000 0 0  0 4 0  0 0x08000000   /* non-prefetchable memory */
>> 				  0xc2000000 0 0  0 5 0  0 0x08000000>; /* prefetchable memory */
>>
>> 			nvidia,ctrl-offset = <0x110>;
>> 			nvidia,num-lanes = <2>;
>> 		};
>>
>>
>> 		pci@1 {
>> 			reg = <1 0 0 0x1000>;
>> 			status = "disabled";
>>
>> 			#address-cells = <3>;
>> 			#size-cells = <2>;
>>
>> 			ranges = <0x80000000 0 0  1 1 0  0 0x00080000   /* config */
>> 				  0x90000000 0 0  1 2 0  0 0x00080000   /* extended config */
>> 				  0x81000000 0 0  1 3 0  0 0x00008000   /* I/O */
>> 				  0x82000000 0 0  1 4 0  0 0x08000000   /* non-prefetchable memory */
>> 				  0xc2000000 0 0  1 5 0  0 0x08000000>; /* prefetchable memory */
>>
>> 			nvidia,ctrl-offset = <0x118>;
>> 			nvidia,num-lanes = <2>;
>> 		};
>
> Everybody seems to be happy with this approach, so I'll give it a shot.
> There is one thing I'm still unsure about, though. What if somebody uses
> the above scheme and maps the registers to the wrong port. The same goes
> for the nvidia,ctrl-offset property. It needs to match the register
> offset because they are directly related. I suppose we could leave that
> property away and look up the register via the port index (which, as
> Stephen already said, we'll have to do in other places anyway, unless we
> list all bit positions in the DT).
>
> Can we safely ignore such issues and assume the device tree to always be
> right? Should we just not care if somebody uses it wrongly?


To the extent that the device tree is the definitive answer about the 
system addressing, if you get it wrong, either the system will not work 
or the OS isn't paying attention to that part of the device tree, 
hardcoding the right answer.

>
> Thierry
>


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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-22 17:09                                                                       ` Mitch Bradley
  0 siblings, 0 replies; 249+ messages in thread
From: Mitch Bradley @ 2012-06-22 17:09 UTC (permalink / raw)
  To: linux-arm-kernel

On 6/20/2012 8:47 PM, Thierry Reding wrote:
> On Tue, Jun 19, 2012 at 11:31:39AM -1000, Mitch Bradley wrote:
>> On 6/19/2012 3:30 AM, Thierry Reding wrote:
>>> On Fri, Jun 15, 2012 at 08:12:36AM +0200, Thierry Reding wrote:
>>>> On Thu, Jun 14, 2012 at 01:50:56PM -0600, Stephen Warren wrote:
>>>>> On 06/14/2012 01:29 PM, Thierry Reding wrote:
>>>>>> On Thu, Jun 14, 2012 at 12:30:50PM -0600, Stephen Warren wrote:
>>>>>>> On 06/14/2012 03:19 AM, Thierry Reding wrote:
>>>>> ...
>>>>>>>> #address-cells = <1>; #size-cells = <1>;
>>>>>>>>
>>>>>>>> pci at 80000000 {
>>>>>>>
>>>>>>> I'm still not convinced that using the address of the port's
>>>>>>> registers is the correct way to represent each port. The port
>>>>>>> index seems much more useful.
>>>>>>>
>>>>>>> The main reason here is that there are a lot of registers that
>>>>>>> contain fields for each port - far more than the combination of
>>>>>>> this node's reg and ctrl-offset (which I assume is an address
>>>>>>> offset for just one example of this issue) properties can
>>>>>>> describe. The bit position and bit stride of these fields isn't
>>>>>>> necessarily the same in each register. Do we want a property like
>>>>>>> ctrl-offset for every single type of field in every single shared
>>>>>>> register that describes the location of the relevant data, or
>>>>>>> just a single "port ID" bit that can be applied to anything?
>>>>>>>
>>>>>>> (Perhaps this isn't so obvious looking at the TRM since it
>>>>>>> doesn't document all registers, and I'm also looking at the
>>>>>>> Tegra30 documentation too, which might be more exposed to this -
>>>>>>> I haven't correlated all the documentation sources to be sure
>>>>>>> though)
>>>>>>
>>>>>> I agree that maybe adding properties for each bit position or
>>>>>> register offset may not work out too well. But I think it still
>>>>>> makes sense to use the base address of the port's registers (see
>>>>>> below). We could of course add some code to determine the index
>>>>> >from the base address at initialization time and reuse the index
>>>>>> where appropriate.
>>>>>
>>>>> To me, working back from address to ID then using the ID to calculate
>>>>> some other addresses seems far more icky than just calculating all the
>>>>> addresses based off of one ID. But, I suppose this doesn't make a huge
>>>>> practical difference.
>>>>
>>>> This really depends on the device vs. no device decision below. If we can
>>>> make it work without needing an extra device for it, then using the index
>>>> is certainly better. However, if we instantiate devices from the DT, then
>>>> we have the address anyway and adding the index as a property would be
>>>> redundant and error prone (what happens if somebody sets the index of the
>>>> port at address 0x80000000 to 2?).
>>>
>>> An additional problem with this is that we'd have to add the following
>>> to the pcie-controller node:
>>>
>>> 	#address-cells = <1>;
>>> 	#size-cells = <0>;
>>>
>>> This will conflict with the "ranges" property, because suddenly we can
>>> no longer map the regions properly. Maybe Mitch can comment on whether
>>> this is possible or not?
>>>
>>> To make it clearer what I'm talking about, here's the DT snippet again
>>> (with the compatible property removed from the pci@ nodes because they
>>> are no longer probed by a driver, the "simple-bus" removed from the
>>> pcie-controller node's compatible property removed and its #address-
>>> and #size-cells properties adjusted as described above).
>>>
>>> 	pcie-controller {
>>> 		compatible = "nvidia,tegra20-pcie";
>>> 		reg = <0x80003000 0x00000800   /* PADS registers */
>>> 		       0x80003800 0x00000200   /* AFI registers */
>>> 		       0x80004000 0x00100000   /* configuration space */
>>> 		       0x80104000 0x00100000>; /* extended configuration space */
>>> 		interrupts = <0 98 0x04   /* controller interrupt */
>>> 			      0 99 0x04>; /* MSI interrupt */
>>> 		status = "disabled";
>>>
>>> 		ranges = <0x80000000 0x80000000 0x00002000   /* 2 root ports */
>>> 			  0x80400000 0x80400000 0x00010000   /* downstream I/O */
>>> 			  0x90000000 0x90000000 0x10000000   /* non-prefetchable memory */
>>> 			  0xa0000000 0xa0000000 0x10000000>; /* prefetchable memory */
>>>
>>> 		#address-cells = <1>;
>>> 		#size-cells = <0>;
>>>
>>> 		pci at 0 {
>>> 			reg = <2>;
>>> 			status = "disabled";
>>>
>>> 			#address-cells = <3>;
>>> 			#size-cells = <2>;
>>>
>>> 			ranges = <0x81000000 0 0 0x80400000 0 0x00008000   /* I/O */
>>> 				  0x82000000 0 0 0x90000000 0 0x08000000   /* non-prefetchable memory */
>>> 				  0xc2000000 0 0 0xa0000000 0 0x08000000>; /* prefetchable memory */
>>>
>>> 			nvidia,ctrl-offset = <0x110>;
>>> 			nvidia,num-lanes = <2>;
>>> 		};
>>>
>>> 		pci at 1 {
>>> 			reg = <1>;
>>> 			status = "disabled";
>>>
>>> 			#address-cells = <3>;
>>> 			#size-cells = <2>;
>>>
>>> 			ranges = <0x81000000 0 0 0x80408000 0 0x00008000   /* I/O */
>>> 				  0x82000000 0 0 0x98000000 0 0x08000000   /* non-prefetchable memory */
>>> 				  0xc2000000 0 0 0xa8000000 0 0x08000000>; /* prefetchable memory */
>>>
>>> 			nvidia,ctrl-offset = <0x118>;
>>> 			nvidia,num-lanes = <2>;
>>> 		};
>>> 	};
>>>
>>> AIUI none of the ranges properties are valid anymore, because the bus
>>> represented by pcie-controller no longer reflects the truth, namely that
>>> it translates the CPU address space to the PCI address space.
>>>
>>
>> I think you can use a small-integer port number as an address by
>> defining the intermediate address space properly, and using
>> appropriate ranges above and below.  Here's a swag at how that would
>> look.
>>
>> I present three versions, using different choices for the
>> intermediate address space encoding.  The intermediate address space
>> may seem somewhat artificial, in that it decouples the "linear pass
>> through of ranges" between the lower PCI address space and the upper
>> CPU address space.  But in another sense, it accurately reflects
>> that fact that the bus bridge "slices and dices" that linear address
>> space into non-contiguous pieces.
>>
>> Note that I'm also fixing a problem that I neglected to mention
>> earlier - namely the fact that config space is part of the child PCI
>> address space so it must be passed through.
>
> This doesn't quite match how the Tegra PCIe controller works. Basically,
> every access to a device's (extended) configuration space goes through a
> single region of memory-mapped registers, independent of which port is
> the parent of the device.
>
> Is it okay to pass both configuration spaces via the ranges property but
> still list them in the reg property of the controller?


It's a small hierarchy violation, but I expect that it would work in 
practice.

>
>> Version A - 3 address cells:  In this version, the intermediate
>> address space has 3 cells:  port#, address type, offset.  Address
>> type is
>>    0 : root port
>>    1 : config space
>>    2 : extended config space
>>    3 : I/O
>>    4 : non-prefetchable memory
>>    5 : prefetchable memory.
>>
>> The third cell "offset" is necessary so that the size field has a
>> number space that can include it.
>>
>> 	pcie-controller {
>> 		compatible = "nvidia,tegra20-pcie";
>> 		reg = <0x80003000 0x00000800   /* PADS registers */
>> 		       0x80003800 0x00000200>; /* extended configuration space */
>> 		interrupts = <0 98 0x04   /* controller interrupt */
>> 			      0 99 0x04>; /* MSI interrupt */
>> 		status = "disabled";
>>
>> 		ranges = <0 0 0  0x80000000 0x00001000   /* Root port 0 */
>> 			  0 1 0  0x80004000 0x00080000   /* Port 0 config space */
>> 			  0 2 0  0x80104000 0x00080000   /* Port 0 ext config space *
>> 			  0 3 0  0x80400000 0x00008000   /* Port 0 downstream I/O */
>> 			  0 4 0  0x90000000 0x08000000   /* Port 0 non-prefetchable memory */
>> 			  0 5 0  0xa0000000 0x08000000   /* Port 0 prefetchable memory */
>>
>> 			  1 0 0  0x80001000 0x00001000   /* Root port 1 */
>> 			  1 1 0  0x80004000 0x00080000   /* Port 1 config space */
>> 			  1 2 0  0x80184000 0x00080000   /* Port 1 ext config space */
>> 			  1 3 0  0x80408000 0x00010000   /* Port 1 downstream I/O */
>> 			  1 4 0  0x98000000 0x08000000   /* Port 1 non-prefetchable memory */
>> 			  1 5 0  0xa0000000 0x08000000>; /* Port 1 prefetchable memory */
>>
>> 		#address-cells = <3>;
>> 		#size-cells = <1>;
>>
>> 		pci at 0 {
>> 			reg = <0 0 0 0x1000>;
>> 			status = "disabled";
>>
>> 			#address-cells = <3>;
>> 			#size-cells = <2>;
>>
>> 			ranges = <0x80000000 0 0  0 1 0  0 0x00080000   /* config */
>> 				  0x90000000 0 0  0 2 0  0 0x00080000   /* extended config */
>> 				  0x81000000 0 0  0 3 0  0 0x00008000   /* I/O */
>> 				  0x82000000 0 0  0 4 0  0 0x08000000   /* non-prefetchable memory */
>> 				  0xc2000000 0 0  0 5 0  0 0x08000000>; /* prefetchable memory */
>>
>> 			nvidia,ctrl-offset = <0x110>;
>> 			nvidia,num-lanes = <2>;
>> 		};
>>
>>
>> 		pci at 1 {
>> 			reg = <1 0 0 0x1000>;
>> 			status = "disabled";
>>
>> 			#address-cells = <3>;
>> 			#size-cells = <2>;
>>
>> 			ranges = <0x80000000 0 0  1 1 0  0 0x00080000   /* config */
>> 				  0x90000000 0 0  1 2 0  0 0x00080000   /* extended config */
>> 				  0x81000000 0 0  1 3 0  0 0x00008000   /* I/O */
>> 				  0x82000000 0 0  1 4 0  0 0x08000000   /* non-prefetchable memory */
>> 				  0xc2000000 0 0  1 5 0  0 0x08000000>; /* prefetchable memory */
>>
>> 			nvidia,ctrl-offset = <0x118>;
>> 			nvidia,num-lanes = <2>;
>> 		};
>
> Everybody seems to be happy with this approach, so I'll give it a shot.
> There is one thing I'm still unsure about, though. What if somebody uses
> the above scheme and maps the registers to the wrong port. The same goes
> for the nvidia,ctrl-offset property. It needs to match the register
> offset because they are directly related. I suppose we could leave that
> property away and look up the register via the port index (which, as
> Stephen already said, we'll have to do in other places anyway, unless we
> list all bit positions in the DT).
>
> Can we safely ignore such issues and assume the device tree to always be
> right? Should we just not care if somebody uses it wrongly?


To the extent that the device tree is the definitive answer about the 
system addressing, if you get it wrong, either the system will not work 
or the OS isn't paying attention to that part of the device tree, 
hardcoding the right answer.

>
> Thierry
>

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-22 16:53                                                                                         ` Arnd Bergmann
  (?)
@ 2012-06-22 17:13                                                                                             ` Bjorn Helgaas
  -1 siblings, 0 replies; 249+ messages in thread
From: Bjorn Helgaas @ 2012-06-22 17:13 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Thierry Reding, Mitch Bradley, Stephen Warren, Russell King,
	linux-pci-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Jesse Barnes, Colin Cross, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Yinghai Lu

On Fri, Jun 22, 2012 at 10:53 AM, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
> On Friday 22 June 2012, Bjorn Helgaas wrote:
>> The requirement (if there is one) isn't anything related to PC-ness.
>> I just don't understand how things can actually work if two host
>> bridges both claim the same bus number.  If we do a config read to
>> that bus, both bridges should claim it and turn it into config cycles
>> on their respective root buses, and we should get two responses.  I
>> would expect the second response to cause an "unexpected response"
>> machine check or similar.
>
> But each PCI domain has its own config space, so if you do a config
> read for one bus, it's always relative to the domain.

Oh, I see!  I totally missed the fact that each host bridge was in its
own domain.  If each has its own domain, then the bus number aperture
can certainly be [bus 00-ff] and there's no problem.

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-22 17:13                                                                                             ` Bjorn Helgaas
  0 siblings, 0 replies; 249+ messages in thread
From: Bjorn Helgaas @ 2012-06-22 17:13 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Thierry Reding, Mitch Bradley, Stephen Warren, Russell King,
	linux-pci, devicetree-discuss, Rob Herring, Jesse Barnes,
	Colin Cross, linux-tegra, linux-arm-kernel, Yinghai Lu

On Fri, Jun 22, 2012 at 10:53 AM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Friday 22 June 2012, Bjorn Helgaas wrote:
>> The requirement (if there is one) isn't anything related to PC-ness.
>> I just don't understand how things can actually work if two host
>> bridges both claim the same bus number.  If we do a config read to
>> that bus, both bridges should claim it and turn it into config cycles
>> on their respective root buses, and we should get two responses.  I
>> would expect the second response to cause an "unexpected response"
>> machine check or similar.
>
> But each PCI domain has its own config space, so if you do a config
> read for one bus, it's always relative to the domain.

Oh, I see!  I totally missed the fact that each host bridge was in its
own domain.  If each has its own domain, then the bus number aperture
can certainly be [bus 00-ff] and there's no problem.

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-22 17:13                                                                                             ` Bjorn Helgaas
  0 siblings, 0 replies; 249+ messages in thread
From: Bjorn Helgaas @ 2012-06-22 17:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jun 22, 2012 at 10:53 AM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Friday 22 June 2012, Bjorn Helgaas wrote:
>> The requirement (if there is one) isn't anything related to PC-ness.
>> I just don't understand how things can actually work if two host
>> bridges both claim the same bus number. ?If we do a config read to
>> that bus, both bridges should claim it and turn it into config cycles
>> on their respective root buses, and we should get two responses. ?I
>> would expect the second response to cause an "unexpected response"
>> machine check or similar.
>
> But each PCI domain has its own config space, so if you do a config
> read for one bus, it's always relative to the domain.

Oh, I see!  I totally missed the fact that each host bridge was in its
own domain.  If each has its own domain, then the bus number aperture
can certainly be [bus 00-ff] and there's no problem.

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-22 16:53                                                                                         ` Arnd Bergmann
  (?)
@ 2012-06-22 17:14                                                                                             ` Arnd Bergmann
  -1 siblings, 0 replies; 249+ messages in thread
From: Arnd Bergmann @ 2012-06-22 17:14 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: Bjorn Helgaas, Russell King, Stephen Warren,
	linux-pci-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Thierry Reding,
	Rob Herring, linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jesse Barnes,
	Colin Cross, Mitch Bradley, Yinghai Lu

On Friday 22 June 2012, Arnd Bergmann wrote:
> The part that is specific to PCs is that they don't have PCI domains
> normally.

Scratch that, PCs have moved on beyond that long ago, I just wasn't
aware that they also do that now. That was only true before mmconfig.

	Arnd

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-22 17:14                                                                                             ` Arnd Bergmann
  0 siblings, 0 replies; 249+ messages in thread
From: Arnd Bergmann @ 2012-06-22 17:14 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Bjorn Helgaas, Russell King, Stephen Warren, linux-pci,
	devicetree-discuss, Thierry Reding, Rob Herring, linux-tegra,
	Jesse Barnes, Colin Cross, Mitch Bradley, Yinghai Lu

On Friday 22 June 2012, Arnd Bergmann wrote:
> The part that is specific to PCs is that they don't have PCI domains
> normally.

Scratch that, PCs have moved on beyond that long ago, I just wasn't
aware that they also do that now. That was only true before mmconfig.

	Arnd

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-22 17:14                                                                                             ` Arnd Bergmann
  0 siblings, 0 replies; 249+ messages in thread
From: Arnd Bergmann @ 2012-06-22 17:14 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 22 June 2012, Arnd Bergmann wrote:
> The part that is specific to PCs is that they don't have PCI domains
> normally.

Scratch that, PCs have moved on beyond that long ago, I just wasn't
aware that they also do that now. That was only true before mmconfig.

	Arnd

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-22 17:00                                                                             ` Stephen Warren
@ 2012-06-22 17:28                                                                               ` Stephen Warren
  -1 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-22 17:28 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Bjorn Helgaas, Mitch Bradley, Russell King, linux-pci,
	devicetree-discuss, Rob Herring, Jesse Barnes, Colin Cross,
	linux-tegra, linux-arm-kernel, Arnd Bergmann

On 06/22/2012 11:00 AM, Stephen Warren wrote:
> On 06/22/2012 05:00 AM, Thierry Reding wrote:
> ...
>> Stephen: can you try to find out whether the Tegra PCIe controller 
>> indeed implements ECAM, or if this scheme is actually just a
>> proprietary variant?
> 
> Sure. I have added this request to the bug I filed requesting more
> complete PCIe host documentation.

I've received unofficial confirmation that we do indeed implement a
non-standard/non-ECAM mapping, and what's in our driver matches our HW.

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-22 17:28                                                                               ` Stephen Warren
  0 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-22 17:28 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/22/2012 11:00 AM, Stephen Warren wrote:
> On 06/22/2012 05:00 AM, Thierry Reding wrote:
> ...
>> Stephen: can you try to find out whether the Tegra PCIe controller 
>> indeed implements ECAM, or if this scheme is actually just a
>> proprietary variant?
> 
> Sure. I have added this request to the bug I filed requesting more
> complete PCIe host documentation.

I've received unofficial confirmation that we do indeed implement a
non-standard/non-ECAM mapping, and what's in our driver matches our HW.

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-22 17:13                                                                                             ` Bjorn Helgaas
  (?)
@ 2012-06-22 21:08                                                                                                 ` Arnd Bergmann
  -1 siblings, 0 replies; 249+ messages in thread
From: Arnd Bergmann @ 2012-06-22 21:08 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Thierry Reding, Mitch Bradley, Stephen Warren, Russell King,
	linux-pci-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Jesse Barnes, Colin Cross, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Yinghai Lu

On Friday 22 June 2012, Bjorn Helgaas wrote:
> 
> On Fri, Jun 22, 2012 at 10:53 AM, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
> > On Friday 22 June 2012, Bjorn Helgaas wrote:
> >> The requirement (if there is one) isn't anything related to PC-ness.
> >> I just don't understand how things can actually work if two host
> >> bridges both claim the same bus number.  If we do a config read to
> >> that bus, both bridges should claim it and turn it into config cycles
> >> on their respective root buses, and we should get two responses.  I
> >> would expect the second response to cause an "unexpected response"
> >> machine check or similar.
> >
> > But each PCI domain has its own config space, so if you do a config
> > read for one bus, it's always relative to the domain.
> 
> Oh, I see!  I totally missed the fact that each host bridge was in its
> own domain.  If each has its own domain, then the bus number aperture
> can certainly be [bus 00-ff] and there's no problem.

Right. On my side, it took me a while to figure out that you can
actually have multiple root ports in one domain ;-)

	Arnd

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-22 21:08                                                                                                 ` Arnd Bergmann
  0 siblings, 0 replies; 249+ messages in thread
From: Arnd Bergmann @ 2012-06-22 21:08 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Thierry Reding, Mitch Bradley, Stephen Warren, Russell King,
	linux-pci, devicetree-discuss, Rob Herring, Jesse Barnes,
	Colin Cross, linux-tegra, linux-arm-kernel, Yinghai Lu

On Friday 22 June 2012, Bjorn Helgaas wrote:
> 
> On Fri, Jun 22, 2012 at 10:53 AM, Arnd Bergmann <arnd@arndb.de> wrote:
> > On Friday 22 June 2012, Bjorn Helgaas wrote:
> >> The requirement (if there is one) isn't anything related to PC-ness.
> >> I just don't understand how things can actually work if two host
> >> bridges both claim the same bus number.  If we do a config read to
> >> that bus, both bridges should claim it and turn it into config cycles
> >> on their respective root buses, and we should get two responses.  I
> >> would expect the second response to cause an "unexpected response"
> >> machine check or similar.
> >
> > But each PCI domain has its own config space, so if you do a config
> > read for one bus, it's always relative to the domain.
> 
> Oh, I see!  I totally missed the fact that each host bridge was in its
> own domain.  If each has its own domain, then the bus number aperture
> can certainly be [bus 00-ff] and there's no problem.

Right. On my side, it took me a while to figure out that you can
actually have multiple root ports in one domain ;-)

	Arnd

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-22 21:08                                                                                                 ` Arnd Bergmann
  0 siblings, 0 replies; 249+ messages in thread
From: Arnd Bergmann @ 2012-06-22 21:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 22 June 2012, Bjorn Helgaas wrote:
> 
> On Fri, Jun 22, 2012 at 10:53 AM, Arnd Bergmann <arnd@arndb.de> wrote:
> > On Friday 22 June 2012, Bjorn Helgaas wrote:
> >> The requirement (if there is one) isn't anything related to PC-ness.
> >> I just don't understand how things can actually work if two host
> >> bridges both claim the same bus number.  If we do a config read to
> >> that bus, both bridges should claim it and turn it into config cycles
> >> on their respective root buses, and we should get two responses.  I
> >> would expect the second response to cause an "unexpected response"
> >> machine check or similar.
> >
> > But each PCI domain has its own config space, so if you do a config
> > read for one bus, it's always relative to the domain.
> 
> Oh, I see!  I totally missed the fact that each host bridge was in its
> own domain.  If each has its own domain, then the bus number aperture
> can certainly be [bus 00-ff] and there's no problem.

Right. On my side, it took me a while to figure out that you can
actually have multiple root ports in one domain ;-)

	Arnd

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-22 17:28                                                                               ` Stephen Warren
@ 2012-06-23 21:35                                                                                 ` Bjorn Helgaas
  -1 siblings, 0 replies; 249+ messages in thread
From: Bjorn Helgaas @ 2012-06-23 21:35 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Thierry Reding, Mitch Bradley, Russell King, linux-pci,
	devicetree-discuss, Rob Herring, Jesse Barnes, Colin Cross,
	linux-tegra, linux-arm-kernel, Arnd Bergmann

On Fri, Jun 22, 2012 at 11:28 AM, Stephen Warren <swarren@wwwdotorg.org> wrote:
> On 06/22/2012 11:00 AM, Stephen Warren wrote:
>> On 06/22/2012 05:00 AM, Thierry Reding wrote:
>> ...
>>> Stephen: can you try to find out whether the Tegra PCIe controller
>>> indeed implements ECAM, or if this scheme is actually just a
>>> proprietary variant?
>>
>> Sure. I have added this request to the bug I filed requesting more
>> complete PCIe host documentation.
>
> I've received unofficial confirmation that we do indeed implement a
> non-standard/non-ECAM mapping, and what's in our driver matches our HW.

Interesting.  A generic ECAM/MMCONFIG solution might still be worth
thinking about.  We could easily have a hook to encapsulate the
address mapping function, while still sharing the resource management
(request_region(), etc).  Not any kind of requirement for the current
patch series, of course, just possible future work.

Bjorn

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-23 21:35                                                                                 ` Bjorn Helgaas
  0 siblings, 0 replies; 249+ messages in thread
From: Bjorn Helgaas @ 2012-06-23 21:35 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jun 22, 2012 at 11:28 AM, Stephen Warren <swarren@wwwdotorg.org> wrote:
> On 06/22/2012 11:00 AM, Stephen Warren wrote:
>> On 06/22/2012 05:00 AM, Thierry Reding wrote:
>> ...
>>> Stephen: can you try to find out whether the Tegra PCIe controller
>>> indeed implements ECAM, or if this scheme is actually just a
>>> proprietary variant?
>>
>> Sure. I have added this request to the bug I filed requesting more
>> complete PCIe host documentation.
>
> I've received unofficial confirmation that we do indeed implement a
> non-standard/non-ECAM mapping, and what's in our driver matches our HW.

Interesting.  A generic ECAM/MMCONFIG solution might still be worth
thinking about.  We could easily have a hook to encapsulate the
address mapping function, while still sharing the resource management
(request_region(), etc).  Not any kind of requirement for the current
patch series, of course, just possible future work.

Bjorn

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-22 17:28                                                                               ` Stephen Warren
  (?)
@ 2012-06-25  6:34                                                                                   ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-25  6:34 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Bjorn Helgaas, Mitch Bradley, Russell King,
	linux-pci-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Jesse Barnes, Colin Cross, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Arnd Bergmann

[-- Attachment #1: Type: text/plain, Size: 872 bytes --]

On Fri, Jun 22, 2012 at 11:28:15AM -0600, Stephen Warren wrote:
> On 06/22/2012 11:00 AM, Stephen Warren wrote:
> > On 06/22/2012 05:00 AM, Thierry Reding wrote:
> > ...
> >> Stephen: can you try to find out whether the Tegra PCIe controller 
> >> indeed implements ECAM, or if this scheme is actually just a
> >> proprietary variant?
> > 
> > Sure. I have added this request to the bug I filed requesting more
> > complete PCIe host documentation.
> 
> I've received unofficial confirmation that we do indeed implement a
> non-standard/non-ECAM mapping, and what's in our driver matches our HW.

What I don't quite see yet is how the extended configuration space is
supposed to work with the current driver. The PCIE_CONF_* macros don't
provide for registers >= 256. Passing a value higher than that will mess
with the device function field.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-25  6:34                                                                                   ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-25  6:34 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Bjorn Helgaas, Mitch Bradley, Russell King, linux-pci,
	devicetree-discuss, Rob Herring, Jesse Barnes, Colin Cross,
	linux-tegra, linux-arm-kernel, Arnd Bergmann

[-- Attachment #1: Type: text/plain, Size: 872 bytes --]

On Fri, Jun 22, 2012 at 11:28:15AM -0600, Stephen Warren wrote:
> On 06/22/2012 11:00 AM, Stephen Warren wrote:
> > On 06/22/2012 05:00 AM, Thierry Reding wrote:
> > ...
> >> Stephen: can you try to find out whether the Tegra PCIe controller 
> >> indeed implements ECAM, or if this scheme is actually just a
> >> proprietary variant?
> > 
> > Sure. I have added this request to the bug I filed requesting more
> > complete PCIe host documentation.
> 
> I've received unofficial confirmation that we do indeed implement a
> non-standard/non-ECAM mapping, and what's in our driver matches our HW.

What I don't quite see yet is how the extended configuration space is
supposed to work with the current driver. The PCIE_CONF_* macros don't
provide for registers >= 256. Passing a value higher than that will mess
with the device function field.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-25  6:34                                                                                   ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-25  6:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jun 22, 2012 at 11:28:15AM -0600, Stephen Warren wrote:
> On 06/22/2012 11:00 AM, Stephen Warren wrote:
> > On 06/22/2012 05:00 AM, Thierry Reding wrote:
> > ...
> >> Stephen: can you try to find out whether the Tegra PCIe controller 
> >> indeed implements ECAM, or if this scheme is actually just a
> >> proprietary variant?
> > 
> > Sure. I have added this request to the bug I filed requesting more
> > complete PCIe host documentation.
> 
> I've received unofficial confirmation that we do indeed implement a
> non-standard/non-ECAM mapping, and what's in our driver matches our HW.

What I don't quite see yet is how the extended configuration space is
supposed to work with the current driver. The PCIE_CONF_* macros don't
provide for registers >= 256. Passing a value higher than that will mess
with the device function field.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120625/62af3efd/attachment.sig>

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-25  6:34                                                                                   ` Thierry Reding
@ 2012-06-26 17:22                                                                                     ` Stephen Warren
  -1 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-26 17:22 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Bjorn Helgaas, Mitch Bradley, Russell King, linux-pci,
	devicetree-discuss, Rob Herring, Jesse Barnes, Colin Cross,
	linux-tegra, linux-arm-kernel, Arnd Bergmann

On 06/25/2012 12:34 AM, Thierry Reding wrote:
> On Fri, Jun 22, 2012 at 11:28:15AM -0600, Stephen Warren wrote:
>> On 06/22/2012 11:00 AM, Stephen Warren wrote:
>>> On 06/22/2012 05:00 AM, Thierry Reding wrote: ...
>>>> Stephen: can you try to find out whether the Tegra PCIe
>>>> controller indeed implements ECAM, or if this scheme is
>>>> actually just a proprietary variant?
>>> 
>>> Sure. I have added this request to the bug I filed requesting
>>> more complete PCIe host documentation.
>> 
>> I've received unofficial confirmation that we do indeed implement
>> a non-standard/non-ECAM mapping, and what's in our driver matches
>> our HW.
> 
> What I don't quite see yet is how the extended configuration space
> is supposed to work with the current driver. The PCIE_CONF_* macros
> don't provide for registers >= 256. Passing a value higher than
> that will mess with the device function field.

The current downstream driver is incorrect for that case. We should be
updating it (at least, I filed a bug to do this).

Here's how the HW works (I believe this information should be in some
future version of the TRM):

There are 3 address spaces:

* The CPU bus.

* An internal (to the PCIe controller) 40-bit address space.
Apparently the layout is HyperTransport-based. Whether HT defines
this, or whether our HW engineers are referring to our particular
implementation of HT, I'm not sure.

* The PCIe external bus.

Accesses from the CPU to the PCIe controller's 1GB aperture are mapped
into the 40-bit bus using the BAR configurations in the PCIe
controller; I believe this is what tegra_pcie_setup_translations() is
configuring in our downstream driver.

Accesses are then mapped from this 40-bit bus to the external 32-bit
bus, I believe using a hard-coded mapping, which I believe may be
inherited from (our implementation of?) HyperTransport

For config and extended config accesses the mapping from the internal
to external bus is as follows:

In the case of PCICFG space,
addr[39:28]=12'hFDF,
addr[27:24]=4'hE means type 0 and addr[27:24]=4'hF means type 1,
addr[23:16]=bus number
addr[15:11]=device number
addr[10:8]=function number
addr[7:0]=register number

In the case of EXTCFG space,
addr[39:32]=8'hFE,
addr[31:28]=4'h0 means type 0 and addr[31:28]=4'h1 means type 1,
addr[27:24]=upper register number (i.e. register number[11:8])
addr[23:16]=bus number
addr[15:11]=device number
addr[10:8]=function number
addr[7:0]=register number (i.e. register number[7:0])

(in actual fact, the HW matches the top 16 or 12 bits to determine
config/ext-config and transaction type, so the top two fields in the
lists above should really be considered merged)

I hope this helps!

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-26 17:22                                                                                     ` Stephen Warren
  0 siblings, 0 replies; 249+ messages in thread
From: Stephen Warren @ 2012-06-26 17:22 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/25/2012 12:34 AM, Thierry Reding wrote:
> On Fri, Jun 22, 2012 at 11:28:15AM -0600, Stephen Warren wrote:
>> On 06/22/2012 11:00 AM, Stephen Warren wrote:
>>> On 06/22/2012 05:00 AM, Thierry Reding wrote: ...
>>>> Stephen: can you try to find out whether the Tegra PCIe
>>>> controller indeed implements ECAM, or if this scheme is
>>>> actually just a proprietary variant?
>>> 
>>> Sure. I have added this request to the bug I filed requesting
>>> more complete PCIe host documentation.
>> 
>> I've received unofficial confirmation that we do indeed implement
>> a non-standard/non-ECAM mapping, and what's in our driver matches
>> our HW.
> 
> What I don't quite see yet is how the extended configuration space
> is supposed to work with the current driver. The PCIE_CONF_* macros
> don't provide for registers >= 256. Passing a value higher than
> that will mess with the device function field.

The current downstream driver is incorrect for that case. We should be
updating it (at least, I filed a bug to do this).

Here's how the HW works (I believe this information should be in some
future version of the TRM):

There are 3 address spaces:

* The CPU bus.

* An internal (to the PCIe controller) 40-bit address space.
Apparently the layout is HyperTransport-based. Whether HT defines
this, or whether our HW engineers are referring to our particular
implementation of HT, I'm not sure.

* The PCIe external bus.

Accesses from the CPU to the PCIe controller's 1GB aperture are mapped
into the 40-bit bus using the BAR configurations in the PCIe
controller; I believe this is what tegra_pcie_setup_translations() is
configuring in our downstream driver.

Accesses are then mapped from this 40-bit bus to the external 32-bit
bus, I believe using a hard-coded mapping, which I believe may be
inherited from (our implementation of?) HyperTransport

For config and extended config accesses the mapping from the internal
to external bus is as follows:

In the case of PCICFG space,
addr[39:28]=12'hFDF,
addr[27:24]=4'hE means type 0 and addr[27:24]=4'hF means type 1,
addr[23:16]=bus number
addr[15:11]=device number
addr[10:8]=function number
addr[7:0]=register number

In the case of EXTCFG space,
addr[39:32]=8'hFE,
addr[31:28]=4'h0 means type 0 and addr[31:28]=4'h1 means type 1,
addr[27:24]=upper register number (i.e. register number[11:8])
addr[23:16]=bus number
addr[15:11]=device number
addr[10:8]=function number
addr[7:0]=register number (i.e. register number[7:0])

(in actual fact, the HW matches the top 16 or 12 bits to determine
config/ext-config and transaction type, so the top two fields in the
lists above should really be considered merged)

I hope this helps!

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
  2012-06-26 17:22                                                                                     ` Stephen Warren
  (?)
@ 2012-06-27  6:19                                                                                         ` Thierry Reding
  -1 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-27  6:19 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Bjorn Helgaas, Mitch Bradley, Russell King,
	linux-pci-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Jesse Barnes, Colin Cross, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Arnd Bergmann

[-- Attachment #1: Type: text/plain, Size: 3523 bytes --]

On Tue, Jun 26, 2012 at 11:22:32AM -0600, Stephen Warren wrote:
> On 06/25/2012 12:34 AM, Thierry Reding wrote:
> > On Fri, Jun 22, 2012 at 11:28:15AM -0600, Stephen Warren wrote:
> >> On 06/22/2012 11:00 AM, Stephen Warren wrote:
> >>> On 06/22/2012 05:00 AM, Thierry Reding wrote: ...
> >>>> Stephen: can you try to find out whether the Tegra PCIe
> >>>> controller indeed implements ECAM, or if this scheme is
> >>>> actually just a proprietary variant?
> >>> 
> >>> Sure. I have added this request to the bug I filed requesting
> >>> more complete PCIe host documentation.
> >> 
> >> I've received unofficial confirmation that we do indeed implement
> >> a non-standard/non-ECAM mapping, and what's in our driver matches
> >> our HW.
> > 
> > What I don't quite see yet is how the extended configuration space
> > is supposed to work with the current driver. The PCIE_CONF_* macros
> > don't provide for registers >= 256. Passing a value higher than
> > that will mess with the device function field.
> 
> The current downstream driver is incorrect for that case. We should be
> updating it (at least, I filed a bug to do this).
> 
> Here's how the HW works (I believe this information should be in some
> future version of the TRM):

Definitely. I'm having a hard time grasping all of this by just looking
at the code. Some sort of functional description (like what you provide
here) would be really useful.

> There are 3 address spaces:
> 
> * The CPU bus.
> 
> * An internal (to the PCIe controller) 40-bit address space.
> Apparently the layout is HyperTransport-based. Whether HT defines
> this, or whether our HW engineers are referring to our particular
> implementation of HT, I'm not sure.
> 
> * The PCIe external bus.
> 
> Accesses from the CPU to the PCIe controller's 1GB aperture are mapped
> into the 40-bit bus using the BAR configurations in the PCIe
> controller; I believe this is what tegra_pcie_setup_translations() is
> configuring in our downstream driver.
> 
> Accesses are then mapped from this 40-bit bus to the external 32-bit
> bus, I believe using a hard-coded mapping, which I believe may be
> inherited from (our implementation of?) HyperTransport

This seems to be what is referred to as the FPCI in the TRM and the
driver.

> For config and extended config accesses the mapping from the internal
> to external bus is as follows:
> 
> In the case of PCICFG space,
> addr[39:28]=12'hFDF,
> addr[27:24]=4'hE means type 0 and addr[27:24]=4'hF means type 1,
> addr[23:16]=bus number
> addr[15:11]=device number
> addr[10:8]=function number
> addr[7:0]=register number
> 
> In the case of EXTCFG space,
> addr[39:32]=8'hFE,
> addr[31:28]=4'h0 means type 0 and addr[31:28]=4'h1 means type 1,
> addr[27:24]=upper register number (i.e. register number[11:8])
> addr[23:16]=bus number
> addr[15:11]=device number
> addr[10:8]=function number
> addr[7:0]=register number (i.e. register number[7:0])
> 
> (in actual fact, the HW matches the top 16 or 12 bits to determine
> config/ext-config and transaction type, so the top two fields in the
> lists above should really be considered merged)

Yes, this actually matches with the driver. Config space accesses are
mapped to 0xfdff0000 and ext. config space accesses go to 0xfe100000.

> I hope this helps!

I don't know how this works out for what Bjorn had in mind, but at least
it'll allow the driver to be fixed for extended config space accesses.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-27  6:19                                                                                         ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-27  6:19 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Bjorn Helgaas, Mitch Bradley, Russell King, linux-pci,
	devicetree-discuss, Rob Herring, Jesse Barnes, Colin Cross,
	linux-tegra, linux-arm-kernel, Arnd Bergmann

[-- Attachment #1: Type: text/plain, Size: 3523 bytes --]

On Tue, Jun 26, 2012 at 11:22:32AM -0600, Stephen Warren wrote:
> On 06/25/2012 12:34 AM, Thierry Reding wrote:
> > On Fri, Jun 22, 2012 at 11:28:15AM -0600, Stephen Warren wrote:
> >> On 06/22/2012 11:00 AM, Stephen Warren wrote:
> >>> On 06/22/2012 05:00 AM, Thierry Reding wrote: ...
> >>>> Stephen: can you try to find out whether the Tegra PCIe
> >>>> controller indeed implements ECAM, or if this scheme is
> >>>> actually just a proprietary variant?
> >>> 
> >>> Sure. I have added this request to the bug I filed requesting
> >>> more complete PCIe host documentation.
> >> 
> >> I've received unofficial confirmation that we do indeed implement
> >> a non-standard/non-ECAM mapping, and what's in our driver matches
> >> our HW.
> > 
> > What I don't quite see yet is how the extended configuration space
> > is supposed to work with the current driver. The PCIE_CONF_* macros
> > don't provide for registers >= 256. Passing a value higher than
> > that will mess with the device function field.
> 
> The current downstream driver is incorrect for that case. We should be
> updating it (at least, I filed a bug to do this).
> 
> Here's how the HW works (I believe this information should be in some
> future version of the TRM):

Definitely. I'm having a hard time grasping all of this by just looking
at the code. Some sort of functional description (like what you provide
here) would be really useful.

> There are 3 address spaces:
> 
> * The CPU bus.
> 
> * An internal (to the PCIe controller) 40-bit address space.
> Apparently the layout is HyperTransport-based. Whether HT defines
> this, or whether our HW engineers are referring to our particular
> implementation of HT, I'm not sure.
> 
> * The PCIe external bus.
> 
> Accesses from the CPU to the PCIe controller's 1GB aperture are mapped
> into the 40-bit bus using the BAR configurations in the PCIe
> controller; I believe this is what tegra_pcie_setup_translations() is
> configuring in our downstream driver.
> 
> Accesses are then mapped from this 40-bit bus to the external 32-bit
> bus, I believe using a hard-coded mapping, which I believe may be
> inherited from (our implementation of?) HyperTransport

This seems to be what is referred to as the FPCI in the TRM and the
driver.

> For config and extended config accesses the mapping from the internal
> to external bus is as follows:
> 
> In the case of PCICFG space,
> addr[39:28]=12'hFDF,
> addr[27:24]=4'hE means type 0 and addr[27:24]=4'hF means type 1,
> addr[23:16]=bus number
> addr[15:11]=device number
> addr[10:8]=function number
> addr[7:0]=register number
> 
> In the case of EXTCFG space,
> addr[39:32]=8'hFE,
> addr[31:28]=4'h0 means type 0 and addr[31:28]=4'h1 means type 1,
> addr[27:24]=upper register number (i.e. register number[11:8])
> addr[23:16]=bus number
> addr[15:11]=device number
> addr[10:8]=function number
> addr[7:0]=register number (i.e. register number[7:0])
> 
> (in actual fact, the HW matches the top 16 or 12 bits to determine
> config/ext-config and transaction type, so the top two fields in the
> lists above should really be considered merged)

Yes, this actually matches with the driver. Config space accesses are
mapped to 0xfdff0000 and ext. config space accesses go to 0xfe100000.

> I hope this helps!

I don't know how this works out for what Bjorn had in mind, but at least
it'll allow the driver to be fixed for extended config space accesses.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

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

* [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
@ 2012-06-27  6:19                                                                                         ` Thierry Reding
  0 siblings, 0 replies; 249+ messages in thread
From: Thierry Reding @ 2012-06-27  6:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jun 26, 2012 at 11:22:32AM -0600, Stephen Warren wrote:
> On 06/25/2012 12:34 AM, Thierry Reding wrote:
> > On Fri, Jun 22, 2012 at 11:28:15AM -0600, Stephen Warren wrote:
> >> On 06/22/2012 11:00 AM, Stephen Warren wrote:
> >>> On 06/22/2012 05:00 AM, Thierry Reding wrote: ...
> >>>> Stephen: can you try to find out whether the Tegra PCIe
> >>>> controller indeed implements ECAM, or if this scheme is
> >>>> actually just a proprietary variant?
> >>> 
> >>> Sure. I have added this request to the bug I filed requesting
> >>> more complete PCIe host documentation.
> >> 
> >> I've received unofficial confirmation that we do indeed implement
> >> a non-standard/non-ECAM mapping, and what's in our driver matches
> >> our HW.
> > 
> > What I don't quite see yet is how the extended configuration space
> > is supposed to work with the current driver. The PCIE_CONF_* macros
> > don't provide for registers >= 256. Passing a value higher than
> > that will mess with the device function field.
> 
> The current downstream driver is incorrect for that case. We should be
> updating it (at least, I filed a bug to do this).
> 
> Here's how the HW works (I believe this information should be in some
> future version of the TRM):

Definitely. I'm having a hard time grasping all of this by just looking
at the code. Some sort of functional description (like what you provide
here) would be really useful.

> There are 3 address spaces:
> 
> * The CPU bus.
> 
> * An internal (to the PCIe controller) 40-bit address space.
> Apparently the layout is HyperTransport-based. Whether HT defines
> this, or whether our HW engineers are referring to our particular
> implementation of HT, I'm not sure.
> 
> * The PCIe external bus.
> 
> Accesses from the CPU to the PCIe controller's 1GB aperture are mapped
> into the 40-bit bus using the BAR configurations in the PCIe
> controller; I believe this is what tegra_pcie_setup_translations() is
> configuring in our downstream driver.
> 
> Accesses are then mapped from this 40-bit bus to the external 32-bit
> bus, I believe using a hard-coded mapping, which I believe may be
> inherited from (our implementation of?) HyperTransport

This seems to be what is referred to as the FPCI in the TRM and the
driver.

> For config and extended config accesses the mapping from the internal
> to external bus is as follows:
> 
> In the case of PCICFG space,
> addr[39:28]=12'hFDF,
> addr[27:24]=4'hE means type 0 and addr[27:24]=4'hF means type 1,
> addr[23:16]=bus number
> addr[15:11]=device number
> addr[10:8]=function number
> addr[7:0]=register number
> 
> In the case of EXTCFG space,
> addr[39:32]=8'hFE,
> addr[31:28]=4'h0 means type 0 and addr[31:28]=4'h1 means type 1,
> addr[27:24]=upper register number (i.e. register number[11:8])
> addr[23:16]=bus number
> addr[15:11]=device number
> addr[10:8]=function number
> addr[7:0]=register number (i.e. register number[7:0])
> 
> (in actual fact, the HW matches the top 16 or 12 bits to determine
> config/ext-config and transaction type, so the top two fields in the
> lists above should really be considered merged)

Yes, this actually matches with the driver. Config space accesses are
mapped to 0xfdff0000 and ext. config space accesses go to 0xfe100000.

> I hope this helps!

I don't know how this works out for what Bjorn had in mind, but at least
it'll allow the driver to be fixed for extended config space accesses.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120627/1018957d/attachment.sig>

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

end of thread, other threads:[~2012-06-27  6:19 UTC | newest]

Thread overview: 249+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-06-11 15:05 [PATCH v2 00/10] ARM: tegra: Add PCIe device tree support Thierry Reding
2012-06-11 15:05 ` Thierry Reding
2012-06-11 15:05 ` Thierry Reding
2012-06-11 15:05 ` [PATCH v2 05/10] ARM: tegra: Rewrite PCIe support as a driver Thierry Reding
2012-06-11 15:05   ` Thierry Reding
2012-06-11 21:09   ` Stephen Warren
2012-06-11 21:09     ` Stephen Warren
     [not found]     ` <4FD65E98.4070200-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2012-06-12  6:41       ` Thierry Reding
2012-06-12  6:41         ` Thierry Reding
2012-06-12  6:41         ` Thierry Reding
2012-06-12  7:24         ` Thierry Reding
2012-06-12  7:24           ` Thierry Reding
     [not found]           ` <20120612072444.GA8577-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/A@public.gmane.org>
2012-06-12 16:00             ` Stephen Warren
2012-06-12 16:00               ` Stephen Warren
2012-06-12 16:00               ` Stephen Warren
2012-06-13  8:12               ` Thierry Reding
2012-06-13  8:12                 ` Thierry Reding
     [not found]   ` <1339427118-32263-6-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
2012-06-11 21:22     ` Stephen Warren
2012-06-11 21:22       ` Stephen Warren
2012-06-11 21:22       ` Stephen Warren
     [not found]       ` <4FD6617C.4090805-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2012-06-12  4:59         ` Thierry Reding
2012-06-12  4:59           ` Thierry Reding
2012-06-12  4:59           ` Thierry Reding
2012-06-11 15:05 ` [PATCH v2 06/10] ARM: tegra: pcie: Add MSI support Thierry Reding
2012-06-11 15:05   ` Thierry Reding
     [not found]   ` <1339427118-32263-7-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
2012-06-11 21:19     ` Stephen Warren
2012-06-11 21:19       ` Stephen Warren
2012-06-11 21:19       ` Stephen Warren
2012-06-12  5:07       ` Thierry Reding
2012-06-12  5:07         ` Thierry Reding
2012-06-12  5:33         ` Stephen Warren
2012-06-12  5:33           ` Stephen Warren
     [not found]           ` <4FD6D4C6.2080201-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2012-06-12  5:41             ` Thierry Reding
2012-06-12  5:41               ` Thierry Reding
2012-06-12  5:41               ` Thierry Reding
     [not found]         ` <20120612050713.GB3669-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/A@public.gmane.org>
2012-06-12  6:10           ` Thierry Reding
2012-06-12  6:10             ` Thierry Reding
2012-06-12  6:10             ` Thierry Reding
     [not found]             ` <20120612061003.GC4040-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
2012-06-12 15:40               ` Stephen Warren
2012-06-12 15:40                 ` Stephen Warren
2012-06-12 15:40                 ` Stephen Warren
2012-06-12 17:23                 ` Thierry Reding
2012-06-12 17:23                   ` Thierry Reding
2012-06-11 15:05 ` [PATCH v2 08/10] ARM: tegra: harmony: Initialize regulators from DT Thierry Reding
2012-06-11 15:05   ` Thierry Reding
2012-06-11 21:36   ` Stephen Warren
2012-06-11 21:36     ` Stephen Warren
     [not found]     ` <4FD664F8.4030800-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2012-06-12  6:13       ` Thierry Reding
2012-06-12  6:13         ` Thierry Reding
2012-06-12  6:13         ` Thierry Reding
     [not found]   ` <1339427118-32263-9-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
2012-06-21 20:17     ` Stephen Warren
2012-06-21 20:17       ` Stephen Warren
2012-06-21 20:17       ` Stephen Warren
     [not found]       ` <4FE3815C.8030505-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2012-06-22  6:06         ` Thierry Reding
2012-06-22  6:06           ` Thierry Reding
2012-06-22  6:06           ` Thierry Reding
     [not found] ` <1339427118-32263-1-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
2012-06-11 15:05   ` [PATCH v2 01/10] PCI: Keep pci_fixup_irqs() around after init Thierry Reding
2012-06-11 15:05     ` Thierry Reding
2012-06-11 15:05     ` Thierry Reding
2012-06-11 15:05   ` [PATCH v2 02/10] ARM: pci: Keep pci_common_init() " Thierry Reding
2012-06-11 15:05     ` Thierry Reding
2012-06-11 15:05     ` Thierry Reding
2012-06-11 15:05   ` [PATCH v2 03/10] ARM: pci: Allow passing per-controller private data Thierry Reding
2012-06-11 15:05     ` Thierry Reding
2012-06-11 15:05     ` Thierry Reding
2012-06-11 15:05   ` [PATCH v2 04/10] ARM: tegra: Move tegra_pcie_xclk_clamp() to PMC Thierry Reding
2012-06-11 15:05     ` Thierry Reding
2012-06-11 15:05     ` Thierry Reding
2012-06-11 15:05   ` [PATCH v2 07/10] ARM: tegra: pcie: Add device tree support Thierry Reding
2012-06-11 15:05     ` Thierry Reding
2012-06-11 15:05     ` Thierry Reding
2012-06-11 21:33     ` Stephen Warren
2012-06-11 21:33       ` Stephen Warren
2012-06-12  6:21       ` Thierry Reding
2012-06-12  6:21         ` Thierry Reding
2012-06-12 15:44         ` Stephen Warren
2012-06-12 15:44           ` Stephen Warren
     [not found]           ` <4FD763C5.3090500-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2012-06-12 17:20             ` Thierry Reding
2012-06-12 17:20               ` Thierry Reding
2012-06-12 17:20               ` Thierry Reding
     [not found]               ` <20120612172041.GA28010-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
2012-06-12 19:10                 ` Mitch Bradley
2012-06-12 19:10                   ` Mitch Bradley
     [not found]                   ` <4FD7943E.60302-D5eQfiDGL7eakBO8gow8eQ@public.gmane.org>
2012-06-12 19:46                     ` Stephen Warren
2012-06-12 19:46                       ` Stephen Warren
2012-06-12 19:46                       ` Stephen Warren
2012-06-12 19:52                       ` Mitch Bradley
2012-06-12 19:52                         ` Mitch Bradley
     [not found]                         ` <4FD79DE8.90603-D5eQfiDGL7eakBO8gow8eQ@public.gmane.org>
2012-06-13  5:54                           ` Thierry Reding
2012-06-13  5:54                             ` Thierry Reding
2012-06-13  5:54                             ` Thierry Reding
2012-06-13  7:04                             ` Mitch Bradley
2012-06-13  7:04                               ` Mitch Bradley
2012-06-12 20:15               ` Stephen Warren
2012-06-12 20:15                 ` Stephen Warren
2012-06-12 21:11                 ` Mitch Bradley
2012-06-12 21:11                   ` Mitch Bradley
2012-06-13  6:45                   ` Thierry Reding
2012-06-13  6:45                     ` Thierry Reding
     [not found]                     ` <20120613064519.GD31001-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/A@public.gmane.org>
2012-06-13  7:28                       ` Mitch Bradley
2012-06-13  7:28                         ` Mitch Bradley
2012-06-13  7:28                         ` Mitch Bradley
     [not found]                         ` <4FD84133.4060401-D5eQfiDGL7eakBO8gow8eQ@public.gmane.org>
2012-06-13  7:52                           ` Thierry Reding
2012-06-13  7:52                             ` Thierry Reding
2012-06-13  7:52                             ` Thierry Reding
     [not found]                             ` <20120613075232.GA6139-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/A@public.gmane.org>
2012-06-13  8:05                               ` Mitch Bradley
2012-06-13  8:05                                 ` Mitch Bradley
2012-06-13  8:05                                 ` Mitch Bradley
     [not found]                                 ` <4FD849CF.4030009-D5eQfiDGL7eakBO8gow8eQ@public.gmane.org>
2012-06-13  8:19                                   ` Thierry Reding
2012-06-13  8:19                                     ` Thierry Reding
2012-06-13  8:19                                     ` Thierry Reding
     [not found]                                     ` <20120613081910.GB6528-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/A@public.gmane.org>
2012-06-13  8:36                                       ` Mitch Bradley
2012-06-13  8:36                                         ` Mitch Bradley
2012-06-13  8:36                                         ` Mitch Bradley
2012-06-13  8:42                                         ` Thierry Reding
2012-06-13  8:42                                           ` Thierry Reding
     [not found]                                         ` <4FD85127.8050301-D5eQfiDGL7eakBO8gow8eQ@public.gmane.org>
2012-06-14  9:19                                           ` Thierry Reding
2012-06-14  9:19                                             ` Thierry Reding
2012-06-14  9:19                                             ` Thierry Reding
     [not found]                                             ` <20120614091905.GA9081-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/A@public.gmane.org>
2012-06-14 18:30                                               ` Stephen Warren
2012-06-14 18:30                                                 ` Stephen Warren
2012-06-14 18:30                                                 ` Stephen Warren
     [not found]                                                 ` <4FDA2DDA.1030704-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2012-06-14 19:29                                                   ` Thierry Reding
2012-06-14 19:29                                                     ` Thierry Reding
2012-06-14 19:29                                                     ` Thierry Reding
     [not found]                                                     ` <20120614192903.GA2212-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/A@public.gmane.org>
2012-06-14 19:50                                                       ` Stephen Warren
2012-06-14 19:50                                                         ` Stephen Warren
2012-06-14 19:50                                                         ` Stephen Warren
     [not found]                                                         ` <4FDA40A0.4030206-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2012-06-15  6:12                                                           ` Thierry Reding
2012-06-15  6:12                                                             ` Thierry Reding
2012-06-15  6:12                                                             ` Thierry Reding
2012-06-19 13:30                                                             ` Thierry Reding
2012-06-19 13:30                                                               ` Thierry Reding
     [not found]                                                               ` <20120619133001.GB24138-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/A@public.gmane.org>
2012-06-19 16:40                                                                 ` Stephen Warren
2012-06-19 16:40                                                                   ` Stephen Warren
2012-06-19 16:40                                                                   ` Stephen Warren
2012-06-19 21:31                                                               ` Mitch Bradley
2012-06-19 21:31                                                                 ` Mitch Bradley
2012-06-20 16:32                                                                 ` Stephen Warren
2012-06-20 16:32                                                                   ` Stephen Warren
2012-06-20 17:41                                                                   ` Mitch Bradley
2012-06-20 17:41                                                                     ` Mitch Bradley
     [not found]                                                                     ` <4FE20B34.2090305-D5eQfiDGL7eakBO8gow8eQ@public.gmane.org>
2012-06-20 17:47                                                                       ` Stephen Warren
2012-06-20 17:47                                                                         ` Stephen Warren
2012-06-20 17:47                                                                         ` Stephen Warren
2012-06-20 19:57                                                                 ` Arnd Bergmann
2012-06-20 19:57                                                                   ` Arnd Bergmann
2012-06-20 20:19                                                                   ` Mitch Bradley
2012-06-20 20:19                                                                     ` Mitch Bradley
2012-06-21  6:47                                                                 ` Thierry Reding
2012-06-21  6:47                                                                   ` Thierry Reding
2012-06-21  6:47                                                                   ` Thierry Reding
     [not found]                                                                   ` <20120621064722.GA1122-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/A@public.gmane.org>
2012-06-22 10:18                                                                     ` Bjorn Helgaas
2012-06-22 10:18                                                                       ` Bjorn Helgaas
2012-06-22 10:18                                                                       ` Bjorn Helgaas
     [not found]                                                                       ` <CAErSpo6Bpfqm-0yGiBOXEhF4kD3PTDYvWVr0babLZ4GkBLXJiA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-06-22 11:00                                                                         ` Thierry Reding
2012-06-22 11:00                                                                           ` Thierry Reding
2012-06-22 11:00                                                                           ` Thierry Reding
2012-06-22 11:46                                                                           ` Bjorn Helgaas
2012-06-22 11:46                                                                             ` Bjorn Helgaas
2012-06-22 12:43                                                                             ` Thierry Reding
2012-06-22 12:43                                                                               ` Thierry Reding
2012-06-22 13:03                                                                               ` Arnd Bergmann
2012-06-22 13:03                                                                                 ` Arnd Bergmann
     [not found]                                                                                 ` <201206221303.21985.arnd-r2nGTMty4D4@public.gmane.org>
2012-06-22 16:49                                                                                   ` Bjorn Helgaas
2012-06-22 16:49                                                                                     ` Bjorn Helgaas
2012-06-22 16:49                                                                                     ` Bjorn Helgaas
     [not found]                                                                                     ` <CAErSpo56=S2oQ0usYfH28T0178SQUBD=5jqmcKWCT6M5WUQF6g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-06-22 16:53                                                                                       ` Arnd Bergmann
2012-06-22 16:53                                                                                         ` Arnd Bergmann
2012-06-22 16:53                                                                                         ` Arnd Bergmann
     [not found]                                                                                         ` <201206221653.31817.arnd-r2nGTMty4D4@public.gmane.org>
2012-06-22 17:13                                                                                           ` Bjorn Helgaas
2012-06-22 17:13                                                                                             ` Bjorn Helgaas
2012-06-22 17:13                                                                                             ` Bjorn Helgaas
     [not found]                                                                                             ` <CAErSpo5dj99iHW0WNEABPR1OO2yS=BwNezOivu6_7Go8sKyjsQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-06-22 21:08                                                                                               ` Arnd Bergmann
2012-06-22 21:08                                                                                                 ` Arnd Bergmann
2012-06-22 21:08                                                                                                 ` Arnd Bergmann
2012-06-22 17:14                                                                                           ` Arnd Bergmann
2012-06-22 17:14                                                                                             ` Arnd Bergmann
2012-06-22 17:14                                                                                             ` Arnd Bergmann
2012-06-22 17:00                                                                           ` Stephen Warren
2012-06-22 17:00                                                                             ` Stephen Warren
2012-06-22 17:28                                                                             ` Stephen Warren
2012-06-22 17:28                                                                               ` Stephen Warren
2012-06-23 21:35                                                                               ` Bjorn Helgaas
2012-06-23 21:35                                                                                 ` Bjorn Helgaas
     [not found]                                                                               ` <4FE4AB2F.8090402-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2012-06-25  6:34                                                                                 ` Thierry Reding
2012-06-25  6:34                                                                                   ` Thierry Reding
2012-06-25  6:34                                                                                   ` Thierry Reding
2012-06-26 17:22                                                                                   ` Stephen Warren
2012-06-26 17:22                                                                                     ` Stephen Warren
     [not found]                                                                                     ` <4FE9EFD8.6010608-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2012-06-27  6:19                                                                                       ` Thierry Reding
2012-06-27  6:19                                                                                         ` Thierry Reding
2012-06-27  6:19                                                                                         ` Thierry Reding
2012-06-22 16:20                                                                     ` Stephen Warren
2012-06-22 16:20                                                                       ` Stephen Warren
2012-06-22 16:20                                                                       ` Stephen Warren
2012-06-22 17:09                                                                     ` Mitch Bradley
2012-06-22 17:09                                                                       ` Mitch Bradley
2012-06-22 17:09                                                                       ` Mitch Bradley
2012-06-22 11:04                                                                 ` Thierry Reding
2012-06-22 11:04                                                                   ` Thierry Reding
     [not found]                                                                   ` <20120622110403.GA15710-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/A@public.gmane.org>
2012-06-22 13:22                                                                     ` Thierry Reding
2012-06-22 13:22                                                                       ` Thierry Reding
2012-06-22 13:22                                                                       ` Thierry Reding
     [not found]                                                                       ` <20120622132253.GA30704-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/A@public.gmane.org>
2012-06-22 13:48                                                                         ` Arnd Bergmann
2012-06-22 13:48                                                                           ` Arnd Bergmann
2012-06-22 13:48                                                                           ` Arnd Bergmann
     [not found]                                                                           ` <201206221348.39346.arnd-r2nGTMty4D4@public.gmane.org>
2012-06-22 14:02                                                                             ` Thierry Reding
2012-06-22 14:02                                                                               ` Thierry Reding
2012-06-22 14:02                                                                               ` Thierry Reding
     [not found]                                                                               ` <20120622140210.GA32097-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/A@public.gmane.org>
2012-06-22 16:40                                                                                 ` Arnd Bergmann
2012-06-22 16:40                                                                                   ` Arnd Bergmann
2012-06-22 16:40                                                                                   ` Arnd Bergmann
2012-06-13 20:21                               ` Arnd Bergmann
2012-06-13 20:21                                 ` Arnd Bergmann
2012-06-13 20:21                                 ` Arnd Bergmann
     [not found]                                 ` <201206132021.09774.arnd-r2nGTMty4D4@public.gmane.org>
2012-06-14  8:37                                   ` Thierry Reding
2012-06-14  8:37                                     ` Thierry Reding
2012-06-14  8:37                                     ` Thierry Reding
2012-06-14 10:25                                     ` Arnd Bergmann
2012-06-14 10:25                                       ` Arnd Bergmann
2012-06-14 10:31                                       ` Thierry Reding
2012-06-14 10:31                                         ` Thierry Reding
2012-06-14 11:06                                         ` Arnd Bergmann
2012-06-14 11:06                                           ` Arnd Bergmann
     [not found]                                           ` <201206141106.49142.arnd-r2nGTMty4D4@public.gmane.org>
2012-06-14 11:58                                             ` Thierry Reding
2012-06-14 11:58                                               ` Thierry Reding
2012-06-14 11:58                                               ` Thierry Reding
     [not found]                 ` <4FD7A36B.9090409-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2012-06-13  6:34                   ` Thierry Reding
2012-06-13  6:34                     ` Thierry Reding
2012-06-13  6:34                     ` Thierry Reding
     [not found]                     ` <20120613063422.GC31001-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/A@public.gmane.org>
2012-06-13 16:20                       ` Stephen Warren
2012-06-13 16:20                         ` Stephen Warren
2012-06-13 16:20                         ` Stephen Warren
2012-06-13 17:03                     ` Stephen Warren
2012-06-13 17:03                       ` Stephen Warren
2012-06-11 15:05   ` [PATCH v2 09/10] ARM: tegra: harmony: Initialize PCIe from DT Thierry Reding
2012-06-11 15:05     ` Thierry Reding
2012-06-11 15:05     ` Thierry Reding
     [not found]     ` <1339427118-32263-10-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
2012-06-11 21:41       ` Stephen Warren
2012-06-11 21:41         ` Stephen Warren
2012-06-11 21:41         ` Stephen Warren
     [not found]         ` <4FD6661A.1060407-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2012-06-12  5:48           ` Thierry Reding
2012-06-12  5:48             ` Thierry Reding
2012-06-12  5:48             ` Thierry Reding
     [not found]             ` <20120612054811.GB4040-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
2012-06-12 15:38               ` Stephen Warren
2012-06-12 15:38                 ` Stephen Warren
2012-06-12 15:38                 ` Stephen Warren
2012-06-11 15:05 ` [PATCH v2 10/10] ARM: tegra: trimslice: " Thierry Reding
2012-06-11 15:05   ` Thierry Reding

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