All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/2] pci: host: Broadcom STB PCIE RC controller support
@ 2016-05-05 19:14 ` Florian Fainelli
  0 siblings, 0 replies; 41+ messages in thread
From: Florian Fainelli @ 2016-05-05 19:14 UTC (permalink / raw)
  To: linux-pci
  Cc: linux-kernel, devicetree, linux-arm-kernel,
	bcm-kernel-feedback-list, jim2101024, bhelgaas, arnd,
	Florian Fainelli

Hi all,

This patch series adds support for Broadcom STB SoC's PCIe root complex driver.

This was primarily tested on BCM7445 (ARM) and BCM7435 (MIPS).

Jim is the original author, and I picked up our downstream 4.1 driver and
updated it to utilize the non-ARM hw_pci functions as well as made some
stylistic changes.

Thanks!

Jim Quinlan (2):
  Documentation: DT: bindings: Add Broadcom STB PCIe bindings
  pci: host: Add Broadcom STB PCIE RC controller

 .../devicetree/bindings/pci/brcm,brcmstb-pcie.txt  |  98 +++
 MAINTAINERS                                        |   1 +
 drivers/pci/host/Kconfig                           |  17 +
 drivers/pci/host/Makefile                          |   2 +
 drivers/pci/host/pcie-brcmstb-msi.c                | 305 ++++++++
 drivers/pci/host/pcie-brcmstb.c                    | 772 +++++++++++++++++++++
 drivers/pci/host/pcie-brcmstb.h                    | 169 +++++
 7 files changed, 1364 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
 create mode 100644 drivers/pci/host/pcie-brcmstb-msi.c
 create mode 100644 drivers/pci/host/pcie-brcmstb.c
 create mode 100644 drivers/pci/host/pcie-brcmstb.h

-- 
2.1.0

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

* [PATCH v2 0/2] pci: host: Broadcom STB PCIE RC controller support
@ 2016-05-05 19:14 ` Florian Fainelli
  0 siblings, 0 replies; 41+ messages in thread
From: Florian Fainelli @ 2016-05-05 19:14 UTC (permalink / raw)
  To: linux-arm-kernel

Hi all,

This patch series adds support for Broadcom STB SoC's PCIe root complex driver.

This was primarily tested on BCM7445 (ARM) and BCM7435 (MIPS).

Jim is the original author, and I picked up our downstream 4.1 driver and
updated it to utilize the non-ARM hw_pci functions as well as made some
stylistic changes.

Thanks!

Jim Quinlan (2):
  Documentation: DT: bindings: Add Broadcom STB PCIe bindings
  pci: host: Add Broadcom STB PCIE RC controller

 .../devicetree/bindings/pci/brcm,brcmstb-pcie.txt  |  98 +++
 MAINTAINERS                                        |   1 +
 drivers/pci/host/Kconfig                           |  17 +
 drivers/pci/host/Makefile                          |   2 +
 drivers/pci/host/pcie-brcmstb-msi.c                | 305 ++++++++
 drivers/pci/host/pcie-brcmstb.c                    | 772 +++++++++++++++++++++
 drivers/pci/host/pcie-brcmstb.h                    | 169 +++++
 7 files changed, 1364 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
 create mode 100644 drivers/pci/host/pcie-brcmstb-msi.c
 create mode 100644 drivers/pci/host/pcie-brcmstb.c
 create mode 100644 drivers/pci/host/pcie-brcmstb.h

-- 
2.1.0

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

* [PATCH v2 1/2] Documentation: DT: bindings: Add Broadcom STB PCIe bindings
  2016-05-05 19:14 ` Florian Fainelli
  (?)
@ 2016-05-05 19:14   ` Florian Fainelli
  -1 siblings, 0 replies; 41+ messages in thread
From: Florian Fainelli @ 2016-05-05 19:14 UTC (permalink / raw)
  To: linux-pci
  Cc: linux-kernel, devicetree, linux-arm-kernel,
	bcm-kernel-feedback-list, jim2101024, bhelgaas, arnd,
	Florian Fainelli

From: Jim Quinlan <jim2101024@gmail.com>

This patchs adds the Device Tree bindings for the Broadcom STB PCIe root
complex hardware.

Signed-off-by: Jim Quinlan <jim2101024@gmail.com>
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
Changes in v2:

- rewrite the binding document almost from scratch to include many more
  references to existing documents
- describe missing properties
- give better examples

 .../devicetree/bindings/pci/brcm,brcmstb-pcie.txt  | 98 ++++++++++++++++++++++
 1 file changed, 98 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt

diff --git a/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt b/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
new file mode 100644
index 000000000000..3682b0f0bc26
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
@@ -0,0 +1,98 @@
+Broadcom STB PCIe Host Controller Device Tree Bindings
+
+This document describes the binding of the PCIe Root Complex hardware found in
+Broadcom Set Top Box System-on-Chips such as BCM7425 (MIPS), BCM7435 (MIPS) and
+BCM7445 (ARMv7).
+
+Required properties:
+- compatible: must be one of: "brcm,bcm7425-pcie"
+			      "brcm,bcm7435-pcie"
+			      "brcm,bcm7445-pcie"
+
+- reg: specifies the physical base address of the controller registers and
+  its length
+
+- interrupt-parent: must be a reference (phandle) to the parent interrupt
+  controller in the system (7038-l1-intc on MIPS, GIC on ARM/ARM64)
+
+- interrrupts: first interrupt must be the Level 1 interrupt number corresponding
+  to the main PCIe RC interrupt, second interrupt must be the MSI interrupt
+  See the interrupt-parent documentation for the number of cells and their meaning:
+  MIPS: Documentation/devicetree/bindings/interrupt-controller/brcm,bcm7038-l1-intc.txt
+  ARM/ARM64: Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt
+
+- interrupt-names: must be "pcie", and if present "msi"
+
+- interrupt-map: see pci.txt
+
+- interrupt-map-mask: see pci.txt
+
+- #address-cells: must be set to <3>, see pci.txt
+
+- #size-cells: must be set to <2>, see pci.txt
+
+- ranges: ranges for the PCI outbound windows, no I/O or prefetchable windows
+  must be specified here, only non-prefetchable. 32-bits windows or 64-bits
+  windows are allowed based on the host processor's capabilities (ARM w/ LPAE,
+  ARM64).
+
+- #interrupt-cells: set to <1>, see pci.txt
+
+- brcm,log2-scb-sizes: log2 size of the SCB window that is mapped to PCIe space
+  there must be exactly one value per memory controller present in the system
+  (ranges from 1 to 3)
+
+Optional properties:
+
+- msi-controller: indicates that this is a MSI controller node (when supported)
+
+- clocks: phandle to the functional clock that feeds into the PCIe RC block
+
+- clock-names: the name(s) of the clocks specified in 'clocks'.  Note
+  that if the 'clocks' property is given, 'clock-names' is mandatory,
+  and the name of the clock is expected to be "pcie".
+
+- brcm,ssc: boolean that indicates usage of spread-spectrum clocking
+
+- brcm,gen: integer that indicates desired forced generation of link: 1 => 2.5
+  Gbps, 2 => 5.0 Gbps, 3 => 8.0 Gbps. Will override the auto-negotation if
+  specified.
+
+- <*>-supply: see Documentation/devicetree/bindings/regulator/regulator.txt
+
+- <*>-supply-names: see Documentation/devicetree/bindings/regulator/regulator.txt
+
+Example Node:
+
+This example assumes that the top-level #address-cells = <2> and #size-cells =
+<2>, e.g: ARM LPAE configuration.
+
+	pcie0: pcie-controller@f0460000 {
+		reg = <0x0 0xf0460000 0x0 0x9310>;
+		interrupts = <0x0 0x33 0x4>, <0x0 0x34, 0x4>;
+		interrupt-names = "pcie", "msi";
+		compatible = "brcm,bcm7445-pcie";
+		#address-cells = <3>;
+		#size-cells = <2>;
+
+		/* Two non-prefetchable 32-bits memory space, each of 128MB
+ 		 * with the following mapping:
+		 * PCIe address		=> CPU physical address space
+		 * 0x00_0000_0000	=> 0x00_C000_0000
+		 * 0x00_0800_0000	=> 0x00_C800_0000
+		 */
+		ranges = <0x02000000 0x00000000 0x00000000 0x00000000 0xc0000000 0x00000000 0x08000000>,
+			 <0x02000000 0x00000000 0x08000000 0x00000000 0xc8000000 0x00000000 0x08000000>;
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0xf800 0 0 7>;
+		interrupt-map = <0 0 0 1 &intc 47 3
+				 0 0 0 2 &intc 48 3
+				 0 0 0 3 &intc 49 3
+				 0 0 0 4 &intc 50 3>;
+		clocks = <&pcie0>;
+		clock-names = "pcie";
+		brcm,ssc;
+		brcm,log2-scb-sizes = <0x1e 0x1e 0x1e>;
+		vreg-wifi-pwr-supply-names = "vreg-wifi-pwr";
+		vreg-wifi-pwr-supply = <&vreg-wifi-pwr>;
+	};
-- 
2.1.0

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

* [PATCH v2 1/2] Documentation: DT: bindings: Add Broadcom STB PCIe bindings
@ 2016-05-05 19:14   ` Florian Fainelli
  0 siblings, 0 replies; 41+ messages in thread
From: Florian Fainelli @ 2016-05-05 19:14 UTC (permalink / raw)
  To: linux-pci
  Cc: devicetree, Florian Fainelli, arnd, linux-kernel, jim2101024,
	bcm-kernel-feedback-list, bhelgaas, linux-arm-kernel

From: Jim Quinlan <jim2101024@gmail.com>

This patchs adds the Device Tree bindings for the Broadcom STB PCIe root
complex hardware.

Signed-off-by: Jim Quinlan <jim2101024@gmail.com>
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
Changes in v2:

- rewrite the binding document almost from scratch to include many more
  references to existing documents
- describe missing properties
- give better examples

 .../devicetree/bindings/pci/brcm,brcmstb-pcie.txt  | 98 ++++++++++++++++++++++
 1 file changed, 98 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt

diff --git a/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt b/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
new file mode 100644
index 000000000000..3682b0f0bc26
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
@@ -0,0 +1,98 @@
+Broadcom STB PCIe Host Controller Device Tree Bindings
+
+This document describes the binding of the PCIe Root Complex hardware found in
+Broadcom Set Top Box System-on-Chips such as BCM7425 (MIPS), BCM7435 (MIPS) and
+BCM7445 (ARMv7).
+
+Required properties:
+- compatible: must be one of: "brcm,bcm7425-pcie"
+			      "brcm,bcm7435-pcie"
+			      "brcm,bcm7445-pcie"
+
+- reg: specifies the physical base address of the controller registers and
+  its length
+
+- interrupt-parent: must be a reference (phandle) to the parent interrupt
+  controller in the system (7038-l1-intc on MIPS, GIC on ARM/ARM64)
+
+- interrrupts: first interrupt must be the Level 1 interrupt number corresponding
+  to the main PCIe RC interrupt, second interrupt must be the MSI interrupt
+  See the interrupt-parent documentation for the number of cells and their meaning:
+  MIPS: Documentation/devicetree/bindings/interrupt-controller/brcm,bcm7038-l1-intc.txt
+  ARM/ARM64: Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt
+
+- interrupt-names: must be "pcie", and if present "msi"
+
+- interrupt-map: see pci.txt
+
+- interrupt-map-mask: see pci.txt
+
+- #address-cells: must be set to <3>, see pci.txt
+
+- #size-cells: must be set to <2>, see pci.txt
+
+- ranges: ranges for the PCI outbound windows, no I/O or prefetchable windows
+  must be specified here, only non-prefetchable. 32-bits windows or 64-bits
+  windows are allowed based on the host processor's capabilities (ARM w/ LPAE,
+  ARM64).
+
+- #interrupt-cells: set to <1>, see pci.txt
+
+- brcm,log2-scb-sizes: log2 size of the SCB window that is mapped to PCIe space
+  there must be exactly one value per memory controller present in the system
+  (ranges from 1 to 3)
+
+Optional properties:
+
+- msi-controller: indicates that this is a MSI controller node (when supported)
+
+- clocks: phandle to the functional clock that feeds into the PCIe RC block
+
+- clock-names: the name(s) of the clocks specified in 'clocks'.  Note
+  that if the 'clocks' property is given, 'clock-names' is mandatory,
+  and the name of the clock is expected to be "pcie".
+
+- brcm,ssc: boolean that indicates usage of spread-spectrum clocking
+
+- brcm,gen: integer that indicates desired forced generation of link: 1 => 2.5
+  Gbps, 2 => 5.0 Gbps, 3 => 8.0 Gbps. Will override the auto-negotation if
+  specified.
+
+- <*>-supply: see Documentation/devicetree/bindings/regulator/regulator.txt
+
+- <*>-supply-names: see Documentation/devicetree/bindings/regulator/regulator.txt
+
+Example Node:
+
+This example assumes that the top-level #address-cells = <2> and #size-cells =
+<2>, e.g: ARM LPAE configuration.
+
+	pcie0: pcie-controller@f0460000 {
+		reg = <0x0 0xf0460000 0x0 0x9310>;
+		interrupts = <0x0 0x33 0x4>, <0x0 0x34, 0x4>;
+		interrupt-names = "pcie", "msi";
+		compatible = "brcm,bcm7445-pcie";
+		#address-cells = <3>;
+		#size-cells = <2>;
+
+		/* Two non-prefetchable 32-bits memory space, each of 128MB
+ 		 * with the following mapping:
+		 * PCIe address		=> CPU physical address space
+		 * 0x00_0000_0000	=> 0x00_C000_0000
+		 * 0x00_0800_0000	=> 0x00_C800_0000
+		 */
+		ranges = <0x02000000 0x00000000 0x00000000 0x00000000 0xc0000000 0x00000000 0x08000000>,
+			 <0x02000000 0x00000000 0x08000000 0x00000000 0xc8000000 0x00000000 0x08000000>;
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0xf800 0 0 7>;
+		interrupt-map = <0 0 0 1 &intc 47 3
+				 0 0 0 2 &intc 48 3
+				 0 0 0 3 &intc 49 3
+				 0 0 0 4 &intc 50 3>;
+		clocks = <&pcie0>;
+		clock-names = "pcie";
+		brcm,ssc;
+		brcm,log2-scb-sizes = <0x1e 0x1e 0x1e>;
+		vreg-wifi-pwr-supply-names = "vreg-wifi-pwr";
+		vreg-wifi-pwr-supply = <&vreg-wifi-pwr>;
+	};
-- 
2.1.0

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

* [PATCH v2 1/2] Documentation: DT: bindings: Add Broadcom STB PCIe bindings
@ 2016-05-05 19:14   ` Florian Fainelli
  0 siblings, 0 replies; 41+ messages in thread
From: Florian Fainelli @ 2016-05-05 19:14 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jim Quinlan <jim2101024@gmail.com>

This patchs adds the Device Tree bindings for the Broadcom STB PCIe root
complex hardware.

Signed-off-by: Jim Quinlan <jim2101024@gmail.com>
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
Changes in v2:

- rewrite the binding document almost from scratch to include many more
  references to existing documents
- describe missing properties
- give better examples

 .../devicetree/bindings/pci/brcm,brcmstb-pcie.txt  | 98 ++++++++++++++++++++++
 1 file changed, 98 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt

diff --git a/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt b/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
new file mode 100644
index 000000000000..3682b0f0bc26
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
@@ -0,0 +1,98 @@
+Broadcom STB PCIe Host Controller Device Tree Bindings
+
+This document describes the binding of the PCIe Root Complex hardware found in
+Broadcom Set Top Box System-on-Chips such as BCM7425 (MIPS), BCM7435 (MIPS) and
+BCM7445 (ARMv7).
+
+Required properties:
+- compatible: must be one of: "brcm,bcm7425-pcie"
+			      "brcm,bcm7435-pcie"
+			      "brcm,bcm7445-pcie"
+
+- reg: specifies the physical base address of the controller registers and
+  its length
+
+- interrupt-parent: must be a reference (phandle) to the parent interrupt
+  controller in the system (7038-l1-intc on MIPS, GIC on ARM/ARM64)
+
+- interrrupts: first interrupt must be the Level 1 interrupt number corresponding
+  to the main PCIe RC interrupt, second interrupt must be the MSI interrupt
+  See the interrupt-parent documentation for the number of cells and their meaning:
+  MIPS: Documentation/devicetree/bindings/interrupt-controller/brcm,bcm7038-l1-intc.txt
+  ARM/ARM64: Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt
+
+- interrupt-names: must be "pcie", and if present "msi"
+
+- interrupt-map: see pci.txt
+
+- interrupt-map-mask: see pci.txt
+
+- #address-cells: must be set to <3>, see pci.txt
+
+- #size-cells: must be set to <2>, see pci.txt
+
+- ranges: ranges for the PCI outbound windows, no I/O or prefetchable windows
+  must be specified here, only non-prefetchable. 32-bits windows or 64-bits
+  windows are allowed based on the host processor's capabilities (ARM w/ LPAE,
+  ARM64).
+
+- #interrupt-cells: set to <1>, see pci.txt
+
+- brcm,log2-scb-sizes: log2 size of the SCB window that is mapped to PCIe space
+  there must be exactly one value per memory controller present in the system
+  (ranges from 1 to 3)
+
+Optional properties:
+
+- msi-controller: indicates that this is a MSI controller node (when supported)
+
+- clocks: phandle to the functional clock that feeds into the PCIe RC block
+
+- clock-names: the name(s) of the clocks specified in 'clocks'.  Note
+  that if the 'clocks' property is given, 'clock-names' is mandatory,
+  and the name of the clock is expected to be "pcie".
+
+- brcm,ssc: boolean that indicates usage of spread-spectrum clocking
+
+- brcm,gen: integer that indicates desired forced generation of link: 1 => 2.5
+  Gbps, 2 => 5.0 Gbps, 3 => 8.0 Gbps. Will override the auto-negotation if
+  specified.
+
+- <*>-supply: see Documentation/devicetree/bindings/regulator/regulator.txt
+
+- <*>-supply-names: see Documentation/devicetree/bindings/regulator/regulator.txt
+
+Example Node:
+
+This example assumes that the top-level #address-cells = <2> and #size-cells =
+<2>, e.g: ARM LPAE configuration.
+
+	pcie0: pcie-controller at f0460000 {
+		reg = <0x0 0xf0460000 0x0 0x9310>;
+		interrupts = <0x0 0x33 0x4>, <0x0 0x34, 0x4>;
+		interrupt-names = "pcie", "msi";
+		compatible = "brcm,bcm7445-pcie";
+		#address-cells = <3>;
+		#size-cells = <2>;
+
+		/* Two non-prefetchable 32-bits memory space, each of 128MB
+ 		 * with the following mapping:
+		 * PCIe address		=> CPU physical address space
+		 * 0x00_0000_0000	=> 0x00_C000_0000
+		 * 0x00_0800_0000	=> 0x00_C800_0000
+		 */
+		ranges = <0x02000000 0x00000000 0x00000000 0x00000000 0xc0000000 0x00000000 0x08000000>,
+			 <0x02000000 0x00000000 0x08000000 0x00000000 0xc8000000 0x00000000 0x08000000>;
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0xf800 0 0 7>;
+		interrupt-map = <0 0 0 1 &intc 47 3
+				 0 0 0 2 &intc 48 3
+				 0 0 0 3 &intc 49 3
+				 0 0 0 4 &intc 50 3>;
+		clocks = <&pcie0>;
+		clock-names = "pcie";
+		brcm,ssc;
+		brcm,log2-scb-sizes = <0x1e 0x1e 0x1e>;
+		vreg-wifi-pwr-supply-names = "vreg-wifi-pwr";
+		vreg-wifi-pwr-supply = <&vreg-wifi-pwr>;
+	};
-- 
2.1.0

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

* [PATCH v2 2/2] pci: host: Add Broadcom STB PCIE RC controller
  2016-05-05 19:14 ` Florian Fainelli
@ 2016-05-05 19:15   ` Florian Fainelli
  -1 siblings, 0 replies; 41+ messages in thread
From: Florian Fainelli @ 2016-05-05 19:15 UTC (permalink / raw)
  To: linux-pci
  Cc: linux-kernel, devicetree, linux-arm-kernel,
	bcm-kernel-feedback-list, jim2101024, bhelgaas, arnd,
	Florian Fainelli

From: Jim Quinlan <jim2101024@gmail.com>

This patch adds support for Broadcom's STB SoC PCIE root complex
controller. This controller can be found in MIPS-based chips such as
BCM7425, 7429 and 7435 and ARM-based SoCs such as BCM7445.

This driver enables support for MSI, and S2/S3 suspend/resume modes.

Signed-off-by: Jim Quinlan <jim2101024@gmail.com>
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
Changes in v2:

- separate MSI logic into a different file
- simplify the code to utilize less bookeeping variables
- replaced fixed delays with sleeps instead
- introduce helper functions to deal with read/write config and reset
- get rid of the custom window variables, walk the resource list instead
- utilize OF aliases to determine PCIe root complex id

 MAINTAINERS                         |   1 +
 drivers/pci/host/Kconfig            |  17 +
 drivers/pci/host/Makefile           |   2 +
 drivers/pci/host/pcie-brcmstb-msi.c | 305 ++++++++++++++
 drivers/pci/host/pcie-brcmstb.c     | 769 ++++++++++++++++++++++++++++++++++++
 drivers/pci/host/pcie-brcmstb.h     | 160 ++++++++
 6 files changed, 1254 insertions(+)
 create mode 100644 drivers/pci/host/pcie-brcmstb-msi.c
 create mode 100644 drivers/pci/host/pcie-brcmstb.c
 create mode 100644 drivers/pci/host/pcie-brcmstb.h

diff --git a/MAINTAINERS b/MAINTAINERS
index ecbb2f6a3ba0..503a2a4fa4ad 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2458,6 +2458,7 @@ S:	Maintained
 F:	arch/arm/mach-bcm/*brcmstb*
 F:	arch/arm/boot/dts/bcm7*.dts*
 F:	drivers/bus/brcmstb_gisb.c
+F:	drivers/pci/host/pcie-brcmstb*.[ch]
 N:	brcmstb
 
 BROADCOM BMIPS MIPS ARCHITECTURE
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index 7a0780d56d2d..0964aa0d36e4 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -143,6 +143,23 @@ config PCI_VERSATILE
 	bool "ARM Versatile PB PCI controller"
 	depends on ARCH_VERSATILE
 
+config PCIE_BRCMSTB
+	tristate "Broadcom STB PCIe controller"
+	depends on OF && (ARCH_BRCMSTB || BMIPS_GENERIC)
+	default ARCH_BRCMSTB || BMIPS_GENERIC
+	help
+	  Say Y here if you want to use the Broadcom STB PCIe controller. This
+	  controller supports Broadcom's STB SoCs such a 7425, 7429, 7435 and
+	  7445 and compatible chips.
+
+config PCIE_BRCMSTB_MSI
+	bool "Broadcom STB PCIe MSI feature"
+	depends on PCIE_BRCMSTB && PCI_MSI
+	select PCI_MSI_IRQ_DOMAIN
+	default PCIE_BRCMSTB
+	help
+	  Say Y here if you want PCIe MSI support for the Broadcom STB PCIe RC.
+
 config PCIE_IPROC
 	tristate
 	help
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index d85b5faf9bbc..f51ef13454b4 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -18,6 +18,8 @@ obj-$(CONFIG_PCI_XGENE) += pci-xgene.o
 obj-$(CONFIG_PCI_XGENE_MSI) += pci-xgene-msi.o
 obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o
 obj-$(CONFIG_PCI_VERSATILE) += pci-versatile.o
+obj-$(CONFIG_PCIE_BRCMSTB) += pcie-brcmstb.o
+obj-$(CONFIG_PCIE_BRCMSTB_MSI) += pcie-brcmstb-msi.o
 obj-$(CONFIG_PCIE_IPROC) += pcie-iproc.o
 obj-$(CONFIG_PCIE_IPROC_MSI) += pcie-iproc-msi.o
 obj-$(CONFIG_PCIE_IPROC_PLATFORM) += pcie-iproc-platform.o
diff --git a/drivers/pci/host/pcie-brcmstb-msi.c b/drivers/pci/host/pcie-brcmstb-msi.c
new file mode 100644
index 000000000000..5aa78a10833c
--- /dev/null
+++ b/drivers/pci/host/pcie-brcmstb-msi.c
@@ -0,0 +1,305 @@
+/*
+ * Broadcom STB PCIe root complex MSI driver
+ *
+ * Copyright (C) 2009 - 2016 Broadcom
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/msi.h>
+#include <linux/printk.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <linux/of_pci.h>
+#include <linux/module.h>
+#include <linux/irqdomain.h>
+#include <linux/string.h>
+#include <linux/sizes.h>
+
+#include "pcie-brcmstb.h"
+
+#define BRCM_INT_PCI_MSI_NR		32
+#define BRCM_PCIE_HW_REV_33		0x0303
+#define BRCM_MSI_TARGET_ADDR_LO		0x0
+#define BRCM_MSI_TARGET_ADDR_HI		0xffffffff
+
+struct brcm_msi {
+	struct irq_domain *domain;
+	struct irq_chip irq_chip;
+	struct msi_controller chip;
+	struct brcm_pcie *pcie;
+	struct mutex lock;
+	int irq;
+	/* intr_base is the base pointer for interrupt status/set/clr regs */
+	void __iomem *intr_base;
+	/* intr_legacy_mask indicates how many bits are MSI interrupts */
+	u32 intr_legacy_mask;
+	/* intr_legacy_offset indicates bit position of MSI_01 */
+	u32 intr_legacy_offset;
+	/* used indicates which MSI interrupts have been alloc'd */
+	unsigned long used;
+	/* working indicates that on boot we have brought up MSI */
+	bool working;
+};
+
+static inline struct brcm_msi *to_brcm_msi(struct msi_controller *chip)
+{
+	return container_of(chip, struct brcm_msi, chip);
+}
+
+static int brcm_msi_alloc(struct brcm_msi *chip)
+{
+	int msi;
+
+	mutex_lock(&chip->lock);
+	msi = ~chip->used ? ffz(chip->used) : -1;
+
+	if (msi >= 0 && msi < BRCM_INT_PCI_MSI_NR)
+		chip->used |= (1 << msi);
+	else
+		msi = -ENOSPC;
+
+	mutex_unlock(&chip->lock);
+	return msi;
+}
+
+static void brcm_msi_free(struct brcm_msi *chip, unsigned long irq)
+{
+	mutex_lock(&chip->lock);
+	chip->used &= ~(1 << irq);
+	mutex_unlock(&chip->lock);
+}
+
+static irqreturn_t brcm_pcie_msi_irq(int irq, void *data)
+{
+	struct brcm_pcie *pcie = data;
+	struct brcm_msi *msi = pcie->msi;
+	unsigned long status;
+
+	status = bpcie_readl(msi->intr_base + STATUS) & msi->intr_legacy_mask;
+
+	if (!status)
+		return IRQ_NONE;
+
+	while (status) {
+		unsigned int index = ffs(status) - 1;
+		unsigned int irq;
+
+		/* clear the interrupt */
+		bpcie_writel(1 << index, msi->intr_base + CLR);
+		status &= ~(1 << index);
+
+		/* Account for legacy interrupt offset */
+		index -= msi->intr_legacy_offset;
+
+		irq = irq_find_mapping(msi->domain, index);
+		if (irq) {
+			if (msi->used & (1 << index))
+				generic_handle_irq(irq);
+			else
+				dev_info(pcie->dev, "unhandled MSI %d\n",
+					 index);
+		} else {
+			/* Unknown MSI, just clear it */
+			dev_dbg(pcie->dev, "unexpected MSI\n");
+		}
+	}
+	return IRQ_HANDLED;
+}
+
+static int brcm_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev,
+			      struct msi_desc *desc)
+{
+	struct brcm_msi *msi = to_brcm_msi(chip);
+	struct brcm_pcie *pcie = msi->pcie;
+	struct msi_msg msg;
+	unsigned int irq;
+	int hwirq;
+	u32 data;
+
+	hwirq = brcm_msi_alloc(msi);
+	if (hwirq < 0)
+		return hwirq;
+
+	irq = irq_create_mapping(msi->domain, hwirq);
+	if (!irq) {
+		brcm_msi_free(msi, hwirq);
+		return -EINVAL;
+	}
+
+	irq_set_msi_desc(irq, desc);
+
+	msg.address_lo = BRCM_MSI_TARGET_ADDR_LO;
+	msg.address_hi = BRCM_MSI_TARGET_ADDR_HI;
+	data = bpcie_readl(pcie->base + PCIE_MISC_MSI_DATA_CONFIG);
+	msg.data = ((data >> 16) & (data & 0xffff)) | hwirq;
+	wmb(); /* just being cautious */
+	write_msi_msg(irq, &msg);
+
+	return 0;
+}
+
+static void brcm_msi_teardown_irq(struct msi_controller *chip, unsigned int irq)
+{
+	struct brcm_msi *msi = to_brcm_msi(chip);
+	struct irq_data *d = irq_get_irq_data(irq);
+
+	brcm_msi_free(msi, d->hwirq);
+}
+
+static int brcm_msi_map(struct irq_domain *domain, unsigned int irq,
+			irq_hw_number_t hwirq)
+{
+	struct brcm_pcie *pcie = domain->host_data;
+
+	irq_set_chip_and_handler(irq, &pcie->msi->irq_chip, handle_simple_irq);
+	irq_set_chip_data(irq, domain->host_data);
+
+	return 0;
+}
+
+static const struct irq_domain_ops msi_domain_ops = {
+	.map = brcm_msi_map,
+};
+
+int brcm_pcie_enable_msi(struct brcm_pcie *pcie, int nr)
+{
+	static const char brcm_msi_name[] = "brcmstb_pcieX_msi";
+	struct brcm_msi *msi;
+	u32 data_val;
+	char *name;
+	int err;
+
+	pcie->msi = devm_kzalloc(pcie->dev, sizeof(*msi), GFP_KERNEL);
+	if (!pcie->msi)
+		return -ENODEV;
+
+	msi = pcie->msi;
+	msi->pcie = pcie;
+
+	if (!pcie->suspended) {
+		/* We are only here on cold boot */
+		mutex_init(&msi->lock);
+
+		msi->chip.dev = pcie->dev;
+		msi->chip.setup_irq = brcm_msi_setup_irq;
+		msi->chip.teardown_irq = brcm_msi_teardown_irq;
+
+		/* We have multiple RC controllers.  We may have as many
+		 * MSI controllers for them.  We want each to have a
+		 * unique name, so we go to the trouble of having an
+		 * irq_chip per RC (instead of one for all of them).
+		 */
+		name = devm_kzalloc(pcie->dev, sizeof(brcm_msi_name),
+				    GFP_KERNEL);
+		if (name) {
+			char *p;
+
+			strcpy(name, brcm_msi_name);
+			p = strchr(name, 'X');
+			if (p)
+				*p = '0' + nr;
+			msi->irq_chip.name = name;
+		} else {
+			msi->irq_chip.name = brcm_msi_name;
+		}
+
+		msi->irq_chip.irq_enable = unmask_msi_irq;
+		msi->irq_chip.irq_disable = mask_msi_irq;
+		msi->irq_chip.irq_mask = mask_msi_irq;
+		msi->irq_chip.irq_unmask = unmask_msi_irq;
+
+		msi->domain =
+			irq_domain_add_linear(pcie->dn, BRCM_INT_PCI_MSI_NR,
+					      &msi_domain_ops, pcie);
+		if (!msi->domain) {
+			dev_err(pcie->dev,
+				"failed to create IRQ domain for MSI\n");
+			return -ENOMEM;
+		}
+
+		err = devm_request_irq(pcie->dev, msi->irq, brcm_pcie_msi_irq,
+				       IRQF_SHARED, msi->irq_chip.name,
+				       pcie);
+		if (err < 0) {
+			dev_err(pcie->dev,
+				"failed to request IRQ (%d) for MSI\n",	err);
+			goto msi_en_err;
+		}
+
+		if (pcie->rev >= BRCM_PCIE_HW_REV_33) {
+			msi->intr_base = pcie->base + PCIE_MSI_INTR2_BASE;
+			/* This version of PCIe hw has only 32 intr bits
+			 * starting at bit position 0.
+			 */
+			msi->intr_legacy_mask = 0xffffffff;
+			msi->intr_legacy_offset = 0x0;
+			msi->used = 0x0;
+
+		} else {
+			msi->intr_base = pcie->base + PCIE_INTR2_CPU_BASE;
+			/* This version of PCIe hw has only 8 intr bits starting
+			 * at bit position 24.
+			 */
+			msi->intr_legacy_mask = 0xff000000;
+			msi->intr_legacy_offset = 24;
+			msi->used = 0xffffff00;
+		}
+		msi->working = true;
+	}
+
+	/* If we are here, and msi->working is false, it means that we've
+	 * already tried and failed to bring up MSI.  Just return 0
+	 * since there is nothing to be done.
+	 */
+	if (!msi->working)
+		return 0;
+
+	if (pcie->rev >= BRCM_PCIE_HW_REV_33) {
+		/* ffe0 -- least sig 5 bits are 0 indicating 32 msgs
+		 * 6540 -- this is our arbitrary unique data value
+		 */
+		data_val = 0xffe06540;
+	} else {
+		/* fff8 -- least sig 3 bits are 0 indicating 8 msgs
+		 * 6540 -- this is our arbitrary unique data value
+		 */
+		data_val = 0xfff86540;
+	}
+
+	/* Make sure we are not masking MSIs.  Note that MSIs can be masked,
+	 * but that occurs on the PCIe EP device
+	 */
+	bpcie_writel(0xffffffff & msi->intr_legacy_mask,
+		     msi->intr_base + MASK_CLR);
+
+	/* The 0 bit of BRCM_MSI_TARGET_ADDR_LO is repurposed to MSI enable,
+	 * which we set to 1.
+	 */
+	bpcie_writel(BRCM_MSI_TARGET_ADDR_LO | 1, pcie->base
+		     + PCIE_MISC_MSI_BAR_CONFIG_LO);
+	bpcie_writel(BRCM_MSI_TARGET_ADDR_HI, pcie->base
+		     + PCIE_MISC_MSI_BAR_CONFIG_HI);
+	bpcie_writel(data_val, pcie->base + PCIE_MISC_MSI_DATA_CONFIG);
+
+	return 0;
+
+msi_en_err:
+	irq_domain_remove(msi->domain);
+	return err;
+}
+
+void brcm_pcie_msi_chip_set(struct brcm_pcie *pcie)
+{
+	pcie->bus->msi = &pcie->msi->chip;
+}
diff --git a/drivers/pci/host/pcie-brcmstb.c b/drivers/pci/host/pcie-brcmstb.c
new file mode 100644
index 000000000000..57011e8e772a
--- /dev/null
+++ b/drivers/pci/host/pcie-brcmstb.c
@@ -0,0 +1,769 @@
+/*
+ * Broadcom STB PCIe root complex driver
+ *
+ * Copyright (C) 2009 - 2016 Broadcom
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/compiler.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/msi.h>
+#include <linux/printk.h>
+#include <linux/of_irq.h>
+#include <linux/of_pci.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/sizes.h>
+
+#include "pcie-brcmstb.h"
+
+static void wr_fld(void __iomem *p, u32 mask, int shift, u32 val)
+{
+	u32 reg;
+
+	reg = bpcie_readl(p);
+	reg = (reg & ~mask) | (val << shift);
+	bpcie_writel(reg, p);
+}
+
+static void wr_fld_rb(void __iomem *p, u32 mask, int shift, u32 val)
+{
+	wr_fld(p, mask, shift, val);
+	(void) bpcie_readl(p);
+}
+
+/* Helper macro to define low-level operations for read/write/reset */
+#define PCIE_LL_OPS(name, def) \
+static void name##_pcie_rgr1_sw_init(struct brcm_pcie *pcie, u32 mask,	\
+				      int shift, u32 val)		\
+{									\
+	wr_fld_rb(pcie->base + def##PCIE_RGR1_SW_INIT_1, mask, shift, val); \
+}									\
+static u32 name##_pcie_read_config(struct brcm_pcie *pcie, int cfg_idx) \
+{									\
+	bpcie_writel(cfg_idx, pcie->base + def##PCIE_EXT_CFG_INDEX);	\
+	bpcie_readl(pcie->base + def##PCIE_EXT_CFG_INDEX);		\
+	return bpcie_readl(pcie->base + def##PCIE_EXT_CFG_DATA);	\
+}									\
+static void name##_pcie_write_config(struct brcm_pcie *pcie,		\
+				     int cfg_idx, u32 val)		\
+{									\
+	bpcie_writel(cfg_idx, pcie->base + def##PCIE_EXT_CFG_INDEX);	\
+	bpcie_readl(pcie->base + def##PCIE_EXT_CFG_INDEX);		\
+	bpcie_writel(val, pcie->base + def##PCIE_EXT_CFG_DATA);		\
+	bpcie_readl(pcie->base + def##PCIE_EXT_CFG_DATA);		\
+}
+
+PCIE_LL_OPS(bcm7425, BCM7425_);
+/* Optional second argument */
+PCIE_LL_OPS(gen,);
+
+static const struct brcm_pcie_cfg_data bcm7425_cfg = {
+	.type = BCM7425,
+	.ops = {
+		.read_config = bcm7425_pcie_read_config,
+		.write_config = bcm7425_pcie_write_config,
+		.rgr1_sw_init = bcm7425_pcie_rgr1_sw_init,
+	},
+};
+
+static const struct brcm_pcie_cfg_data bcm7435_cfg = {
+	.type = BCM7435,
+	.ops = {
+		.read_config = gen_pcie_read_config,
+		.write_config = gen_pcie_write_config,
+		.rgr1_sw_init = gen_pcie_rgr1_sw_init,
+	},
+};
+
+static const struct brcm_pcie_cfg_data generic_cfg = {
+	.type = GENERIC,
+	.ops = {
+		.read_config = gen_pcie_read_config,
+		.write_config = gen_pcie_write_config,
+		.rgr1_sw_init = gen_pcie_rgr1_sw_init,
+	},
+};
+
+#if defined(__BIG_ENDIAN)
+#define	DATA_ENDIAN		2	/* PCI->DDR inbound accesses */
+#define MMIO_ENDIAN		2	/* CPU->PCI outbound accesses */
+#else
+#define	DATA_ENDIAN		0
+#define MMIO_ENDIAN		0
+#endif
+
+/* negative return value indicates error */
+static int mdio_read(void __iomem *base, u8 phyad, u8 regad)
+{
+	u32 data = ((phyad & 0xf) << 16)
+		| (regad & 0x1f)
+		| 0x100000;
+
+	bpcie_writel(data, base + PCIE_RC_DL_MDIO_ADDR);
+	bpcie_readl(base + PCIE_RC_DL_MDIO_ADDR);
+
+	data = bpcie_readl(base + PCIE_RC_DL_MDIO_RD_DATA);
+	if (!(data & 0x80000000)) {
+		msleep(1);
+		data = bpcie_readl(base + PCIE_RC_DL_MDIO_RD_DATA);
+	}
+
+	return (data & 0x80000000) ? (data & 0xffff) : -EIO;
+}
+
+/* negative return value indicates error */
+static int mdio_write(void __iomem *base, u8 phyad, u8 regad, u16 wrdata)
+{
+	u32 data = ((phyad & 0xf) << 16) | (regad & 0x1f);
+
+	bpcie_writel(data, base + PCIE_RC_DL_MDIO_ADDR);
+	bpcie_readl(base + PCIE_RC_DL_MDIO_ADDR);
+
+	bpcie_writel(0x80000000 | wrdata, base + PCIE_RC_DL_MDIO_WR_DATA);
+	data = bpcie_readl(base + PCIE_RC_DL_MDIO_WR_DATA);
+	if (!(data & 0x80000000)) {
+		msleep(1);
+		data = bpcie_readl(base + PCIE_RC_DL_MDIO_WR_DATA);
+	}
+
+	return (data & 0x80000000) ? 0 : -EIO;
+}
+
+/* configures device for ssc mode; negative return value indicates error */
+static int set_ssc(void __iomem *base)
+{
+	int tmp;
+	u16 wrdata;
+
+	tmp = mdio_write(base, 0, 0x1f, 0x1100);
+	if (tmp < 0)
+		return tmp;
+
+	tmp = mdio_read(base, 0, 2);
+	if (tmp < 0)
+		return tmp;
+
+	wrdata = ((u16)tmp & 0x3fff) | 0xc000;
+	tmp = mdio_write(base, 0, 2, wrdata);
+	if (tmp < 0)
+		return tmp;
+
+	msleep(1);
+	tmp = mdio_read(base, 0, 1);
+	if (tmp < 0)
+		return tmp;
+
+	return 0;
+}
+
+
+/* returns 0 if in ssc mode, 1 if not, <0 on error */
+static int is_ssc(void __iomem *base)
+{
+	int tmp = mdio_write(base, 0, 0x1f, 0x1100);
+
+	if (tmp < 0)
+		return tmp;
+	tmp = mdio_read(base, 0, 1);
+	if (tmp < 0)
+		return tmp;
+	return (tmp & 0xc00) == 0xc00 ? 0 : 1;
+}
+
+/* limits operation to a specific generation (1, 2, or 3) */
+static void set_gen(void __iomem *base, int gen)
+{
+	wr_fld(base + PCIE_RC_CFG_PCIE_LINK_CAPABILITY, 0xf, 0, gen);
+	wr_fld(base + PCIE_RC_CFG_PCIE_LINK_STATUS_CONTROL_2, 0xf, 0, gen);
+}
+
+static void set_pcie_outbound_win(void __iomem *base, unsigned int win,
+				  u64 start, u64 len)
+{
+	u32 tmp;
+
+	bpcie_writel((u32)(start) + MMIO_ENDIAN,
+		     base + PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO + (win * 8));
+	bpcie_writel((u32)(start >> 32),
+		     base + PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI + (win * 8));
+	tmp = ((((u32)start) >> 20) << 4)
+		| (((((u32)start) + ((u32)len) - 1) >> 20) << 20);
+	bpcie_writel(tmp, base +
+		     PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT + (win * 4));
+}
+
+static int is_pcie_link_up(struct brcm_pcie *pcie)
+{
+	void __iomem *base = pcie->base;
+	u32 val = bpcie_readl(base + PCIE_MISC_PCIE_STATUS);
+
+	return ((val & 0x30) == 0x30) ? 1 : 0;
+}
+
+static int brcm_pcie_setup_early(struct brcm_pcie *pcie)
+{
+	void __iomem *base = pcie->base;
+	struct resource_entry *win;
+	unsigned int scb_size_val;
+	struct resource *r;
+	int i, ret;
+
+	/* reset the bridge and the endpoint device
+	 * field: PCIE_BRIDGE_SW_INIT = 1
+	 */
+	brcm_pcie_rgr1_sw_init(pcie, 0x00000002, 1, 1);
+
+	/* field: PCIE_SW_PERST = 1 */
+	brcm_pcie_rgr1_sw_init(pcie, 0x00000001, 0, 1);
+
+	/* delay 100us */
+	usleep_range(100, 1000);
+
+	/* take the bridge out of reset
+	 * field: PCIE_BRIDGE_SW_INIT = 0
+	 */
+	brcm_pcie_rgr1_sw_init(pcie, 0x00000002, 1, 0);
+
+	/* Grab the PCIe hw revision number */
+	pcie->rev = bpcie_readl(base + PCIE_MISC_REVISION) & 0xffff;
+
+	/* enable SCB_MAX_BURST_SIZE | CSR_READ_UR_MODE | SCB_ACCESS_EN */
+	if (pcie->type == GENERIC)
+		bpcie_writel(0x81e03000, base + PCIE_MISC_MISC_CTRL);
+	else
+		bpcie_writel(0x00103000, base + PCIE_MISC_MISC_CTRL);
+
+	i = 0;
+	resource_list_for_each_entry(win, &pcie->resource) {
+		r = win->res;
+
+		if (!r->flags)
+			continue;
+
+		switch (resource_type(r)) {
+		case IORESOURCE_MEM:
+			/* Program PCIe outbound windows */
+			set_pcie_outbound_win(base, i, r->start,
+					      resource_size(r));
+			i++;
+
+			/* Request memory region resources the first time */
+			if (!pcie->bridge_setup_done) {
+				ret = devm_request_resource(pcie->dev,
+							    &iomem_resource,
+							    r);
+				if (ret)
+					return ret;
+			}
+
+			if (i == BRCM_NUM_PCI_OUT_WINS)
+				dev_warn(pcie->dev,
+					 "exceeded number of windows\n");
+			break;
+
+		default:
+			/* No support for IORESOURCE_IO or IORESOURCE_BUS */
+			continue;
+		}
+	}
+
+	/* set up 4GB PCIE->SCB memory window on BAR2 */
+	bpcie_writel(0x00000011, base + PCIE_MISC_RC_BAR2_CONFIG_LO);
+	bpcie_writel(0x00000000, base + PCIE_MISC_RC_BAR2_CONFIG_HI);
+
+	/* field: SCB0_SIZE, default = 0xf (1 GB) */
+	scb_size_val = pcie->scb_size_vals[0] ? pcie->scb_size_vals[0] : 0xf;
+	wr_fld(base + PCIE_MISC_MISC_CTRL, 0xf8000000, 27, scb_size_val);
+
+	/* field: SCB1_SIZE, default = 0xf (1 GB) */
+	if (pcie->num_memc > 1) {
+		scb_size_val = pcie->scb_size_vals[1]
+			? pcie->scb_size_vals[1] : 0xf;
+		wr_fld(base + PCIE_MISC_MISC_CTRL, 0x07c00000,
+		       22, scb_size_val);
+	}
+
+	/* field: SCB2_SIZE, default = 0xf (1 GB) */
+	if (pcie->num_memc > 2) {
+		scb_size_val = pcie->scb_size_vals[2]
+			? pcie->scb_size_vals[2] : 0xf;
+		wr_fld(base + PCIE_MISC_MISC_CTRL, 0x0000001f,
+		       0, scb_size_val);
+	}
+
+	/* disable the PCIE->GISB memory window */
+	bpcie_writel(0x00000000, base + PCIE_MISC_RC_BAR1_CONFIG_LO);
+
+	/* disable the PCIE->SCB memory window */
+	bpcie_writel(0x00000000, base + PCIE_MISC_RC_BAR3_CONFIG_LO);
+
+	if (!pcie->suspended) {
+		/* clear any interrupts we find on boot */
+		bpcie_writel(0xffffffff, base + PCIE_INTR2_CPU_BASE + CLR);
+		(void) bpcie_readl(base + PCIE_INTR2_CPU_BASE + CLR);
+	}
+
+	/* Mask all interrupts since we are not handling any yet */
+	bpcie_writel(0xffffffff, base + PCIE_INTR2_CPU_BASE + MASK_SET);
+	(void) bpcie_readl(base + PCIE_INTR2_CPU_BASE + MASK_SET);
+
+	if (pcie->ssc)
+		if (set_ssc(base))
+			dev_err(pcie->dev, "error while configuring ssc mode\n");
+	if (pcie->gen)
+		set_gen(base, pcie->gen);
+
+	/* take the EP device out of reset */
+	/* field: PCIE_SW_PERST = 0 */
+	brcm_pcie_rgr1_sw_init(pcie, 0x00000001, 0, 0);
+
+	return 0;
+}
+
+static void brcm_pcie_turn_off(struct brcm_pcie *pcie)
+{
+	void __iomem *base = pcie->base;
+
+	/* Reset endpoint device */
+	brcm_pcie_rgr1_sw_init(pcie, 0x00000001, 0, 1);
+
+	/* deassert request for L23 in case it was asserted */
+	wr_fld_rb(base + PCIE_MISC_PCIE_CTRL, 0x1, 0, 0);
+
+	/* SERDES_IDDQ = 1 */
+	wr_fld_rb(base + PCIE_MISC_HARD_PCIE_HARD_DEBUG, 0x08000000,
+		  27, 1);
+	/* Shutdown PCIe bridge */
+	brcm_pcie_rgr1_sw_init(pcie, 0x00000002, 1, 1);
+}
+
+static void brcm_pcie_enter_l23(struct brcm_pcie *pcie)
+{
+	void __iomem *base = pcie->base;
+	int timeout = 1000;
+	int l23;
+
+	/* assert request for L23 */
+	wr_fld_rb(base + PCIE_MISC_PCIE_CTRL, 0x1, 0, 1);
+	do {
+		/* poll L23 status */
+		l23 = bpcie_readl(base + PCIE_MISC_PCIE_STATUS) & (1 << 6);
+	} while (--timeout && !l23);
+
+	if (!timeout)
+		dev_err(pcie->dev, "failed to enter L23\n");
+}
+
+static int brcm_setup_pcie_bridge(struct brcm_pcie *pcie)
+{
+	static const char *link_speed[4] = { "???", "2.5", "5.0", "8.0" };
+	void __iomem *base = pcie->base;
+	const int limit = pcie->suspended ? 1000 : 100;
+	struct clk *clk;
+	unsigned int status;
+	int i, j, ret;
+	bool ssc_good = false;
+
+	/* Give the RC/EP time to wake up, before trying to configure RC.
+	 * Intermittently check status for link-up, up to a total of 100ms
+	 * when we don't know if the device is there, and up to 1000ms if
+	 * we do know the device is there.
+	 */
+	for (i = 1, j = 0; j < limit && !is_pcie_link_up(pcie); j += i, i = i*2)
+		msleep(i + j > limit ? limit - j : i);
+
+	if (!is_pcie_link_up(pcie)) {
+		dev_info(pcie->dev, "link down\n");
+		goto fail;
+	}
+
+	/* Attempt to enable MSI if we have an interrupt for it. */
+	if (pcie->msi_irq > 0) {
+		ret = brcm_pcie_enable_msi(pcie, pcie->num);
+		if (ret < 0) {
+			dev_err(pcie->dev, "failed to enable MSI support: %d\n",
+				ret);
+		}
+	}
+
+	/* For config space accesses on the RC, show the right class for
+	 * a PCI-PCI bridge
+	 */
+	wr_fld_rb(base + PCIE_RC_CFG_PRIV1_ID_VAL3, 0x00ffffff, 0, 0x060400);
+
+	status = bpcie_readl(base + PCIE_RC_CFG_PCIE_LINK_STATUS_CONTROL);
+
+	if (pcie->ssc) {
+		if (is_ssc(base) == 0)
+			ssc_good = true;
+		else
+			dev_err(pcie->dev, "failed to enter SSC mode\n");
+	}
+
+	dev_info(pcie->dev, "link up, %s Gbps x%u %s\n",
+		 link_speed[((status & 0x000f0000) >> 16) & 0x3],
+		 (status & 0x03f00000) >> 20, ssc_good ? "(SSC)" : "(!SSC)");
+
+	/* Enable configuration request retry (see pci_scan_device()) */
+	/* field RC_CRS_EN = 1
+	 */
+	wr_fld(base + PCIE_RC_CFG_PCIE_ROOT_CAP_CONTROL, 0x00000010, 4, 1);
+
+	/* PCIE->SCB endian mode for BAR ield ENDIAN_MODE_BAR2 = DATA_ENDIAN
+	 */
+	wr_fld_rb(base + PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1, 0x0000000c, 2,
+		  DATA_ENDIAN);
+
+	/* Refclk from RC should be gated with CLKREQ# input when ASPM L0s,L1
+	 * is enabled =>  setting the CLKREQ_DEBUG_ENABLE field to 1.
+	 */
+	wr_fld_rb(base + PCIE_MISC_HARD_PCIE_HARD_DEBUG, 0x00000002, 1, 1);
+
+	/* Add bogus IO resource structure so that pcibios_init_resources()
+	 * does not allocate the same IO region for different domains
+	 */
+
+	pcie->bridge_setup_done = true;
+
+	return 0;
+fail:
+	if (IS_ENABLED(CONFIG_PM))
+		brcm_pcie_turn_off(pcie);
+
+	clk = pcie->clk;
+	if (pcie->suspended)
+		clk_disable(clk);
+	else {
+		clk_disable_unprepare(clk);
+		clk_put(clk);
+	}
+
+	pcie->bridge_setup_done = false;
+
+	return -ENODEV;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int brcm_pcie_suspend(struct device *dev)
+{
+	struct brcm_pcie *pcie = dev_get_drvdata(dev);
+
+	if (!pcie->bridge_setup_done)
+		return 0;
+
+	brcm_pcie_enter_l23(pcie);
+	brcm_pcie_turn_off(pcie);
+	clk_disable(pcie->clk);
+	pcie->suspended = true;
+
+	return 0;
+}
+
+static int brcm_pcie_resume(struct device *dev)
+{
+	struct brcm_pcie *pcie = dev_get_drvdata(dev);
+
+	if (!pcie->bridge_setup_done)
+		return 0;
+
+	/* Take bridge out of reset so we can access the SERDES reg */
+	brcm_pcie_rgr1_sw_init(pcie, 0x00000002, 1, 0);
+
+	/* SERDES_IDDQ = 0 */
+	wr_fld_rb(pcie->base + PCIE_MISC_HARD_PCIE_HARD_DEBUG, 0x08000000,
+		  27, 0);
+	/* wait for serdes to be stable */
+	usleep_range(100, 1000);
+
+	brcm_pcie_setup_early(pcie);
+
+	brcm_setup_pcie_bridge(pcie);
+	pcie->suspended = false;
+
+	return 0;
+}
+
+static const struct dev_pm_ops brcm_pcie_pm_ops = {
+	.suspend_noirq = brcm_pcie_suspend,
+	.resume_noirq = brcm_pcie_resume,
+};
+#else
+#define brcm_pcie_pm_ops	NULL
+#endif /* CONFIG_PM_SLEEP */
+
+static int cfg_index(int busnr, int devfn, int reg)
+{
+	return ((PCI_SLOT(devfn) & 0x1f) << PCI_SLOT_SHIFT)
+		| ((PCI_FUNC(devfn) & 0x07) << PCI_FUNC_SHIFT)
+		| (busnr << PCI_BUSNUM_SHIFT)
+		| (reg & ~3);
+}
+
+static int brcm_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
+				  int where, int size, u32 data)
+{
+	struct brcm_pcie *pcie = bus->sysdata;
+	u32 val = 0, mask, shift;
+	void __iomem *base;
+	bool rc_access;
+	int idx;
+
+	if (!is_pcie_link_up(pcie))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	base = pcie->base;
+
+	rc_access = !!pci_is_root_bus(bus);
+
+	idx = cfg_index(bus->number, devfn, where);
+	WARN_ON(((where & 3) + size) > 4);
+
+	if (rc_access && PCI_SLOT(devfn))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	if (size < 4) {
+		/* partial word - read, modify, write */
+		if (rc_access)
+			val = bpcie_readl(base + (where & ~3));
+		else
+			val = brcm_pcie_ll_read_config(pcie, idx);
+	}
+
+	shift = (where & 3) << 3;
+	mask = (0xffffffff >> ((4 - size) << 3)) << shift;
+	val = (val & ~mask) | ((data << shift) & mask);
+
+	if (rc_access) {
+		bpcie_writel(val, base + (where & ~3));
+		bpcie_readl(base + (where & ~3));
+	} else {
+		brcm_pcie_ll_write_config(pcie, idx, val);
+	}
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int brcm_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
+				 int where, int size, u32 *data)
+{
+	struct brcm_pcie *pcie = bus->sysdata;
+	u32 val, mask, shift;
+	void __iomem *base;
+	bool rc_access;
+	int idx;
+
+	if (!is_pcie_link_up(pcie))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	base = pcie->base;
+
+	rc_access = !!pci_is_root_bus(bus);
+	idx = cfg_index(bus->number, devfn, where);
+	WARN_ON(((where & 3) + size) > 4);
+
+	if (rc_access && PCI_SLOT(devfn)) {
+		*data = 0xffffffff;
+		return PCIBIOS_FUNC_NOT_SUPPORTED;
+	}
+
+	if (rc_access)
+		val = bpcie_readl(base + (where & ~3));
+	else
+		val = brcm_pcie_ll_read_config(pcie, idx);
+
+	shift = (where & 3) << 3;
+	mask = (0xffffffff >> ((4 - size) << 3)) << shift;
+	*data = (val & mask) >> shift;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static const struct of_device_id brcm_pcie_match[] = {
+	{ .compatible = "brcm,bcm7425-pcie", .data = &bcm7425_cfg },
+	{ .compatible = "brcm,bcm7435-pcie", .data = &bcm7435_cfg },
+	{ .compatible = "brcm,bcm7445-pcie", .data = &generic_cfg },
+	{},
+};
+MODULE_DEVICE_TABLE(of, brcm_pcie_match);
+
+static struct pci_ops brcm_pcie_ops = {
+	.read = brcm_pcie_read_config,
+	.write = brcm_pcie_write_config,
+};
+
+static int brcm_pcie_probe(struct platform_device *pdev)
+{
+	struct device_node *dn = pdev->dev.of_node;
+	const u32 *log2_scb_sizes, *dma_ranges;
+	const struct brcm_pcie_cfg_data *data;
+	const struct of_device_id *of_id;
+	struct brcm_pcie *pcie;
+	void __iomem *base;
+	struct resource *r;
+	int i, rlen, ret;
+	u32 tmp;
+
+	pcie = devm_kzalloc(&pdev->dev, sizeof(struct brcm_pcie), GFP_KERNEL);
+	if (!pcie)
+		return -ENOMEM;
+
+	of_id = of_match_node(brcm_pcie_match, dn);
+	if (!of_id)
+		return -EINVAL;
+
+	data = of_id->data;
+	pcie->type = data->type;
+	pcie->ops = &data->ops;
+
+	platform_set_drvdata(pdev, pcie);
+
+	INIT_LIST_HEAD(&pcie->resource);
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	base = devm_ioremap_resource(&pdev->dev, r);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	ret = of_alias_get_id(dn, "pcie");
+	if (ret >= 0)
+		pcie->num = ret;
+
+	pcie->clk = devm_clk_get(&pdev->dev, "pcie");
+	if (IS_ERR(pcie->clk)) {
+		dev_err(&pdev->dev, "could not get clock\n");
+		pcie->clk = NULL;
+	}
+
+	ret = clk_prepare_enable(pcie->clk);
+	if (ret) {
+		dev_err(&pdev->dev, "could not enable clock\n");
+		return ret;
+	}
+
+	pcie->dn = dn;
+	pcie->base = base;
+	pcie->dev = &pdev->dev;
+	pcie->dev->of_node = dn;
+	pcie->gen = 0;
+
+	ret = of_property_read_u32(dn, "brcm,gen", &tmp);
+	if (ret == 0) {
+		if (tmp > 0 && tmp < 3)
+			pcie->gen = (int)tmp;
+		else
+			dev_warn(pcie->dev, "bad DT value for prop 'brcm,gen");
+	} else if (ret != -EINVAL) {
+		dev_warn(pcie->dev, "error reading DT prop 'brcm,gen");
+	}
+
+	pcie->ssc = of_property_read_bool(dn, "brcm,ssc");
+
+	/* Get the value for the log2 of the scb sizes. Subtract 15 from
+	 * each because the target register field has 0==disabled and 1==6KB.
+	 */
+	log2_scb_sizes = of_get_property(dn, "brcm,log2-scb-sizes", &rlen);
+	if (log2_scb_sizes) {
+		for (i = 0; i < rlen / sizeof(u32); i++) {
+			pcie->scb_size_vals[i]
+				= (int)of_read_number(log2_scb_sizes + i, 1)
+					- 15;
+			pcie->num_memc++;
+		}
+	}
+
+	/* Look for the dma-ranges property.  If it exists, issue a warning
+	 * as PCIe drivers may not work.  This is because the identity
+	 * mapping between system memory and PCIe space is not preserved,
+	 * and we need Linux to massage the dma_addr_t values it gets
+	 * from dma memory allocation.  This functionality will be added
+	 * in the near future.
+	 */
+	dma_ranges = of_get_property(dn, "dma-ranges", &rlen);
+	if (dma_ranges != NULL)
+		dev_warn(pcie->dev, "no identity map; PCI drivers may fail");
+
+	if (IS_ENABLED(CONFIG_PCI_MSI)) {
+		ret = irq_of_parse_and_map(pdev->dev.of_node, 1);
+		if (ret == 0)
+			dev_warn(pcie->dev, "cannot get msi intr; MSI disabled\n");
+		else
+			pcie->msi_irq = ret;
+	}
+
+	ret = of_pci_get_host_bridge_resources(dn, 0, 0xff,
+					       &pcie->resource, NULL);
+	if (ret) {
+		dev_err(pcie->dev, "ranges parsing failed\n");
+		return ret;
+	}
+
+	ret = brcm_pcie_setup_early(pcie);
+	if (ret)
+		goto out_err_clk;
+
+	/* If setup bridge fails, it cleans up behind itself */
+	ret = brcm_setup_pcie_bridge(pcie);
+	if (ret)
+		goto out_err;
+
+	pcie->bus = pci_scan_root_bus(pcie->dev, pcie->num, &brcm_pcie_ops,
+				      pcie, &pcie->resource);
+	if (!pcie->bus) {
+		ret = -ENOMEM;
+		goto out_err_bus;
+	}
+
+	if (IS_ENABLED(CONFIG_PCI_MSI))
+		brcm_pcie_msi_chip_set(pcie);
+
+	pci_bus_size_bridges(pcie->bus);
+	pci_bus_assign_resources(pcie->bus);
+
+	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
+	pci_bus_add_devices(pcie->bus);
+
+	return 0;
+
+out_err_bus:
+	brcm_pcie_enter_l23(pcie);
+	brcm_pcie_turn_off(pcie);
+out_err_clk:
+	clk_disable_unprepare(pcie->clk);
+out_err:
+	return ret;
+}
+
+static int brcm_pcie_remove(struct platform_device *pdev)
+{
+	return brcm_pcie_suspend(&pdev->dev);
+}
+
+static struct platform_driver brcm_pcie_driver = {
+	.probe = brcm_pcie_probe,
+	.remove = brcm_pcie_remove,
+	.driver = {
+		.name = "brcm-pcie",
+		.owner = THIS_MODULE,
+		.of_match_table = brcm_pcie_match,
+		.pm = &brcm_pcie_pm_ops,
+	},
+};
+module_platform_driver(brcm_pcie_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Broadcom STB PCIE RC driver");
+MODULE_AUTHOR("Broadcom");
diff --git a/drivers/pci/host/pcie-brcmstb.h b/drivers/pci/host/pcie-brcmstb.h
new file mode 100644
index 000000000000..b4a507423bb0
--- /dev/null
+++ b/drivers/pci/host/pcie-brcmstb.h
@@ -0,0 +1,160 @@
+#ifndef __PCIE_BRCMSTB_H
+#define __PCIE_BRCMSTB_H
+
+#include <linux/io.h>
+
+/* Broadcom PCIE Offsets */
+#define PCIE_RC_CFG_PCIE_LINK_CAPABILITY		0x00b8
+#define PCIE_RC_CFG_PCIE_LINK_STATUS_CONTROL		0x00bc
+#define PCIE_RC_CFG_PCIE_ROOT_CAP_CONTROL		0x00c8
+#define PCIE_RC_CFG_PCIE_LINK_STATUS_CONTROL_2		0x00dc
+#define PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1		0x0188
+#define PCIE_RC_CFG_PRIV1_ID_VAL3			0x043c
+#define PCIE_RC_DL_MDIO_ADDR				0x1100
+#define PCIE_RC_DL_MDIO_WR_DATA				0x1104
+#define PCIE_RC_DL_MDIO_RD_DATA				0x1108
+#define PCIE_MISC_MISC_CTRL				0x4008
+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO		0x400c
+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI		0x4010
+#define PCIE_MISC_RC_BAR1_CONFIG_LO			0x402c
+#define PCIE_MISC_RC_BAR1_CONFIG_HI			0x4030
+#define PCIE_MISC_RC_BAR2_CONFIG_LO			0x4034
+#define PCIE_MISC_RC_BAR2_CONFIG_HI			0x4038
+#define PCIE_MISC_RC_BAR3_CONFIG_LO			0x403c
+#define PCIE_MISC_RC_BAR3_CONFIG_HI			0x4040
+#define PCIE_MISC_MSI_BAR_CONFIG_LO			0x4044
+#define PCIE_MISC_MSI_BAR_CONFIG_HI			0x4048
+#define PCIE_MISC_MSI_DATA_CONFIG			0x404c
+#define PCIE_MISC_PCIE_CTRL				0x4064
+#define PCIE_MISC_PCIE_STATUS				0x4068
+#define PCIE_MISC_REVISION				0x406c
+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT	0x4070
+#define PCIE_MISC_HARD_PCIE_HARD_DEBUG			0x4204
+#define PCIE_INTR2_CPU_BASE				0x4300
+#define PCIE_MSI_INTR2_BASE				0x4500
+
+#define PCIE_RGR1_SW_INIT_1				0x9210
+#define PCIE_EXT_CFG_INDEX				0x9000
+#define PCIE_EXT_CFG_DATA				0x9004
+
+/* BCM7425 specific register offsets */
+#define BCM7425_PCIE_RGR1_SW_INIT_1			0x8010
+#define BCM7425_PCIE_EXT_CFG_INDEX			0x8300
+#define BCM7425_PCIE_EXT_CFG_DATA			0x8304
+
+#define PCI_BUSNUM_SHIFT		20
+#define PCI_SLOT_SHIFT			15
+#define PCI_FUNC_SHIFT			12
+
+#define BRCM_NUM_PCI_OUT_WINS		4
+#define BRCM_MAX_SCB			4
+
+/* Offsets from PCIE_INTR2_CPU_BASE and PCIE_MSI_INTR2_BASE */
+#define STATUS				0x0
+#define SET				0x4
+#define CLR				0x8
+#define MASK_STATUS			0xc
+#define MASK_SET			0x10
+#define MASK_CLR			0x14
+
+enum brcm_pcie_type {
+	BCM7425,
+	BCM7435,
+	GENERIC,
+};
+
+struct brcm_pcie;
+
+/* Chip-specific PCIe operations (read/write config and reset) */
+struct brcm_pcie_ll_ops {
+	u32 (*read_config)(struct brcm_pcie *pcie, int cfg_idx);
+	void (*write_config)(struct brcm_pcie *pcie, int cfg_idx, u32 val);
+	void (*rgr1_sw_init)(struct brcm_pcie *pcie, u32 mask,
+			     int shift, u32 val);
+};
+
+struct brcm_pcie_cfg_data {
+	const enum brcm_pcie_type type;
+	const struct brcm_pcie_ll_ops ops;
+};
+
+struct brcm_msi;
+
+/* Internal Bus Controller Information.*/
+struct brcm_pcie {
+	void __iomem		*base;
+	bool			suspended;
+	struct clk		*clk;
+	struct device_node	*dn;
+	bool			ssc;
+	int			gen;
+	int			scb_size_vals[BRCM_MAX_SCB];
+	struct pci_bus		*bus;
+	struct device		*dev;
+	struct list_head	resource;
+	int			msi_irq;
+	struct brcm_msi		*msi;
+	unsigned int		rev;
+	unsigned int		num;
+	bool			bridge_setup_done;
+	enum brcm_pcie_type	type;
+	const struct brcm_pcie_ll_ops *ops;
+	unsigned int		num_memc;
+};
+
+/* Helper functions to access read/write config space and software init which
+ * are chip-specific
+ */
+static inline u32 brcm_pcie_ll_read_config(struct brcm_pcie *pcie, int cfg_idx)
+{
+	return pcie->ops->read_config(pcie, cfg_idx);
+}
+
+static inline void brcm_pcie_ll_write_config(struct brcm_pcie *pcie,
+					     int cfg_idx, u32 val)
+{
+	pcie->ops->write_config(pcie, cfg_idx, val);
+}
+
+static inline void brcm_pcie_rgr1_sw_init(struct brcm_pcie *pcie, u32 mask,
+					  int shift, u32 val)
+{
+	pcie->ops->rgr1_sw_init(pcie, mask, shift, val);
+}
+
+/*
+ * MIPS endianness is configured by boot strap, which also reverses all
+ * bus endianness (i.e., big-endian CPU + big endian bus ==> native
+ * endian I/O).
+ *
+ * Other architectures (e.g., ARM) either do not support big endian, or
+ * else leave I/O in little endian mode.
+ */
+static inline u32 bpcie_readl(void __iomem *base)
+{
+	if (IS_ENABLED(CONFIG_MIPS))
+		return __raw_readl(base);
+	else
+		return readl(base);
+}
+
+static inline void bpcie_writel(u32 val, void __iomem *base)
+{
+	if (IS_ENABLED(CONFIG_MIPS))
+		__raw_writel(val, base);
+	else
+		writel(val, base);
+}
+
+#ifdef CONFIG_PCIE_BRCMSTB_MSI
+int brcm_pcie_enable_msi(struct brcm_pcie *pcie, int nr);
+void brcm_pcie_msi_chip_set(struct brcm_pcie *pcie);
+#else
+static inline int brcm_pcie_enable_msi(struct brcm_pcie *pcie, int nr)
+{
+	return 0;
+}
+static inline void brcm_pcie_msi_chip_set(struct brcm_pcie *pcie) { }
+#endif
+
+#endif /* __PCIE_BRCMSTB_H */
-- 
2.1.0

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

* [PATCH v2 2/2] pci: host: Add Broadcom STB PCIE RC controller
@ 2016-05-05 19:15   ` Florian Fainelli
  0 siblings, 0 replies; 41+ messages in thread
From: Florian Fainelli @ 2016-05-05 19:15 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jim Quinlan <jim2101024@gmail.com>

This patch adds support for Broadcom's STB SoC PCIE root complex
controller. This controller can be found in MIPS-based chips such as
BCM7425, 7429 and 7435 and ARM-based SoCs such as BCM7445.

This driver enables support for MSI, and S2/S3 suspend/resume modes.

Signed-off-by: Jim Quinlan <jim2101024@gmail.com>
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
Changes in v2:

- separate MSI logic into a different file
- simplify the code to utilize less bookeeping variables
- replaced fixed delays with sleeps instead
- introduce helper functions to deal with read/write config and reset
- get rid of the custom window variables, walk the resource list instead
- utilize OF aliases to determine PCIe root complex id

 MAINTAINERS                         |   1 +
 drivers/pci/host/Kconfig            |  17 +
 drivers/pci/host/Makefile           |   2 +
 drivers/pci/host/pcie-brcmstb-msi.c | 305 ++++++++++++++
 drivers/pci/host/pcie-brcmstb.c     | 769 ++++++++++++++++++++++++++++++++++++
 drivers/pci/host/pcie-brcmstb.h     | 160 ++++++++
 6 files changed, 1254 insertions(+)
 create mode 100644 drivers/pci/host/pcie-brcmstb-msi.c
 create mode 100644 drivers/pci/host/pcie-brcmstb.c
 create mode 100644 drivers/pci/host/pcie-brcmstb.h

diff --git a/MAINTAINERS b/MAINTAINERS
index ecbb2f6a3ba0..503a2a4fa4ad 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2458,6 +2458,7 @@ S:	Maintained
 F:	arch/arm/mach-bcm/*brcmstb*
 F:	arch/arm/boot/dts/bcm7*.dts*
 F:	drivers/bus/brcmstb_gisb.c
+F:	drivers/pci/host/pcie-brcmstb*.[ch]
 N:	brcmstb
 
 BROADCOM BMIPS MIPS ARCHITECTURE
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index 7a0780d56d2d..0964aa0d36e4 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -143,6 +143,23 @@ config PCI_VERSATILE
 	bool "ARM Versatile PB PCI controller"
 	depends on ARCH_VERSATILE
 
+config PCIE_BRCMSTB
+	tristate "Broadcom STB PCIe controller"
+	depends on OF && (ARCH_BRCMSTB || BMIPS_GENERIC)
+	default ARCH_BRCMSTB || BMIPS_GENERIC
+	help
+	  Say Y here if you want to use the Broadcom STB PCIe controller. This
+	  controller supports Broadcom's STB SoCs such a 7425, 7429, 7435 and
+	  7445 and compatible chips.
+
+config PCIE_BRCMSTB_MSI
+	bool "Broadcom STB PCIe MSI feature"
+	depends on PCIE_BRCMSTB && PCI_MSI
+	select PCI_MSI_IRQ_DOMAIN
+	default PCIE_BRCMSTB
+	help
+	  Say Y here if you want PCIe MSI support for the Broadcom STB PCIe RC.
+
 config PCIE_IPROC
 	tristate
 	help
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index d85b5faf9bbc..f51ef13454b4 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -18,6 +18,8 @@ obj-$(CONFIG_PCI_XGENE) += pci-xgene.o
 obj-$(CONFIG_PCI_XGENE_MSI) += pci-xgene-msi.o
 obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o
 obj-$(CONFIG_PCI_VERSATILE) += pci-versatile.o
+obj-$(CONFIG_PCIE_BRCMSTB) += pcie-brcmstb.o
+obj-$(CONFIG_PCIE_BRCMSTB_MSI) += pcie-brcmstb-msi.o
 obj-$(CONFIG_PCIE_IPROC) += pcie-iproc.o
 obj-$(CONFIG_PCIE_IPROC_MSI) += pcie-iproc-msi.o
 obj-$(CONFIG_PCIE_IPROC_PLATFORM) += pcie-iproc-platform.o
diff --git a/drivers/pci/host/pcie-brcmstb-msi.c b/drivers/pci/host/pcie-brcmstb-msi.c
new file mode 100644
index 000000000000..5aa78a10833c
--- /dev/null
+++ b/drivers/pci/host/pcie-brcmstb-msi.c
@@ -0,0 +1,305 @@
+/*
+ * Broadcom STB PCIe root complex MSI driver
+ *
+ * Copyright (C) 2009 - 2016 Broadcom
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/msi.h>
+#include <linux/printk.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <linux/of_pci.h>
+#include <linux/module.h>
+#include <linux/irqdomain.h>
+#include <linux/string.h>
+#include <linux/sizes.h>
+
+#include "pcie-brcmstb.h"
+
+#define BRCM_INT_PCI_MSI_NR		32
+#define BRCM_PCIE_HW_REV_33		0x0303
+#define BRCM_MSI_TARGET_ADDR_LO		0x0
+#define BRCM_MSI_TARGET_ADDR_HI		0xffffffff
+
+struct brcm_msi {
+	struct irq_domain *domain;
+	struct irq_chip irq_chip;
+	struct msi_controller chip;
+	struct brcm_pcie *pcie;
+	struct mutex lock;
+	int irq;
+	/* intr_base is the base pointer for interrupt status/set/clr regs */
+	void __iomem *intr_base;
+	/* intr_legacy_mask indicates how many bits are MSI interrupts */
+	u32 intr_legacy_mask;
+	/* intr_legacy_offset indicates bit position of MSI_01 */
+	u32 intr_legacy_offset;
+	/* used indicates which MSI interrupts have been alloc'd */
+	unsigned long used;
+	/* working indicates that on boot we have brought up MSI */
+	bool working;
+};
+
+static inline struct brcm_msi *to_brcm_msi(struct msi_controller *chip)
+{
+	return container_of(chip, struct brcm_msi, chip);
+}
+
+static int brcm_msi_alloc(struct brcm_msi *chip)
+{
+	int msi;
+
+	mutex_lock(&chip->lock);
+	msi = ~chip->used ? ffz(chip->used) : -1;
+
+	if (msi >= 0 && msi < BRCM_INT_PCI_MSI_NR)
+		chip->used |= (1 << msi);
+	else
+		msi = -ENOSPC;
+
+	mutex_unlock(&chip->lock);
+	return msi;
+}
+
+static void brcm_msi_free(struct brcm_msi *chip, unsigned long irq)
+{
+	mutex_lock(&chip->lock);
+	chip->used &= ~(1 << irq);
+	mutex_unlock(&chip->lock);
+}
+
+static irqreturn_t brcm_pcie_msi_irq(int irq, void *data)
+{
+	struct brcm_pcie *pcie = data;
+	struct brcm_msi *msi = pcie->msi;
+	unsigned long status;
+
+	status = bpcie_readl(msi->intr_base + STATUS) & msi->intr_legacy_mask;
+
+	if (!status)
+		return IRQ_NONE;
+
+	while (status) {
+		unsigned int index = ffs(status) - 1;
+		unsigned int irq;
+
+		/* clear the interrupt */
+		bpcie_writel(1 << index, msi->intr_base + CLR);
+		status &= ~(1 << index);
+
+		/* Account for legacy interrupt offset */
+		index -= msi->intr_legacy_offset;
+
+		irq = irq_find_mapping(msi->domain, index);
+		if (irq) {
+			if (msi->used & (1 << index))
+				generic_handle_irq(irq);
+			else
+				dev_info(pcie->dev, "unhandled MSI %d\n",
+					 index);
+		} else {
+			/* Unknown MSI, just clear it */
+			dev_dbg(pcie->dev, "unexpected MSI\n");
+		}
+	}
+	return IRQ_HANDLED;
+}
+
+static int brcm_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev,
+			      struct msi_desc *desc)
+{
+	struct brcm_msi *msi = to_brcm_msi(chip);
+	struct brcm_pcie *pcie = msi->pcie;
+	struct msi_msg msg;
+	unsigned int irq;
+	int hwirq;
+	u32 data;
+
+	hwirq = brcm_msi_alloc(msi);
+	if (hwirq < 0)
+		return hwirq;
+
+	irq = irq_create_mapping(msi->domain, hwirq);
+	if (!irq) {
+		brcm_msi_free(msi, hwirq);
+		return -EINVAL;
+	}
+
+	irq_set_msi_desc(irq, desc);
+
+	msg.address_lo = BRCM_MSI_TARGET_ADDR_LO;
+	msg.address_hi = BRCM_MSI_TARGET_ADDR_HI;
+	data = bpcie_readl(pcie->base + PCIE_MISC_MSI_DATA_CONFIG);
+	msg.data = ((data >> 16) & (data & 0xffff)) | hwirq;
+	wmb(); /* just being cautious */
+	write_msi_msg(irq, &msg);
+
+	return 0;
+}
+
+static void brcm_msi_teardown_irq(struct msi_controller *chip, unsigned int irq)
+{
+	struct brcm_msi *msi = to_brcm_msi(chip);
+	struct irq_data *d = irq_get_irq_data(irq);
+
+	brcm_msi_free(msi, d->hwirq);
+}
+
+static int brcm_msi_map(struct irq_domain *domain, unsigned int irq,
+			irq_hw_number_t hwirq)
+{
+	struct brcm_pcie *pcie = domain->host_data;
+
+	irq_set_chip_and_handler(irq, &pcie->msi->irq_chip, handle_simple_irq);
+	irq_set_chip_data(irq, domain->host_data);
+
+	return 0;
+}
+
+static const struct irq_domain_ops msi_domain_ops = {
+	.map = brcm_msi_map,
+};
+
+int brcm_pcie_enable_msi(struct brcm_pcie *pcie, int nr)
+{
+	static const char brcm_msi_name[] = "brcmstb_pcieX_msi";
+	struct brcm_msi *msi;
+	u32 data_val;
+	char *name;
+	int err;
+
+	pcie->msi = devm_kzalloc(pcie->dev, sizeof(*msi), GFP_KERNEL);
+	if (!pcie->msi)
+		return -ENODEV;
+
+	msi = pcie->msi;
+	msi->pcie = pcie;
+
+	if (!pcie->suspended) {
+		/* We are only here on cold boot */
+		mutex_init(&msi->lock);
+
+		msi->chip.dev = pcie->dev;
+		msi->chip.setup_irq = brcm_msi_setup_irq;
+		msi->chip.teardown_irq = brcm_msi_teardown_irq;
+
+		/* We have multiple RC controllers.  We may have as many
+		 * MSI controllers for them.  We want each to have a
+		 * unique name, so we go to the trouble of having an
+		 * irq_chip per RC (instead of one for all of them).
+		 */
+		name = devm_kzalloc(pcie->dev, sizeof(brcm_msi_name),
+				    GFP_KERNEL);
+		if (name) {
+			char *p;
+
+			strcpy(name, brcm_msi_name);
+			p = strchr(name, 'X');
+			if (p)
+				*p = '0' + nr;
+			msi->irq_chip.name = name;
+		} else {
+			msi->irq_chip.name = brcm_msi_name;
+		}
+
+		msi->irq_chip.irq_enable = unmask_msi_irq;
+		msi->irq_chip.irq_disable = mask_msi_irq;
+		msi->irq_chip.irq_mask = mask_msi_irq;
+		msi->irq_chip.irq_unmask = unmask_msi_irq;
+
+		msi->domain =
+			irq_domain_add_linear(pcie->dn, BRCM_INT_PCI_MSI_NR,
+					      &msi_domain_ops, pcie);
+		if (!msi->domain) {
+			dev_err(pcie->dev,
+				"failed to create IRQ domain for MSI\n");
+			return -ENOMEM;
+		}
+
+		err = devm_request_irq(pcie->dev, msi->irq, brcm_pcie_msi_irq,
+				       IRQF_SHARED, msi->irq_chip.name,
+				       pcie);
+		if (err < 0) {
+			dev_err(pcie->dev,
+				"failed to request IRQ (%d) for MSI\n",	err);
+			goto msi_en_err;
+		}
+
+		if (pcie->rev >= BRCM_PCIE_HW_REV_33) {
+			msi->intr_base = pcie->base + PCIE_MSI_INTR2_BASE;
+			/* This version of PCIe hw has only 32 intr bits
+			 * starting at bit position 0.
+			 */
+			msi->intr_legacy_mask = 0xffffffff;
+			msi->intr_legacy_offset = 0x0;
+			msi->used = 0x0;
+
+		} else {
+			msi->intr_base = pcie->base + PCIE_INTR2_CPU_BASE;
+			/* This version of PCIe hw has only 8 intr bits starting
+			 * at bit position 24.
+			 */
+			msi->intr_legacy_mask = 0xff000000;
+			msi->intr_legacy_offset = 24;
+			msi->used = 0xffffff00;
+		}
+		msi->working = true;
+	}
+
+	/* If we are here, and msi->working is false, it means that we've
+	 * already tried and failed to bring up MSI.  Just return 0
+	 * since there is nothing to be done.
+	 */
+	if (!msi->working)
+		return 0;
+
+	if (pcie->rev >= BRCM_PCIE_HW_REV_33) {
+		/* ffe0 -- least sig 5 bits are 0 indicating 32 msgs
+		 * 6540 -- this is our arbitrary unique data value
+		 */
+		data_val = 0xffe06540;
+	} else {
+		/* fff8 -- least sig 3 bits are 0 indicating 8 msgs
+		 * 6540 -- this is our arbitrary unique data value
+		 */
+		data_val = 0xfff86540;
+	}
+
+	/* Make sure we are not masking MSIs.  Note that MSIs can be masked,
+	 * but that occurs on the PCIe EP device
+	 */
+	bpcie_writel(0xffffffff & msi->intr_legacy_mask,
+		     msi->intr_base + MASK_CLR);
+
+	/* The 0 bit of BRCM_MSI_TARGET_ADDR_LO is repurposed to MSI enable,
+	 * which we set to 1.
+	 */
+	bpcie_writel(BRCM_MSI_TARGET_ADDR_LO | 1, pcie->base
+		     + PCIE_MISC_MSI_BAR_CONFIG_LO);
+	bpcie_writel(BRCM_MSI_TARGET_ADDR_HI, pcie->base
+		     + PCIE_MISC_MSI_BAR_CONFIG_HI);
+	bpcie_writel(data_val, pcie->base + PCIE_MISC_MSI_DATA_CONFIG);
+
+	return 0;
+
+msi_en_err:
+	irq_domain_remove(msi->domain);
+	return err;
+}
+
+void brcm_pcie_msi_chip_set(struct brcm_pcie *pcie)
+{
+	pcie->bus->msi = &pcie->msi->chip;
+}
diff --git a/drivers/pci/host/pcie-brcmstb.c b/drivers/pci/host/pcie-brcmstb.c
new file mode 100644
index 000000000000..57011e8e772a
--- /dev/null
+++ b/drivers/pci/host/pcie-brcmstb.c
@@ -0,0 +1,769 @@
+/*
+ * Broadcom STB PCIe root complex driver
+ *
+ * Copyright (C) 2009 - 2016 Broadcom
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/compiler.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/msi.h>
+#include <linux/printk.h>
+#include <linux/of_irq.h>
+#include <linux/of_pci.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/sizes.h>
+
+#include "pcie-brcmstb.h"
+
+static void wr_fld(void __iomem *p, u32 mask, int shift, u32 val)
+{
+	u32 reg;
+
+	reg = bpcie_readl(p);
+	reg = (reg & ~mask) | (val << shift);
+	bpcie_writel(reg, p);
+}
+
+static void wr_fld_rb(void __iomem *p, u32 mask, int shift, u32 val)
+{
+	wr_fld(p, mask, shift, val);
+	(void) bpcie_readl(p);
+}
+
+/* Helper macro to define low-level operations for read/write/reset */
+#define PCIE_LL_OPS(name, def) \
+static void name##_pcie_rgr1_sw_init(struct brcm_pcie *pcie, u32 mask,	\
+				      int shift, u32 val)		\
+{									\
+	wr_fld_rb(pcie->base + def##PCIE_RGR1_SW_INIT_1, mask, shift, val); \
+}									\
+static u32 name##_pcie_read_config(struct brcm_pcie *pcie, int cfg_idx) \
+{									\
+	bpcie_writel(cfg_idx, pcie->base + def##PCIE_EXT_CFG_INDEX);	\
+	bpcie_readl(pcie->base + def##PCIE_EXT_CFG_INDEX);		\
+	return bpcie_readl(pcie->base + def##PCIE_EXT_CFG_DATA);	\
+}									\
+static void name##_pcie_write_config(struct brcm_pcie *pcie,		\
+				     int cfg_idx, u32 val)		\
+{									\
+	bpcie_writel(cfg_idx, pcie->base + def##PCIE_EXT_CFG_INDEX);	\
+	bpcie_readl(pcie->base + def##PCIE_EXT_CFG_INDEX);		\
+	bpcie_writel(val, pcie->base + def##PCIE_EXT_CFG_DATA);		\
+	bpcie_readl(pcie->base + def##PCIE_EXT_CFG_DATA);		\
+}
+
+PCIE_LL_OPS(bcm7425, BCM7425_);
+/* Optional second argument */
+PCIE_LL_OPS(gen,);
+
+static const struct brcm_pcie_cfg_data bcm7425_cfg = {
+	.type = BCM7425,
+	.ops = {
+		.read_config = bcm7425_pcie_read_config,
+		.write_config = bcm7425_pcie_write_config,
+		.rgr1_sw_init = bcm7425_pcie_rgr1_sw_init,
+	},
+};
+
+static const struct brcm_pcie_cfg_data bcm7435_cfg = {
+	.type = BCM7435,
+	.ops = {
+		.read_config = gen_pcie_read_config,
+		.write_config = gen_pcie_write_config,
+		.rgr1_sw_init = gen_pcie_rgr1_sw_init,
+	},
+};
+
+static const struct brcm_pcie_cfg_data generic_cfg = {
+	.type = GENERIC,
+	.ops = {
+		.read_config = gen_pcie_read_config,
+		.write_config = gen_pcie_write_config,
+		.rgr1_sw_init = gen_pcie_rgr1_sw_init,
+	},
+};
+
+#if defined(__BIG_ENDIAN)
+#define	DATA_ENDIAN		2	/* PCI->DDR inbound accesses */
+#define MMIO_ENDIAN		2	/* CPU->PCI outbound accesses */
+#else
+#define	DATA_ENDIAN		0
+#define MMIO_ENDIAN		0
+#endif
+
+/* negative return value indicates error */
+static int mdio_read(void __iomem *base, u8 phyad, u8 regad)
+{
+	u32 data = ((phyad & 0xf) << 16)
+		| (regad & 0x1f)
+		| 0x100000;
+
+	bpcie_writel(data, base + PCIE_RC_DL_MDIO_ADDR);
+	bpcie_readl(base + PCIE_RC_DL_MDIO_ADDR);
+
+	data = bpcie_readl(base + PCIE_RC_DL_MDIO_RD_DATA);
+	if (!(data & 0x80000000)) {
+		msleep(1);
+		data = bpcie_readl(base + PCIE_RC_DL_MDIO_RD_DATA);
+	}
+
+	return (data & 0x80000000) ? (data & 0xffff) : -EIO;
+}
+
+/* negative return value indicates error */
+static int mdio_write(void __iomem *base, u8 phyad, u8 regad, u16 wrdata)
+{
+	u32 data = ((phyad & 0xf) << 16) | (regad & 0x1f);
+
+	bpcie_writel(data, base + PCIE_RC_DL_MDIO_ADDR);
+	bpcie_readl(base + PCIE_RC_DL_MDIO_ADDR);
+
+	bpcie_writel(0x80000000 | wrdata, base + PCIE_RC_DL_MDIO_WR_DATA);
+	data = bpcie_readl(base + PCIE_RC_DL_MDIO_WR_DATA);
+	if (!(data & 0x80000000)) {
+		msleep(1);
+		data = bpcie_readl(base + PCIE_RC_DL_MDIO_WR_DATA);
+	}
+
+	return (data & 0x80000000) ? 0 : -EIO;
+}
+
+/* configures device for ssc mode; negative return value indicates error */
+static int set_ssc(void __iomem *base)
+{
+	int tmp;
+	u16 wrdata;
+
+	tmp = mdio_write(base, 0, 0x1f, 0x1100);
+	if (tmp < 0)
+		return tmp;
+
+	tmp = mdio_read(base, 0, 2);
+	if (tmp < 0)
+		return tmp;
+
+	wrdata = ((u16)tmp & 0x3fff) | 0xc000;
+	tmp = mdio_write(base, 0, 2, wrdata);
+	if (tmp < 0)
+		return tmp;
+
+	msleep(1);
+	tmp = mdio_read(base, 0, 1);
+	if (tmp < 0)
+		return tmp;
+
+	return 0;
+}
+
+
+/* returns 0 if in ssc mode, 1 if not, <0 on error */
+static int is_ssc(void __iomem *base)
+{
+	int tmp = mdio_write(base, 0, 0x1f, 0x1100);
+
+	if (tmp < 0)
+		return tmp;
+	tmp = mdio_read(base, 0, 1);
+	if (tmp < 0)
+		return tmp;
+	return (tmp & 0xc00) == 0xc00 ? 0 : 1;
+}
+
+/* limits operation to a specific generation (1, 2, or 3) */
+static void set_gen(void __iomem *base, int gen)
+{
+	wr_fld(base + PCIE_RC_CFG_PCIE_LINK_CAPABILITY, 0xf, 0, gen);
+	wr_fld(base + PCIE_RC_CFG_PCIE_LINK_STATUS_CONTROL_2, 0xf, 0, gen);
+}
+
+static void set_pcie_outbound_win(void __iomem *base, unsigned int win,
+				  u64 start, u64 len)
+{
+	u32 tmp;
+
+	bpcie_writel((u32)(start) + MMIO_ENDIAN,
+		     base + PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO + (win * 8));
+	bpcie_writel((u32)(start >> 32),
+		     base + PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI + (win * 8));
+	tmp = ((((u32)start) >> 20) << 4)
+		| (((((u32)start) + ((u32)len) - 1) >> 20) << 20);
+	bpcie_writel(tmp, base +
+		     PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT + (win * 4));
+}
+
+static int is_pcie_link_up(struct brcm_pcie *pcie)
+{
+	void __iomem *base = pcie->base;
+	u32 val = bpcie_readl(base + PCIE_MISC_PCIE_STATUS);
+
+	return ((val & 0x30) == 0x30) ? 1 : 0;
+}
+
+static int brcm_pcie_setup_early(struct brcm_pcie *pcie)
+{
+	void __iomem *base = pcie->base;
+	struct resource_entry *win;
+	unsigned int scb_size_val;
+	struct resource *r;
+	int i, ret;
+
+	/* reset the bridge and the endpoint device
+	 * field: PCIE_BRIDGE_SW_INIT = 1
+	 */
+	brcm_pcie_rgr1_sw_init(pcie, 0x00000002, 1, 1);
+
+	/* field: PCIE_SW_PERST = 1 */
+	brcm_pcie_rgr1_sw_init(pcie, 0x00000001, 0, 1);
+
+	/* delay 100us */
+	usleep_range(100, 1000);
+
+	/* take the bridge out of reset
+	 * field: PCIE_BRIDGE_SW_INIT = 0
+	 */
+	brcm_pcie_rgr1_sw_init(pcie, 0x00000002, 1, 0);
+
+	/* Grab the PCIe hw revision number */
+	pcie->rev = bpcie_readl(base + PCIE_MISC_REVISION) & 0xffff;
+
+	/* enable SCB_MAX_BURST_SIZE | CSR_READ_UR_MODE | SCB_ACCESS_EN */
+	if (pcie->type == GENERIC)
+		bpcie_writel(0x81e03000, base + PCIE_MISC_MISC_CTRL);
+	else
+		bpcie_writel(0x00103000, base + PCIE_MISC_MISC_CTRL);
+
+	i = 0;
+	resource_list_for_each_entry(win, &pcie->resource) {
+		r = win->res;
+
+		if (!r->flags)
+			continue;
+
+		switch (resource_type(r)) {
+		case IORESOURCE_MEM:
+			/* Program PCIe outbound windows */
+			set_pcie_outbound_win(base, i, r->start,
+					      resource_size(r));
+			i++;
+
+			/* Request memory region resources the first time */
+			if (!pcie->bridge_setup_done) {
+				ret = devm_request_resource(pcie->dev,
+							    &iomem_resource,
+							    r);
+				if (ret)
+					return ret;
+			}
+
+			if (i == BRCM_NUM_PCI_OUT_WINS)
+				dev_warn(pcie->dev,
+					 "exceeded number of windows\n");
+			break;
+
+		default:
+			/* No support for IORESOURCE_IO or IORESOURCE_BUS */
+			continue;
+		}
+	}
+
+	/* set up 4GB PCIE->SCB memory window on BAR2 */
+	bpcie_writel(0x00000011, base + PCIE_MISC_RC_BAR2_CONFIG_LO);
+	bpcie_writel(0x00000000, base + PCIE_MISC_RC_BAR2_CONFIG_HI);
+
+	/* field: SCB0_SIZE, default = 0xf (1 GB) */
+	scb_size_val = pcie->scb_size_vals[0] ? pcie->scb_size_vals[0] : 0xf;
+	wr_fld(base + PCIE_MISC_MISC_CTRL, 0xf8000000, 27, scb_size_val);
+
+	/* field: SCB1_SIZE, default = 0xf (1 GB) */
+	if (pcie->num_memc > 1) {
+		scb_size_val = pcie->scb_size_vals[1]
+			? pcie->scb_size_vals[1] : 0xf;
+		wr_fld(base + PCIE_MISC_MISC_CTRL, 0x07c00000,
+		       22, scb_size_val);
+	}
+
+	/* field: SCB2_SIZE, default = 0xf (1 GB) */
+	if (pcie->num_memc > 2) {
+		scb_size_val = pcie->scb_size_vals[2]
+			? pcie->scb_size_vals[2] : 0xf;
+		wr_fld(base + PCIE_MISC_MISC_CTRL, 0x0000001f,
+		       0, scb_size_val);
+	}
+
+	/* disable the PCIE->GISB memory window */
+	bpcie_writel(0x00000000, base + PCIE_MISC_RC_BAR1_CONFIG_LO);
+
+	/* disable the PCIE->SCB memory window */
+	bpcie_writel(0x00000000, base + PCIE_MISC_RC_BAR3_CONFIG_LO);
+
+	if (!pcie->suspended) {
+		/* clear any interrupts we find on boot */
+		bpcie_writel(0xffffffff, base + PCIE_INTR2_CPU_BASE + CLR);
+		(void) bpcie_readl(base + PCIE_INTR2_CPU_BASE + CLR);
+	}
+
+	/* Mask all interrupts since we are not handling any yet */
+	bpcie_writel(0xffffffff, base + PCIE_INTR2_CPU_BASE + MASK_SET);
+	(void) bpcie_readl(base + PCIE_INTR2_CPU_BASE + MASK_SET);
+
+	if (pcie->ssc)
+		if (set_ssc(base))
+			dev_err(pcie->dev, "error while configuring ssc mode\n");
+	if (pcie->gen)
+		set_gen(base, pcie->gen);
+
+	/* take the EP device out of reset */
+	/* field: PCIE_SW_PERST = 0 */
+	brcm_pcie_rgr1_sw_init(pcie, 0x00000001, 0, 0);
+
+	return 0;
+}
+
+static void brcm_pcie_turn_off(struct brcm_pcie *pcie)
+{
+	void __iomem *base = pcie->base;
+
+	/* Reset endpoint device */
+	brcm_pcie_rgr1_sw_init(pcie, 0x00000001, 0, 1);
+
+	/* deassert request for L23 in case it was asserted */
+	wr_fld_rb(base + PCIE_MISC_PCIE_CTRL, 0x1, 0, 0);
+
+	/* SERDES_IDDQ = 1 */
+	wr_fld_rb(base + PCIE_MISC_HARD_PCIE_HARD_DEBUG, 0x08000000,
+		  27, 1);
+	/* Shutdown PCIe bridge */
+	brcm_pcie_rgr1_sw_init(pcie, 0x00000002, 1, 1);
+}
+
+static void brcm_pcie_enter_l23(struct brcm_pcie *pcie)
+{
+	void __iomem *base = pcie->base;
+	int timeout = 1000;
+	int l23;
+
+	/* assert request for L23 */
+	wr_fld_rb(base + PCIE_MISC_PCIE_CTRL, 0x1, 0, 1);
+	do {
+		/* poll L23 status */
+		l23 = bpcie_readl(base + PCIE_MISC_PCIE_STATUS) & (1 << 6);
+	} while (--timeout && !l23);
+
+	if (!timeout)
+		dev_err(pcie->dev, "failed to enter L23\n");
+}
+
+static int brcm_setup_pcie_bridge(struct brcm_pcie *pcie)
+{
+	static const char *link_speed[4] = { "???", "2.5", "5.0", "8.0" };
+	void __iomem *base = pcie->base;
+	const int limit = pcie->suspended ? 1000 : 100;
+	struct clk *clk;
+	unsigned int status;
+	int i, j, ret;
+	bool ssc_good = false;
+
+	/* Give the RC/EP time to wake up, before trying to configure RC.
+	 * Intermittently check status for link-up, up to a total of 100ms
+	 * when we don't know if the device is there, and up to 1000ms if
+	 * we do know the device is there.
+	 */
+	for (i = 1, j = 0; j < limit && !is_pcie_link_up(pcie); j += i, i = i*2)
+		msleep(i + j > limit ? limit - j : i);
+
+	if (!is_pcie_link_up(pcie)) {
+		dev_info(pcie->dev, "link down\n");
+		goto fail;
+	}
+
+	/* Attempt to enable MSI if we have an interrupt for it. */
+	if (pcie->msi_irq > 0) {
+		ret = brcm_pcie_enable_msi(pcie, pcie->num);
+		if (ret < 0) {
+			dev_err(pcie->dev, "failed to enable MSI support: %d\n",
+				ret);
+		}
+	}
+
+	/* For config space accesses on the RC, show the right class for
+	 * a PCI-PCI bridge
+	 */
+	wr_fld_rb(base + PCIE_RC_CFG_PRIV1_ID_VAL3, 0x00ffffff, 0, 0x060400);
+
+	status = bpcie_readl(base + PCIE_RC_CFG_PCIE_LINK_STATUS_CONTROL);
+
+	if (pcie->ssc) {
+		if (is_ssc(base) == 0)
+			ssc_good = true;
+		else
+			dev_err(pcie->dev, "failed to enter SSC mode\n");
+	}
+
+	dev_info(pcie->dev, "link up, %s Gbps x%u %s\n",
+		 link_speed[((status & 0x000f0000) >> 16) & 0x3],
+		 (status & 0x03f00000) >> 20, ssc_good ? "(SSC)" : "(!SSC)");
+
+	/* Enable configuration request retry (see pci_scan_device()) */
+	/* field RC_CRS_EN = 1
+	 */
+	wr_fld(base + PCIE_RC_CFG_PCIE_ROOT_CAP_CONTROL, 0x00000010, 4, 1);
+
+	/* PCIE->SCB endian mode for BAR ield ENDIAN_MODE_BAR2 = DATA_ENDIAN
+	 */
+	wr_fld_rb(base + PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1, 0x0000000c, 2,
+		  DATA_ENDIAN);
+
+	/* Refclk from RC should be gated with CLKREQ# input when ASPM L0s,L1
+	 * is enabled =>  setting the CLKREQ_DEBUG_ENABLE field to 1.
+	 */
+	wr_fld_rb(base + PCIE_MISC_HARD_PCIE_HARD_DEBUG, 0x00000002, 1, 1);
+
+	/* Add bogus IO resource structure so that pcibios_init_resources()
+	 * does not allocate the same IO region for different domains
+	 */
+
+	pcie->bridge_setup_done = true;
+
+	return 0;
+fail:
+	if (IS_ENABLED(CONFIG_PM))
+		brcm_pcie_turn_off(pcie);
+
+	clk = pcie->clk;
+	if (pcie->suspended)
+		clk_disable(clk);
+	else {
+		clk_disable_unprepare(clk);
+		clk_put(clk);
+	}
+
+	pcie->bridge_setup_done = false;
+
+	return -ENODEV;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int brcm_pcie_suspend(struct device *dev)
+{
+	struct brcm_pcie *pcie = dev_get_drvdata(dev);
+
+	if (!pcie->bridge_setup_done)
+		return 0;
+
+	brcm_pcie_enter_l23(pcie);
+	brcm_pcie_turn_off(pcie);
+	clk_disable(pcie->clk);
+	pcie->suspended = true;
+
+	return 0;
+}
+
+static int brcm_pcie_resume(struct device *dev)
+{
+	struct brcm_pcie *pcie = dev_get_drvdata(dev);
+
+	if (!pcie->bridge_setup_done)
+		return 0;
+
+	/* Take bridge out of reset so we can access the SERDES reg */
+	brcm_pcie_rgr1_sw_init(pcie, 0x00000002, 1, 0);
+
+	/* SERDES_IDDQ = 0 */
+	wr_fld_rb(pcie->base + PCIE_MISC_HARD_PCIE_HARD_DEBUG, 0x08000000,
+		  27, 0);
+	/* wait for serdes to be stable */
+	usleep_range(100, 1000);
+
+	brcm_pcie_setup_early(pcie);
+
+	brcm_setup_pcie_bridge(pcie);
+	pcie->suspended = false;
+
+	return 0;
+}
+
+static const struct dev_pm_ops brcm_pcie_pm_ops = {
+	.suspend_noirq = brcm_pcie_suspend,
+	.resume_noirq = brcm_pcie_resume,
+};
+#else
+#define brcm_pcie_pm_ops	NULL
+#endif /* CONFIG_PM_SLEEP */
+
+static int cfg_index(int busnr, int devfn, int reg)
+{
+	return ((PCI_SLOT(devfn) & 0x1f) << PCI_SLOT_SHIFT)
+		| ((PCI_FUNC(devfn) & 0x07) << PCI_FUNC_SHIFT)
+		| (busnr << PCI_BUSNUM_SHIFT)
+		| (reg & ~3);
+}
+
+static int brcm_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
+				  int where, int size, u32 data)
+{
+	struct brcm_pcie *pcie = bus->sysdata;
+	u32 val = 0, mask, shift;
+	void __iomem *base;
+	bool rc_access;
+	int idx;
+
+	if (!is_pcie_link_up(pcie))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	base = pcie->base;
+
+	rc_access = !!pci_is_root_bus(bus);
+
+	idx = cfg_index(bus->number, devfn, where);
+	WARN_ON(((where & 3) + size) > 4);
+
+	if (rc_access && PCI_SLOT(devfn))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	if (size < 4) {
+		/* partial word - read, modify, write */
+		if (rc_access)
+			val = bpcie_readl(base + (where & ~3));
+		else
+			val = brcm_pcie_ll_read_config(pcie, idx);
+	}
+
+	shift = (where & 3) << 3;
+	mask = (0xffffffff >> ((4 - size) << 3)) << shift;
+	val = (val & ~mask) | ((data << shift) & mask);
+
+	if (rc_access) {
+		bpcie_writel(val, base + (where & ~3));
+		bpcie_readl(base + (where & ~3));
+	} else {
+		brcm_pcie_ll_write_config(pcie, idx, val);
+	}
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int brcm_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
+				 int where, int size, u32 *data)
+{
+	struct brcm_pcie *pcie = bus->sysdata;
+	u32 val, mask, shift;
+	void __iomem *base;
+	bool rc_access;
+	int idx;
+
+	if (!is_pcie_link_up(pcie))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	base = pcie->base;
+
+	rc_access = !!pci_is_root_bus(bus);
+	idx = cfg_index(bus->number, devfn, where);
+	WARN_ON(((where & 3) + size) > 4);
+
+	if (rc_access && PCI_SLOT(devfn)) {
+		*data = 0xffffffff;
+		return PCIBIOS_FUNC_NOT_SUPPORTED;
+	}
+
+	if (rc_access)
+		val = bpcie_readl(base + (where & ~3));
+	else
+		val = brcm_pcie_ll_read_config(pcie, idx);
+
+	shift = (where & 3) << 3;
+	mask = (0xffffffff >> ((4 - size) << 3)) << shift;
+	*data = (val & mask) >> shift;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static const struct of_device_id brcm_pcie_match[] = {
+	{ .compatible = "brcm,bcm7425-pcie", .data = &bcm7425_cfg },
+	{ .compatible = "brcm,bcm7435-pcie", .data = &bcm7435_cfg },
+	{ .compatible = "brcm,bcm7445-pcie", .data = &generic_cfg },
+	{},
+};
+MODULE_DEVICE_TABLE(of, brcm_pcie_match);
+
+static struct pci_ops brcm_pcie_ops = {
+	.read = brcm_pcie_read_config,
+	.write = brcm_pcie_write_config,
+};
+
+static int brcm_pcie_probe(struct platform_device *pdev)
+{
+	struct device_node *dn = pdev->dev.of_node;
+	const u32 *log2_scb_sizes, *dma_ranges;
+	const struct brcm_pcie_cfg_data *data;
+	const struct of_device_id *of_id;
+	struct brcm_pcie *pcie;
+	void __iomem *base;
+	struct resource *r;
+	int i, rlen, ret;
+	u32 tmp;
+
+	pcie = devm_kzalloc(&pdev->dev, sizeof(struct brcm_pcie), GFP_KERNEL);
+	if (!pcie)
+		return -ENOMEM;
+
+	of_id = of_match_node(brcm_pcie_match, dn);
+	if (!of_id)
+		return -EINVAL;
+
+	data = of_id->data;
+	pcie->type = data->type;
+	pcie->ops = &data->ops;
+
+	platform_set_drvdata(pdev, pcie);
+
+	INIT_LIST_HEAD(&pcie->resource);
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	base = devm_ioremap_resource(&pdev->dev, r);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	ret = of_alias_get_id(dn, "pcie");
+	if (ret >= 0)
+		pcie->num = ret;
+
+	pcie->clk = devm_clk_get(&pdev->dev, "pcie");
+	if (IS_ERR(pcie->clk)) {
+		dev_err(&pdev->dev, "could not get clock\n");
+		pcie->clk = NULL;
+	}
+
+	ret = clk_prepare_enable(pcie->clk);
+	if (ret) {
+		dev_err(&pdev->dev, "could not enable clock\n");
+		return ret;
+	}
+
+	pcie->dn = dn;
+	pcie->base = base;
+	pcie->dev = &pdev->dev;
+	pcie->dev->of_node = dn;
+	pcie->gen = 0;
+
+	ret = of_property_read_u32(dn, "brcm,gen", &tmp);
+	if (ret == 0) {
+		if (tmp > 0 && tmp < 3)
+			pcie->gen = (int)tmp;
+		else
+			dev_warn(pcie->dev, "bad DT value for prop 'brcm,gen");
+	} else if (ret != -EINVAL) {
+		dev_warn(pcie->dev, "error reading DT prop 'brcm,gen");
+	}
+
+	pcie->ssc = of_property_read_bool(dn, "brcm,ssc");
+
+	/* Get the value for the log2 of the scb sizes. Subtract 15 from
+	 * each because the target register field has 0==disabled and 1==6KB.
+	 */
+	log2_scb_sizes = of_get_property(dn, "brcm,log2-scb-sizes", &rlen);
+	if (log2_scb_sizes) {
+		for (i = 0; i < rlen / sizeof(u32); i++) {
+			pcie->scb_size_vals[i]
+				= (int)of_read_number(log2_scb_sizes + i, 1)
+					- 15;
+			pcie->num_memc++;
+		}
+	}
+
+	/* Look for the dma-ranges property.  If it exists, issue a warning
+	 * as PCIe drivers may not work.  This is because the identity
+	 * mapping between system memory and PCIe space is not preserved,
+	 * and we need Linux to massage the dma_addr_t values it gets
+	 * from dma memory allocation.  This functionality will be added
+	 * in the near future.
+	 */
+	dma_ranges = of_get_property(dn, "dma-ranges", &rlen);
+	if (dma_ranges != NULL)
+		dev_warn(pcie->dev, "no identity map; PCI drivers may fail");
+
+	if (IS_ENABLED(CONFIG_PCI_MSI)) {
+		ret = irq_of_parse_and_map(pdev->dev.of_node, 1);
+		if (ret == 0)
+			dev_warn(pcie->dev, "cannot get msi intr; MSI disabled\n");
+		else
+			pcie->msi_irq = ret;
+	}
+
+	ret = of_pci_get_host_bridge_resources(dn, 0, 0xff,
+					       &pcie->resource, NULL);
+	if (ret) {
+		dev_err(pcie->dev, "ranges parsing failed\n");
+		return ret;
+	}
+
+	ret = brcm_pcie_setup_early(pcie);
+	if (ret)
+		goto out_err_clk;
+
+	/* If setup bridge fails, it cleans up behind itself */
+	ret = brcm_setup_pcie_bridge(pcie);
+	if (ret)
+		goto out_err;
+
+	pcie->bus = pci_scan_root_bus(pcie->dev, pcie->num, &brcm_pcie_ops,
+				      pcie, &pcie->resource);
+	if (!pcie->bus) {
+		ret = -ENOMEM;
+		goto out_err_bus;
+	}
+
+	if (IS_ENABLED(CONFIG_PCI_MSI))
+		brcm_pcie_msi_chip_set(pcie);
+
+	pci_bus_size_bridges(pcie->bus);
+	pci_bus_assign_resources(pcie->bus);
+
+	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
+	pci_bus_add_devices(pcie->bus);
+
+	return 0;
+
+out_err_bus:
+	brcm_pcie_enter_l23(pcie);
+	brcm_pcie_turn_off(pcie);
+out_err_clk:
+	clk_disable_unprepare(pcie->clk);
+out_err:
+	return ret;
+}
+
+static int brcm_pcie_remove(struct platform_device *pdev)
+{
+	return brcm_pcie_suspend(&pdev->dev);
+}
+
+static struct platform_driver brcm_pcie_driver = {
+	.probe = brcm_pcie_probe,
+	.remove = brcm_pcie_remove,
+	.driver = {
+		.name = "brcm-pcie",
+		.owner = THIS_MODULE,
+		.of_match_table = brcm_pcie_match,
+		.pm = &brcm_pcie_pm_ops,
+	},
+};
+module_platform_driver(brcm_pcie_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Broadcom STB PCIE RC driver");
+MODULE_AUTHOR("Broadcom");
diff --git a/drivers/pci/host/pcie-brcmstb.h b/drivers/pci/host/pcie-brcmstb.h
new file mode 100644
index 000000000000..b4a507423bb0
--- /dev/null
+++ b/drivers/pci/host/pcie-brcmstb.h
@@ -0,0 +1,160 @@
+#ifndef __PCIE_BRCMSTB_H
+#define __PCIE_BRCMSTB_H
+
+#include <linux/io.h>
+
+/* Broadcom PCIE Offsets */
+#define PCIE_RC_CFG_PCIE_LINK_CAPABILITY		0x00b8
+#define PCIE_RC_CFG_PCIE_LINK_STATUS_CONTROL		0x00bc
+#define PCIE_RC_CFG_PCIE_ROOT_CAP_CONTROL		0x00c8
+#define PCIE_RC_CFG_PCIE_LINK_STATUS_CONTROL_2		0x00dc
+#define PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1		0x0188
+#define PCIE_RC_CFG_PRIV1_ID_VAL3			0x043c
+#define PCIE_RC_DL_MDIO_ADDR				0x1100
+#define PCIE_RC_DL_MDIO_WR_DATA				0x1104
+#define PCIE_RC_DL_MDIO_RD_DATA				0x1108
+#define PCIE_MISC_MISC_CTRL				0x4008
+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO		0x400c
+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI		0x4010
+#define PCIE_MISC_RC_BAR1_CONFIG_LO			0x402c
+#define PCIE_MISC_RC_BAR1_CONFIG_HI			0x4030
+#define PCIE_MISC_RC_BAR2_CONFIG_LO			0x4034
+#define PCIE_MISC_RC_BAR2_CONFIG_HI			0x4038
+#define PCIE_MISC_RC_BAR3_CONFIG_LO			0x403c
+#define PCIE_MISC_RC_BAR3_CONFIG_HI			0x4040
+#define PCIE_MISC_MSI_BAR_CONFIG_LO			0x4044
+#define PCIE_MISC_MSI_BAR_CONFIG_HI			0x4048
+#define PCIE_MISC_MSI_DATA_CONFIG			0x404c
+#define PCIE_MISC_PCIE_CTRL				0x4064
+#define PCIE_MISC_PCIE_STATUS				0x4068
+#define PCIE_MISC_REVISION				0x406c
+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT	0x4070
+#define PCIE_MISC_HARD_PCIE_HARD_DEBUG			0x4204
+#define PCIE_INTR2_CPU_BASE				0x4300
+#define PCIE_MSI_INTR2_BASE				0x4500
+
+#define PCIE_RGR1_SW_INIT_1				0x9210
+#define PCIE_EXT_CFG_INDEX				0x9000
+#define PCIE_EXT_CFG_DATA				0x9004
+
+/* BCM7425 specific register offsets */
+#define BCM7425_PCIE_RGR1_SW_INIT_1			0x8010
+#define BCM7425_PCIE_EXT_CFG_INDEX			0x8300
+#define BCM7425_PCIE_EXT_CFG_DATA			0x8304
+
+#define PCI_BUSNUM_SHIFT		20
+#define PCI_SLOT_SHIFT			15
+#define PCI_FUNC_SHIFT			12
+
+#define BRCM_NUM_PCI_OUT_WINS		4
+#define BRCM_MAX_SCB			4
+
+/* Offsets from PCIE_INTR2_CPU_BASE and PCIE_MSI_INTR2_BASE */
+#define STATUS				0x0
+#define SET				0x4
+#define CLR				0x8
+#define MASK_STATUS			0xc
+#define MASK_SET			0x10
+#define MASK_CLR			0x14
+
+enum brcm_pcie_type {
+	BCM7425,
+	BCM7435,
+	GENERIC,
+};
+
+struct brcm_pcie;
+
+/* Chip-specific PCIe operations (read/write config and reset) */
+struct brcm_pcie_ll_ops {
+	u32 (*read_config)(struct brcm_pcie *pcie, int cfg_idx);
+	void (*write_config)(struct brcm_pcie *pcie, int cfg_idx, u32 val);
+	void (*rgr1_sw_init)(struct brcm_pcie *pcie, u32 mask,
+			     int shift, u32 val);
+};
+
+struct brcm_pcie_cfg_data {
+	const enum brcm_pcie_type type;
+	const struct brcm_pcie_ll_ops ops;
+};
+
+struct brcm_msi;
+
+/* Internal Bus Controller Information.*/
+struct brcm_pcie {
+	void __iomem		*base;
+	bool			suspended;
+	struct clk		*clk;
+	struct device_node	*dn;
+	bool			ssc;
+	int			gen;
+	int			scb_size_vals[BRCM_MAX_SCB];
+	struct pci_bus		*bus;
+	struct device		*dev;
+	struct list_head	resource;
+	int			msi_irq;
+	struct brcm_msi		*msi;
+	unsigned int		rev;
+	unsigned int		num;
+	bool			bridge_setup_done;
+	enum brcm_pcie_type	type;
+	const struct brcm_pcie_ll_ops *ops;
+	unsigned int		num_memc;
+};
+
+/* Helper functions to access read/write config space and software init which
+ * are chip-specific
+ */
+static inline u32 brcm_pcie_ll_read_config(struct brcm_pcie *pcie, int cfg_idx)
+{
+	return pcie->ops->read_config(pcie, cfg_idx);
+}
+
+static inline void brcm_pcie_ll_write_config(struct brcm_pcie *pcie,
+					     int cfg_idx, u32 val)
+{
+	pcie->ops->write_config(pcie, cfg_idx, val);
+}
+
+static inline void brcm_pcie_rgr1_sw_init(struct brcm_pcie *pcie, u32 mask,
+					  int shift, u32 val)
+{
+	pcie->ops->rgr1_sw_init(pcie, mask, shift, val);
+}
+
+/*
+ * MIPS endianness is configured by boot strap, which also reverses all
+ * bus endianness (i.e., big-endian CPU + big endian bus ==> native
+ * endian I/O).
+ *
+ * Other architectures (e.g., ARM) either do not support big endian, or
+ * else leave I/O in little endian mode.
+ */
+static inline u32 bpcie_readl(void __iomem *base)
+{
+	if (IS_ENABLED(CONFIG_MIPS))
+		return __raw_readl(base);
+	else
+		return readl(base);
+}
+
+static inline void bpcie_writel(u32 val, void __iomem *base)
+{
+	if (IS_ENABLED(CONFIG_MIPS))
+		__raw_writel(val, base);
+	else
+		writel(val, base);
+}
+
+#ifdef CONFIG_PCIE_BRCMSTB_MSI
+int brcm_pcie_enable_msi(struct brcm_pcie *pcie, int nr);
+void brcm_pcie_msi_chip_set(struct brcm_pcie *pcie);
+#else
+static inline int brcm_pcie_enable_msi(struct brcm_pcie *pcie, int nr)
+{
+	return 0;
+}
+static inline void brcm_pcie_msi_chip_set(struct brcm_pcie *pcie) { }
+#endif
+
+#endif /* __PCIE_BRCMSTB_H */
-- 
2.1.0

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

* Re: [PATCH v2 1/2] Documentation: DT: bindings: Add Broadcom STB PCIe bindings
  2016-05-05 19:14   ` Florian Fainelli
@ 2016-05-05 21:15     ` Arnd Bergmann
  -1 siblings, 0 replies; 41+ messages in thread
From: Arnd Bergmann @ 2016-05-05 21:15 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: linux-pci, linux-kernel, devicetree, linux-arm-kernel,
	bcm-kernel-feedback-list, jim2101024, bhelgaas

On Thursday 05 May 2016 12:14:59 Florian Fainelli wrote:
> From: Jim Quinlan <jim2101024@gmail.com>
> 
> This patchs adds the Device Tree bindings for the Broadcom STB PCIe root
> complex hardware.
> 
> Signed-off-by: Jim Quinlan <jim2101024@gmail.com>
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
> ---
> Changes in v2:
> 
> - rewrite the binding document almost from scratch to include many more
>   references to existing documents
> - describe missing properties
> - give better examples
> 
>  .../devicetree/bindings/pci/brcm,brcmstb-pcie.txt  | 98 ++++++++++++++++++++++
>  1 file changed, 98 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
> 
> diff --git a/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt b/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
> new file mode 100644
> index 000000000000..3682b0f0bc26
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
> @@ -0,0 +1,98 @@
> +Broadcom STB PCIe Host Controller Device Tree Bindings
> +
> +This document describes the binding of the PCIe Root Complex hardware found in
> +Broadcom Set Top Box System-on-Chips such as BCM7425 (MIPS), BCM7435 (MIPS) and
> +BCM7445 (ARMv7).
> +
> +Required properties:
> +- compatible: must be one of: "brcm,bcm7425-pcie"
> +			      "brcm,bcm7435-pcie"
> +			      "brcm,bcm7445-pcie"
> +
> +- reg: specifies the physical base address of the controller registers and
> +  its length
> +
> +- interrupt-parent: must be a reference (phandle) to the parent interrupt
> +  controller in the system (7038-l1-intc on MIPS, GIC on ARM/ARM64)
> +
> +- interrrupts: first interrupt must be the Level 1 interrupt number corresponding
> +  to the main PCIe RC interrupt, second interrupt must be the MSI interrupt
> +  See the interrupt-parent documentation for the number of cells and their meaning:
> +  MIPS: Documentation/devicetree/bindings/interrupt-controller/brcm,bcm7038-l1-intc.txt
> +  ARM/ARM64: Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt
> +
> +- interrupt-names: must be "pcie", and if present "msi"

When I suggested splitting out the MSI support, I was thinking (but not writing)
that you'd use an msi-parent property to refer to the node that holds the
msi-controller as well.

> +- ranges: ranges for the PCI outbound windows, no I/O or prefetchable windows
> +  must be specified here, only non-prefetchable. 32-bits windows or 64-bits
> +  windows are allowed based on the host processor's capabilities (ARM w/ LPAE,
> +  ARM64).

So this supports 64-bit non-prefetchable windows? Usually 64-bit windows
are prefetchable.

> +- brcm,log2-scb-sizes: log2 size of the SCB window that is mapped to PCIe space
> +  there must be exactly one value per memory controller present in the system
> +  (ranges from 1 to 3)

I'm still not too happy with this property. I see no reason for the log2
format (rather than length in bytes, or offset/length tuples, or dma-ranges,
or phandles pointing to the memory controllers). I think we need to discuss
this some more.

> +- brcm,gen: integer that indicates desired forced generation of link: 1 => 2.5
> +  Gbps, 2 => 5.0 Gbps, 3 => 8.0 Gbps. Will override the auto-negotation if
> +  specified.

to repeat my earlier comment from v1:

Shouldn't the link generation be probed automatically?

> +- <*>-supply: see Documentation/devicetree/bindings/regulator/regulator.txt
> +
> +- <*>-supply-names: see Documentation/devicetree/bindings/regulator/regulator.txt

I don't see supply-names documented there.

	Arnd

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

* [PATCH v2 1/2] Documentation: DT: bindings: Add Broadcom STB PCIe bindings
@ 2016-05-05 21:15     ` Arnd Bergmann
  0 siblings, 0 replies; 41+ messages in thread
From: Arnd Bergmann @ 2016-05-05 21:15 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday 05 May 2016 12:14:59 Florian Fainelli wrote:
> From: Jim Quinlan <jim2101024@gmail.com>
> 
> This patchs adds the Device Tree bindings for the Broadcom STB PCIe root
> complex hardware.
> 
> Signed-off-by: Jim Quinlan <jim2101024@gmail.com>
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
> ---
> Changes in v2:
> 
> - rewrite the binding document almost from scratch to include many more
>   references to existing documents
> - describe missing properties
> - give better examples
> 
>  .../devicetree/bindings/pci/brcm,brcmstb-pcie.txt  | 98 ++++++++++++++++++++++
>  1 file changed, 98 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
> 
> diff --git a/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt b/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
> new file mode 100644
> index 000000000000..3682b0f0bc26
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
> @@ -0,0 +1,98 @@
> +Broadcom STB PCIe Host Controller Device Tree Bindings
> +
> +This document describes the binding of the PCIe Root Complex hardware found in
> +Broadcom Set Top Box System-on-Chips such as BCM7425 (MIPS), BCM7435 (MIPS) and
> +BCM7445 (ARMv7).
> +
> +Required properties:
> +- compatible: must be one of: "brcm,bcm7425-pcie"
> +			      "brcm,bcm7435-pcie"
> +			      "brcm,bcm7445-pcie"
> +
> +- reg: specifies the physical base address of the controller registers and
> +  its length
> +
> +- interrupt-parent: must be a reference (phandle) to the parent interrupt
> +  controller in the system (7038-l1-intc on MIPS, GIC on ARM/ARM64)
> +
> +- interrrupts: first interrupt must be the Level 1 interrupt number corresponding
> +  to the main PCIe RC interrupt, second interrupt must be the MSI interrupt
> +  See the interrupt-parent documentation for the number of cells and their meaning:
> +  MIPS: Documentation/devicetree/bindings/interrupt-controller/brcm,bcm7038-l1-intc.txt
> +  ARM/ARM64: Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt
> +
> +- interrupt-names: must be "pcie", and if present "msi"

When I suggested splitting out the MSI support, I was thinking (but not writing)
that you'd use an msi-parent property to refer to the node that holds the
msi-controller as well.

> +- ranges: ranges for the PCI outbound windows, no I/O or prefetchable windows
> +  must be specified here, only non-prefetchable. 32-bits windows or 64-bits
> +  windows are allowed based on the host processor's capabilities (ARM w/ LPAE,
> +  ARM64).

So this supports 64-bit non-prefetchable windows? Usually 64-bit windows
are prefetchable.

> +- brcm,log2-scb-sizes: log2 size of the SCB window that is mapped to PCIe space
> +  there must be exactly one value per memory controller present in the system
> +  (ranges from 1 to 3)

I'm still not too happy with this property. I see no reason for the log2
format (rather than length in bytes, or offset/length tuples, or dma-ranges,
or phandles pointing to the memory controllers). I think we need to discuss
this some more.

> +- brcm,gen: integer that indicates desired forced generation of link: 1 => 2.5
> +  Gbps, 2 => 5.0 Gbps, 3 => 8.0 Gbps. Will override the auto-negotation if
> +  specified.

to repeat my earlier comment from v1:

Shouldn't the link generation be probed automatically?

> +- <*>-supply: see Documentation/devicetree/bindings/regulator/regulator.txt
> +
> +- <*>-supply-names: see Documentation/devicetree/bindings/regulator/regulator.txt

I don't see supply-names documented there.

	Arnd

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

* Re: [PATCH v2 1/2] Documentation: DT: bindings: Add Broadcom STB PCIe bindings
  2016-05-05 21:15     ` Arnd Bergmann
@ 2016-05-05 21:46       ` Florian Fainelli
  -1 siblings, 0 replies; 41+ messages in thread
From: Florian Fainelli @ 2016-05-05 21:46 UTC (permalink / raw)
  To: Arnd Bergmann, Florian Fainelli
  Cc: linux-pci, linux-kernel, devicetree, linux-arm-kernel,
	bcm-kernel-feedback-list, jim2101024, bhelgaas

On 05/05/16 14:15, Arnd Bergmann wrote:
> On Thursday 05 May 2016 12:14:59 Florian Fainelli wrote:
>> From: Jim Quinlan <jim2101024@gmail.com>
>>
>> This patchs adds the Device Tree bindings for the Broadcom STB PCIe root
>> complex hardware.
>>
>> Signed-off-by: Jim Quinlan <jim2101024@gmail.com>
>> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
>> ---
>> Changes in v2:
>>
>> - rewrite the binding document almost from scratch to include many more
>>   references to existing documents
>> - describe missing properties
>> - give better examples
>>
>>  .../devicetree/bindings/pci/brcm,brcmstb-pcie.txt  | 98 ++++++++++++++++++++++
>>  1 file changed, 98 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
>>
>> diff --git a/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt b/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
>> new file mode 100644
>> index 000000000000..3682b0f0bc26
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
>> @@ -0,0 +1,98 @@
>> +Broadcom STB PCIe Host Controller Device Tree Bindings
>> +
>> +This document describes the binding of the PCIe Root Complex hardware found in
>> +Broadcom Set Top Box System-on-Chips such as BCM7425 (MIPS), BCM7435 (MIPS) and
>> +BCM7445 (ARMv7).
>> +
>> +Required properties:
>> +- compatible: must be one of: "brcm,bcm7425-pcie"
>> +			      "brcm,bcm7435-pcie"
>> +			      "brcm,bcm7445-pcie"
>> +
>> +- reg: specifies the physical base address of the controller registers and
>> +  its length
>> +
>> +- interrupt-parent: must be a reference (phandle) to the parent interrupt
>> +  controller in the system (7038-l1-intc on MIPS, GIC on ARM/ARM64)
>> +
>> +- interrrupts: first interrupt must be the Level 1 interrupt number corresponding
>> +  to the main PCIe RC interrupt, second interrupt must be the MSI interrupt
>> +  See the interrupt-parent documentation for the number of cells and their meaning:
>> +  MIPS: Documentation/devicetree/bindings/interrupt-controller/brcm,bcm7038-l1-intc.txt
>> +  ARM/ARM64: Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt
>> +
>> +- interrupt-names: must be "pcie", and if present "msi"
> 
> When I suggested splitting out the MSI support, I was thinking (but not writing)
> that you'd use an msi-parent property to refer to the node that holds the
> msi-controller as well.

Humm fair enough.

> 
>> +- ranges: ranges for the PCI outbound windows, no I/O or prefetchable windows
>> +  must be specified here, only non-prefetchable. 32-bits windows or 64-bits
>> +  windows are allowed based on the host processor's capabilities (ARM w/ LPAE,
>> +  ARM64).
> 
> So this supports 64-bit non-prefetchable windows? Usually 64-bit windows
> are prefetchable.
> 
>> +- brcm,log2-scb-sizes: log2 size of the SCB window that is mapped to PCIe space
>> +  there must be exactly one value per memory controller present in the system
>> +  (ranges from 1 to 3)
> 
> I'm still not too happy with this property. I see no reason for the log2
> format (rather than length in bytes, or offset/length tuples, or dma-ranges,
> or phandles pointing to the memory controllers). I think we need to discuss
> this some more.

Sure, works for me.

> 
>> +- brcm,gen: integer that indicates desired forced generation of link: 1 => 2.5
>> +  Gbps, 2 => 5.0 Gbps, 3 => 8.0 Gbps. Will override the auto-negotation if
>> +  specified.
> 
> to repeat my earlier comment from v1:
> 
> Shouldn't the link generation be probed automatically?

It is, but if the property is present, we can foce the link negotiation,
We have had cases where this was desired and helpful.

> 
>> +- <*>-supply: see Documentation/devicetree/bindings/regulator/regulator.txt
>> +
>> +- <*>-supply-names: see Documentation/devicetree/bindings/regulator/regulator.txt
> 
> I don't see supply-names documented there.

Meh, I read that wrong, will fix that.

Thanks!
-- 
Florian

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

* [PATCH v2 1/2] Documentation: DT: bindings: Add Broadcom STB PCIe bindings
@ 2016-05-05 21:46       ` Florian Fainelli
  0 siblings, 0 replies; 41+ messages in thread
From: Florian Fainelli @ 2016-05-05 21:46 UTC (permalink / raw)
  To: linux-arm-kernel

On 05/05/16 14:15, Arnd Bergmann wrote:
> On Thursday 05 May 2016 12:14:59 Florian Fainelli wrote:
>> From: Jim Quinlan <jim2101024@gmail.com>
>>
>> This patchs adds the Device Tree bindings for the Broadcom STB PCIe root
>> complex hardware.
>>
>> Signed-off-by: Jim Quinlan <jim2101024@gmail.com>
>> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
>> ---
>> Changes in v2:
>>
>> - rewrite the binding document almost from scratch to include many more
>>   references to existing documents
>> - describe missing properties
>> - give better examples
>>
>>  .../devicetree/bindings/pci/brcm,brcmstb-pcie.txt  | 98 ++++++++++++++++++++++
>>  1 file changed, 98 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
>>
>> diff --git a/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt b/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
>> new file mode 100644
>> index 000000000000..3682b0f0bc26
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
>> @@ -0,0 +1,98 @@
>> +Broadcom STB PCIe Host Controller Device Tree Bindings
>> +
>> +This document describes the binding of the PCIe Root Complex hardware found in
>> +Broadcom Set Top Box System-on-Chips such as BCM7425 (MIPS), BCM7435 (MIPS) and
>> +BCM7445 (ARMv7).
>> +
>> +Required properties:
>> +- compatible: must be one of: "brcm,bcm7425-pcie"
>> +			      "brcm,bcm7435-pcie"
>> +			      "brcm,bcm7445-pcie"
>> +
>> +- reg: specifies the physical base address of the controller registers and
>> +  its length
>> +
>> +- interrupt-parent: must be a reference (phandle) to the parent interrupt
>> +  controller in the system (7038-l1-intc on MIPS, GIC on ARM/ARM64)
>> +
>> +- interrrupts: first interrupt must be the Level 1 interrupt number corresponding
>> +  to the main PCIe RC interrupt, second interrupt must be the MSI interrupt
>> +  See the interrupt-parent documentation for the number of cells and their meaning:
>> +  MIPS: Documentation/devicetree/bindings/interrupt-controller/brcm,bcm7038-l1-intc.txt
>> +  ARM/ARM64: Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt
>> +
>> +- interrupt-names: must be "pcie", and if present "msi"
> 
> When I suggested splitting out the MSI support, I was thinking (but not writing)
> that you'd use an msi-parent property to refer to the node that holds the
> msi-controller as well.

Humm fair enough.

> 
>> +- ranges: ranges for the PCI outbound windows, no I/O or prefetchable windows
>> +  must be specified here, only non-prefetchable. 32-bits windows or 64-bits
>> +  windows are allowed based on the host processor's capabilities (ARM w/ LPAE,
>> +  ARM64).
> 
> So this supports 64-bit non-prefetchable windows? Usually 64-bit windows
> are prefetchable.
> 
>> +- brcm,log2-scb-sizes: log2 size of the SCB window that is mapped to PCIe space
>> +  there must be exactly one value per memory controller present in the system
>> +  (ranges from 1 to 3)
> 
> I'm still not too happy with this property. I see no reason for the log2
> format (rather than length in bytes, or offset/length tuples, or dma-ranges,
> or phandles pointing to the memory controllers). I think we need to discuss
> this some more.

Sure, works for me.

> 
>> +- brcm,gen: integer that indicates desired forced generation of link: 1 => 2.5
>> +  Gbps, 2 => 5.0 Gbps, 3 => 8.0 Gbps. Will override the auto-negotation if
>> +  specified.
> 
> to repeat my earlier comment from v1:
> 
> Shouldn't the link generation be probed automatically?

It is, but if the property is present, we can foce the link negotiation,
We have had cases where this was desired and helpful.

> 
>> +- <*>-supply: see Documentation/devicetree/bindings/regulator/regulator.txt
>> +
>> +- <*>-supply-names: see Documentation/devicetree/bindings/regulator/regulator.txt
> 
> I don't see supply-names documented there.

Meh, I read that wrong, will fix that.

Thanks!
-- 
Florian

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

* Re: [PATCH v2 1/2] Documentation: DT: bindings: Add Broadcom STB PCIe bindings
  2016-05-05 21:46       ` Florian Fainelli
@ 2016-05-09 13:12         ` Arnd Bergmann
  -1 siblings, 0 replies; 41+ messages in thread
From: Arnd Bergmann @ 2016-05-09 13:12 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: Florian Fainelli, linux-pci, linux-kernel, devicetree,
	linux-arm-kernel, bcm-kernel-feedback-list, jim2101024, bhelgaas

On Thursday 05 May 2016 14:46:22 Florian Fainelli wrote:
> 
> > 
> >> +- brcm,gen: integer that indicates desired forced generation of link: 1 => 2.5
> >> +  Gbps, 2 => 5.0 Gbps, 3 => 8.0 Gbps. Will override the auto-negotation if
> >> +  specified.
> > 
> > to repeat my earlier comment from v1:
> > 
> > Shouldn't the link generation be probed automatically?
> 
> It is, but if the property is present, we can foce the link negotiation,
> We have had cases where this was desired and helpful.
> 

Right, I missed that this is listed as 'optional', so that seems
perfectly fine.

Thanks,

	Arnd

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

* [PATCH v2 1/2] Documentation: DT: bindings: Add Broadcom STB PCIe bindings
@ 2016-05-09 13:12         ` Arnd Bergmann
  0 siblings, 0 replies; 41+ messages in thread
From: Arnd Bergmann @ 2016-05-09 13:12 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday 05 May 2016 14:46:22 Florian Fainelli wrote:
> 
> > 
> >> +- brcm,gen: integer that indicates desired forced generation of link: 1 => 2.5
> >> +  Gbps, 2 => 5.0 Gbps, 3 => 8.0 Gbps. Will override the auto-negotation if
> >> +  specified.
> > 
> > to repeat my earlier comment from v1:
> > 
> > Shouldn't the link generation be probed automatically?
> 
> It is, but if the property is present, we can foce the link negotiation,
> We have had cases where this was desired and helpful.
> 

Right, I missed that this is listed as 'optional', so that seems
perfectly fine.

Thanks,

	Arnd

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

* Re: [PATCH v2 1/2] Documentation: DT: bindings: Add Broadcom STB PCIe bindings
  2016-05-05 19:14   ` Florian Fainelli
@ 2016-05-09 19:26     ` Rob Herring
  -1 siblings, 0 replies; 41+ messages in thread
From: Rob Herring @ 2016-05-09 19:26 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: linux-pci, linux-kernel, devicetree, linux-arm-kernel,
	bcm-kernel-feedback-list, jim2101024, bhelgaas, arnd

On Thu, May 05, 2016 at 12:14:59PM -0700, Florian Fainelli wrote:
> From: Jim Quinlan <jim2101024@gmail.com>
> 
> This patchs adds the Device Tree bindings for the Broadcom STB PCIe root
> complex hardware.
> 
> Signed-off-by: Jim Quinlan <jim2101024@gmail.com>
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
> ---
> Changes in v2:
> 
> - rewrite the binding document almost from scratch to include many more
>   references to existing documents
> - describe missing properties
> - give better examples
> 
>  .../devicetree/bindings/pci/brcm,brcmstb-pcie.txt  | 98 ++++++++++++++++++++++
>  1 file changed, 98 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
> 
> diff --git a/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt b/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
> new file mode 100644
> index 000000000000..3682b0f0bc26
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
> @@ -0,0 +1,98 @@
> +Broadcom STB PCIe Host Controller Device Tree Bindings
> +
> +This document describes the binding of the PCIe Root Complex hardware found in
> +Broadcom Set Top Box System-on-Chips such as BCM7425 (MIPS), BCM7435 (MIPS) and
> +BCM7445 (ARMv7).
> +
> +Required properties:
> +- compatible: must be one of: "brcm,bcm7425-pcie"
> +			      "brcm,bcm7435-pcie"
> +			      "brcm,bcm7445-pcie"
> +
> +- reg: specifies the physical base address of the controller registers and
> +  its length
> +
> +- interrupt-parent: must be a reference (phandle) to the parent interrupt
> +  controller in the system (7038-l1-intc on MIPS, GIC on ARM/ARM64)
> +
> +- interrrupts: first interrupt must be the Level 1 interrupt number corresponding
> +  to the main PCIe RC interrupt, second interrupt must be the MSI interrupt
> +  See the interrupt-parent documentation for the number of cells and their meaning:
> +  MIPS: Documentation/devicetree/bindings/interrupt-controller/brcm,bcm7038-l1-intc.txt
> +  ARM/ARM64: Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt
> +
> +- interrupt-names: must be "pcie", and if present "msi"
> +
> +- interrupt-map: see pci.txt
> +
> +- interrupt-map-mask: see pci.txt
> +
> +- #address-cells: must be set to <3>, see pci.txt
> +
> +- #size-cells: must be set to <2>, see pci.txt
> +
> +- ranges: ranges for the PCI outbound windows, no I/O or prefetchable windows
> +  must be specified here, only non-prefetchable. 32-bits windows or 64-bits
> +  windows are allowed based on the host processor's capabilities (ARM w/ LPAE,
> +  ARM64).
> +
> +- #interrupt-cells: set to <1>, see pci.txt
> +
> +- brcm,log2-scb-sizes: log2 size of the SCB window that is mapped to PCIe space
> +  there must be exactly one value per memory controller present in the system
> +  (ranges from 1 to 3)
> +
> +Optional properties:
> +
> +- msi-controller: indicates that this is a MSI controller node (when supported)
> +
> +- clocks: phandle to the functional clock that feeds into the PCIe RC block
> +
> +- clock-names: the name(s) of the clocks specified in 'clocks'.  Note
> +  that if the 'clocks' property is given, 'clock-names' is mandatory,
> +  and the name of the clock is expected to be "pcie".
> +
> +- brcm,ssc: boolean that indicates usage of spread-spectrum clocking

Shouldn't this be a property of the phy? Is there no separate phy to 
control?

> +
> +- brcm,gen: integer that indicates desired forced generation of link: 1 => 2.5
> +  Gbps, 2 => 5.0 Gbps, 3 => 8.0 Gbps. Will override the auto-negotation if
> +  specified.
> +
> +- <*>-supply: see Documentation/devicetree/bindings/regulator/regulator.txt
> +
> +- <*>-supply-names: see Documentation/devicetree/bindings/regulator/regulator.txt
> +
> +Example Node:
> +
> +This example assumes that the top-level #address-cells = <2> and #size-cells =
> +<2>, e.g: ARM LPAE configuration.
> +
> +	pcie0: pcie-controller@f0460000 {
> +		reg = <0x0 0xf0460000 0x0 0x9310>;
> +		interrupts = <0x0 0x33 0x4>, <0x0 0x34, 0x4>;
                                                      ^
typo

> +		interrupt-names = "pcie", "msi";
> +		compatible = "brcm,bcm7445-pcie";
> +		#address-cells = <3>;
> +		#size-cells = <2>;
> +
> +		/* Two non-prefetchable 32-bits memory space, each of 128MB
> + 		 * with the following mapping:
> +		 * PCIe address		=> CPU physical address space
> +		 * 0x00_0000_0000	=> 0x00_C000_0000
> +		 * 0x00_0800_0000	=> 0x00_C800_0000
> +		 */
> +		ranges = <0x02000000 0x00000000 0x00000000 0x00000000 0xc0000000 0x00000000 0x08000000>,
> +			 <0x02000000 0x00000000 0x08000000 0x00000000 0xc8000000 0x00000000 0x08000000>;
> +		#interrupt-cells = <1>;
> +		interrupt-map-mask = <0xf800 0 0 7>;
> +		interrupt-map = <0 0 0 1 &intc 47 3
> +				 0 0 0 2 &intc 48 3
> +				 0 0 0 3 &intc 49 3
> +				 0 0 0 4 &intc 50 3>;
> +		clocks = <&pcie0>;
> +		clock-names = "pcie";
> +		brcm,ssc;
> +		brcm,log2-scb-sizes = <0x1e 0x1e 0x1e>;
> +		vreg-wifi-pwr-supply-names = "vreg-wifi-pwr";
> +		vreg-wifi-pwr-supply = <&vreg-wifi-pwr>;

The supply for the PCIE RC is called "vreg-wifi-pwr"? Seems a bit 
strange.

Rob

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

* [PATCH v2 1/2] Documentation: DT: bindings: Add Broadcom STB PCIe bindings
@ 2016-05-09 19:26     ` Rob Herring
  0 siblings, 0 replies; 41+ messages in thread
From: Rob Herring @ 2016-05-09 19:26 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, May 05, 2016 at 12:14:59PM -0700, Florian Fainelli wrote:
> From: Jim Quinlan <jim2101024@gmail.com>
> 
> This patchs adds the Device Tree bindings for the Broadcom STB PCIe root
> complex hardware.
> 
> Signed-off-by: Jim Quinlan <jim2101024@gmail.com>
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
> ---
> Changes in v2:
> 
> - rewrite the binding document almost from scratch to include many more
>   references to existing documents
> - describe missing properties
> - give better examples
> 
>  .../devicetree/bindings/pci/brcm,brcmstb-pcie.txt  | 98 ++++++++++++++++++++++
>  1 file changed, 98 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
> 
> diff --git a/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt b/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
> new file mode 100644
> index 000000000000..3682b0f0bc26
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
> @@ -0,0 +1,98 @@
> +Broadcom STB PCIe Host Controller Device Tree Bindings
> +
> +This document describes the binding of the PCIe Root Complex hardware found in
> +Broadcom Set Top Box System-on-Chips such as BCM7425 (MIPS), BCM7435 (MIPS) and
> +BCM7445 (ARMv7).
> +
> +Required properties:
> +- compatible: must be one of: "brcm,bcm7425-pcie"
> +			      "brcm,bcm7435-pcie"
> +			      "brcm,bcm7445-pcie"
> +
> +- reg: specifies the physical base address of the controller registers and
> +  its length
> +
> +- interrupt-parent: must be a reference (phandle) to the parent interrupt
> +  controller in the system (7038-l1-intc on MIPS, GIC on ARM/ARM64)
> +
> +- interrrupts: first interrupt must be the Level 1 interrupt number corresponding
> +  to the main PCIe RC interrupt, second interrupt must be the MSI interrupt
> +  See the interrupt-parent documentation for the number of cells and their meaning:
> +  MIPS: Documentation/devicetree/bindings/interrupt-controller/brcm,bcm7038-l1-intc.txt
> +  ARM/ARM64: Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt
> +
> +- interrupt-names: must be "pcie", and if present "msi"
> +
> +- interrupt-map: see pci.txt
> +
> +- interrupt-map-mask: see pci.txt
> +
> +- #address-cells: must be set to <3>, see pci.txt
> +
> +- #size-cells: must be set to <2>, see pci.txt
> +
> +- ranges: ranges for the PCI outbound windows, no I/O or prefetchable windows
> +  must be specified here, only non-prefetchable. 32-bits windows or 64-bits
> +  windows are allowed based on the host processor's capabilities (ARM w/ LPAE,
> +  ARM64).
> +
> +- #interrupt-cells: set to <1>, see pci.txt
> +
> +- brcm,log2-scb-sizes: log2 size of the SCB window that is mapped to PCIe space
> +  there must be exactly one value per memory controller present in the system
> +  (ranges from 1 to 3)
> +
> +Optional properties:
> +
> +- msi-controller: indicates that this is a MSI controller node (when supported)
> +
> +- clocks: phandle to the functional clock that feeds into the PCIe RC block
> +
> +- clock-names: the name(s) of the clocks specified in 'clocks'.  Note
> +  that if the 'clocks' property is given, 'clock-names' is mandatory,
> +  and the name of the clock is expected to be "pcie".
> +
> +- brcm,ssc: boolean that indicates usage of spread-spectrum clocking

Shouldn't this be a property of the phy? Is there no separate phy to 
control?

> +
> +- brcm,gen: integer that indicates desired forced generation of link: 1 => 2.5
> +  Gbps, 2 => 5.0 Gbps, 3 => 8.0 Gbps. Will override the auto-negotation if
> +  specified.
> +
> +- <*>-supply: see Documentation/devicetree/bindings/regulator/regulator.txt
> +
> +- <*>-supply-names: see Documentation/devicetree/bindings/regulator/regulator.txt
> +
> +Example Node:
> +
> +This example assumes that the top-level #address-cells = <2> and #size-cells =
> +<2>, e.g: ARM LPAE configuration.
> +
> +	pcie0: pcie-controller at f0460000 {
> +		reg = <0x0 0xf0460000 0x0 0x9310>;
> +		interrupts = <0x0 0x33 0x4>, <0x0 0x34, 0x4>;
                                                      ^
typo

> +		interrupt-names = "pcie", "msi";
> +		compatible = "brcm,bcm7445-pcie";
> +		#address-cells = <3>;
> +		#size-cells = <2>;
> +
> +		/* Two non-prefetchable 32-bits memory space, each of 128MB
> + 		 * with the following mapping:
> +		 * PCIe address		=> CPU physical address space
> +		 * 0x00_0000_0000	=> 0x00_C000_0000
> +		 * 0x00_0800_0000	=> 0x00_C800_0000
> +		 */
> +		ranges = <0x02000000 0x00000000 0x00000000 0x00000000 0xc0000000 0x00000000 0x08000000>,
> +			 <0x02000000 0x00000000 0x08000000 0x00000000 0xc8000000 0x00000000 0x08000000>;
> +		#interrupt-cells = <1>;
> +		interrupt-map-mask = <0xf800 0 0 7>;
> +		interrupt-map = <0 0 0 1 &intc 47 3
> +				 0 0 0 2 &intc 48 3
> +				 0 0 0 3 &intc 49 3
> +				 0 0 0 4 &intc 50 3>;
> +		clocks = <&pcie0>;
> +		clock-names = "pcie";
> +		brcm,ssc;
> +		brcm,log2-scb-sizes = <0x1e 0x1e 0x1e>;
> +		vreg-wifi-pwr-supply-names = "vreg-wifi-pwr";
> +		vreg-wifi-pwr-supply = <&vreg-wifi-pwr>;

The supply for the PCIE RC is called "vreg-wifi-pwr"? Seems a bit 
strange.

Rob

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

* Re: [PATCH v2 1/2] Documentation: DT: bindings: Add Broadcom STB PCIe bindings
  2016-05-09 19:26     ` Rob Herring
  (?)
@ 2016-05-09 23:15       ` Florian Fainelli
  -1 siblings, 0 replies; 41+ messages in thread
From: Florian Fainelli @ 2016-05-09 23:15 UTC (permalink / raw)
  To: Rob Herring, Florian Fainelli
  Cc: linux-pci, linux-kernel, devicetree, linux-arm-kernel,
	bcm-kernel-feedback-list, jim2101024, bhelgaas, arnd

On 05/09/2016 12:26 PM, Rob Herring wrote:
> On Thu, May 05, 2016 at 12:14:59PM -0700, Florian Fainelli wrote:
>> From: Jim Quinlan <jim2101024@gmail.com>
>>
>> This patchs adds the Device Tree bindings for the Broadcom STB PCIe root
>> complex hardware.
>>
>> Signed-off-by: Jim Quinlan <jim2101024@gmail.com>
>> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
>> ---
>> Changes in v2:
>>
>> - rewrite the binding document almost from scratch to include many more
>>   references to existing documents
>> - describe missing properties
>> - give better examples
>>
>>  .../devicetree/bindings/pci/brcm,brcmstb-pcie.txt  | 98 ++++++++++++++++++++++
>>  1 file changed, 98 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
>>
>> diff --git a/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt b/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
>> new file mode 100644
>> index 000000000000..3682b0f0bc26
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
>> @@ -0,0 +1,98 @@
>> +Broadcom STB PCIe Host Controller Device Tree Bindings
>> +
>> +This document describes the binding of the PCIe Root Complex hardware found in
>> +Broadcom Set Top Box System-on-Chips such as BCM7425 (MIPS), BCM7435 (MIPS) and
>> +BCM7445 (ARMv7).
>> +
>> +Required properties:
>> +- compatible: must be one of: "brcm,bcm7425-pcie"
>> +			      "brcm,bcm7435-pcie"
>> +			      "brcm,bcm7445-pcie"
>> +
>> +- reg: specifies the physical base address of the controller registers and
>> +  its length
>> +
>> +- interrupt-parent: must be a reference (phandle) to the parent interrupt
>> +  controller in the system (7038-l1-intc on MIPS, GIC on ARM/ARM64)
>> +
>> +- interrrupts: first interrupt must be the Level 1 interrupt number corresponding
>> +  to the main PCIe RC interrupt, second interrupt must be the MSI interrupt
>> +  See the interrupt-parent documentation for the number of cells and their meaning:
>> +  MIPS: Documentation/devicetree/bindings/interrupt-controller/brcm,bcm7038-l1-intc.txt
>> +  ARM/ARM64: Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt
>> +
>> +- interrupt-names: must be "pcie", and if present "msi"
>> +
>> +- interrupt-map: see pci.txt
>> +
>> +- interrupt-map-mask: see pci.txt
>> +
>> +- #address-cells: must be set to <3>, see pci.txt
>> +
>> +- #size-cells: must be set to <2>, see pci.txt
>> +
>> +- ranges: ranges for the PCI outbound windows, no I/O or prefetchable windows
>> +  must be specified here, only non-prefetchable. 32-bits windows or 64-bits
>> +  windows are allowed based on the host processor's capabilities (ARM w/ LPAE,
>> +  ARM64).
>> +
>> +- #interrupt-cells: set to <1>, see pci.txt
>> +
>> +- brcm,log2-scb-sizes: log2 size of the SCB window that is mapped to PCIe space
>> +  there must be exactly one value per memory controller present in the system
>> +  (ranges from 1 to 3)
>> +
>> +Optional properties:
>> +
>> +- msi-controller: indicates that this is a MSI controller node (when supported)
>> +
>> +- clocks: phandle to the functional clock that feeds into the PCIe RC block
>> +
>> +- clock-names: the name(s) of the clocks specified in 'clocks'.  Note
>> +  that if the 'clocks' property is given, 'clock-names' is mandatory,
>> +  and the name of the clock is expected to be "pcie".
>> +
>> +- brcm,ssc: boolean that indicates usage of spread-spectrum clocking
> 
> Shouldn't this be a property of the phy? Is there no separate phy to 
> control?

No, the PHY is baked into the PCIe root complex, which is why this is a
property of the root complex node since the two are conflated.

> 
>> +
>> +- brcm,gen: integer that indicates desired forced generation of link: 1 => 2.5
>> +  Gbps, 2 => 5.0 Gbps, 3 => 8.0 Gbps. Will override the auto-negotation if
>> +  specified.
>> +
>> +- <*>-supply: see Documentation/devicetree/bindings/regulator/regulator.txt
>> +
>> +- <*>-supply-names: see Documentation/devicetree/bindings/regulator/regulator.txt
>> +
>> +Example Node:
>> +
>> +This example assumes that the top-level #address-cells = <2> and #size-cells =
>> +<2>, e.g: ARM LPAE configuration.
>> +
>> +	pcie0: pcie-controller@f0460000 {
>> +		reg = <0x0 0xf0460000 0x0 0x9310>;
>> +		interrupts = <0x0 0x33 0x4>, <0x0 0x34, 0x4>;
>                                                       ^
> typo

Whoops, thanks.

> 
>> +		interrupt-names = "pcie", "msi";
>> +		compatible = "brcm,bcm7445-pcie";
>> +		#address-cells = <3>;
>> +		#size-cells = <2>;
>> +
>> +		/* Two non-prefetchable 32-bits memory space, each of 128MB
>> + 		 * with the following mapping:
>> +		 * PCIe address		=> CPU physical address space
>> +		 * 0x00_0000_0000	=> 0x00_C000_0000
>> +		 * 0x00_0800_0000	=> 0x00_C800_0000
>> +		 */
>> +		ranges = <0x02000000 0x00000000 0x00000000 0x00000000 0xc0000000 0x00000000 0x08000000>,
>> +			 <0x02000000 0x00000000 0x08000000 0x00000000 0xc8000000 0x00000000 0x08000000>;
>> +		#interrupt-cells = <1>;
>> +		interrupt-map-mask = <0xf800 0 0 7>;
>> +		interrupt-map = <0 0 0 1 &intc 47 3
>> +				 0 0 0 2 &intc 48 3
>> +				 0 0 0 3 &intc 49 3
>> +				 0 0 0 4 &intc 50 3>;
>> +		clocks = <&pcie0>;
>> +		clock-names = "pcie";
>> +		brcm,ssc;
>> +		brcm,log2-scb-sizes = <0x1e 0x1e 0x1e>;
>> +		vreg-wifi-pwr-supply-names = "vreg-wifi-pwr";
>> +		vreg-wifi-pwr-supply = <&vreg-wifi-pwr>;
> 
> The supply for the PCIE RC is called "vreg-wifi-pwr"? Seems a bit 
> strange.

It can be called anything, this just happens to be the example, but I
can certainly drop that, since a) this is optional and b) we need to
rework that in the driver anyway.
-- 
Florian

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

* Re: [PATCH v2 1/2] Documentation: DT: bindings: Add Broadcom STB PCIe bindings
@ 2016-05-09 23:15       ` Florian Fainelli
  0 siblings, 0 replies; 41+ messages in thread
From: Florian Fainelli @ 2016-05-09 23:15 UTC (permalink / raw)
  To: Rob Herring, Florian Fainelli
  Cc: linux-pci-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w,
	jim2101024-Re5JQEeQqe8AvxtiuMwx3w,
	bhelgaas-hpIqsD4AKlfQT0dZR+AlfA, arnd-r2nGTMty4D4

On 05/09/2016 12:26 PM, Rob Herring wrote:
> On Thu, May 05, 2016 at 12:14:59PM -0700, Florian Fainelli wrote:
>> From: Jim Quinlan <jim2101024-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>>
>> This patchs adds the Device Tree bindings for the Broadcom STB PCIe root
>> complex hardware.
>>
>> Signed-off-by: Jim Quinlan <jim2101024-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>> Signed-off-by: Florian Fainelli <f.fainelli-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>> ---
>> Changes in v2:
>>
>> - rewrite the binding document almost from scratch to include many more
>>   references to existing documents
>> - describe missing properties
>> - give better examples
>>
>>  .../devicetree/bindings/pci/brcm,brcmstb-pcie.txt  | 98 ++++++++++++++++++++++
>>  1 file changed, 98 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
>>
>> diff --git a/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt b/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
>> new file mode 100644
>> index 000000000000..3682b0f0bc26
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
>> @@ -0,0 +1,98 @@
>> +Broadcom STB PCIe Host Controller Device Tree Bindings
>> +
>> +This document describes the binding of the PCIe Root Complex hardware found in
>> +Broadcom Set Top Box System-on-Chips such as BCM7425 (MIPS), BCM7435 (MIPS) and
>> +BCM7445 (ARMv7).
>> +
>> +Required properties:
>> +- compatible: must be one of: "brcm,bcm7425-pcie"
>> +			      "brcm,bcm7435-pcie"
>> +			      "brcm,bcm7445-pcie"
>> +
>> +- reg: specifies the physical base address of the controller registers and
>> +  its length
>> +
>> +- interrupt-parent: must be a reference (phandle) to the parent interrupt
>> +  controller in the system (7038-l1-intc on MIPS, GIC on ARM/ARM64)
>> +
>> +- interrrupts: first interrupt must be the Level 1 interrupt number corresponding
>> +  to the main PCIe RC interrupt, second interrupt must be the MSI interrupt
>> +  See the interrupt-parent documentation for the number of cells and their meaning:
>> +  MIPS: Documentation/devicetree/bindings/interrupt-controller/brcm,bcm7038-l1-intc.txt
>> +  ARM/ARM64: Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt
>> +
>> +- interrupt-names: must be "pcie", and if present "msi"
>> +
>> +- interrupt-map: see pci.txt
>> +
>> +- interrupt-map-mask: see pci.txt
>> +
>> +- #address-cells: must be set to <3>, see pci.txt
>> +
>> +- #size-cells: must be set to <2>, see pci.txt
>> +
>> +- ranges: ranges for the PCI outbound windows, no I/O or prefetchable windows
>> +  must be specified here, only non-prefetchable. 32-bits windows or 64-bits
>> +  windows are allowed based on the host processor's capabilities (ARM w/ LPAE,
>> +  ARM64).
>> +
>> +- #interrupt-cells: set to <1>, see pci.txt
>> +
>> +- brcm,log2-scb-sizes: log2 size of the SCB window that is mapped to PCIe space
>> +  there must be exactly one value per memory controller present in the system
>> +  (ranges from 1 to 3)
>> +
>> +Optional properties:
>> +
>> +- msi-controller: indicates that this is a MSI controller node (when supported)
>> +
>> +- clocks: phandle to the functional clock that feeds into the PCIe RC block
>> +
>> +- clock-names: the name(s) of the clocks specified in 'clocks'.  Note
>> +  that if the 'clocks' property is given, 'clock-names' is mandatory,
>> +  and the name of the clock is expected to be "pcie".
>> +
>> +- brcm,ssc: boolean that indicates usage of spread-spectrum clocking
> 
> Shouldn't this be a property of the phy? Is there no separate phy to 
> control?

No, the PHY is baked into the PCIe root complex, which is why this is a
property of the root complex node since the two are conflated.

> 
>> +
>> +- brcm,gen: integer that indicates desired forced generation of link: 1 => 2.5
>> +  Gbps, 2 => 5.0 Gbps, 3 => 8.0 Gbps. Will override the auto-negotation if
>> +  specified.
>> +
>> +- <*>-supply: see Documentation/devicetree/bindings/regulator/regulator.txt
>> +
>> +- <*>-supply-names: see Documentation/devicetree/bindings/regulator/regulator.txt
>> +
>> +Example Node:
>> +
>> +This example assumes that the top-level #address-cells = <2> and #size-cells =
>> +<2>, e.g: ARM LPAE configuration.
>> +
>> +	pcie0: pcie-controller@f0460000 {
>> +		reg = <0x0 0xf0460000 0x0 0x9310>;
>> +		interrupts = <0x0 0x33 0x4>, <0x0 0x34, 0x4>;
>                                                       ^
> typo

Whoops, thanks.

> 
>> +		interrupt-names = "pcie", "msi";
>> +		compatible = "brcm,bcm7445-pcie";
>> +		#address-cells = <3>;
>> +		#size-cells = <2>;
>> +
>> +		/* Two non-prefetchable 32-bits memory space, each of 128MB
>> + 		 * with the following mapping:
>> +		 * PCIe address		=> CPU physical address space
>> +		 * 0x00_0000_0000	=> 0x00_C000_0000
>> +		 * 0x00_0800_0000	=> 0x00_C800_0000
>> +		 */
>> +		ranges = <0x02000000 0x00000000 0x00000000 0x00000000 0xc0000000 0x00000000 0x08000000>,
>> +			 <0x02000000 0x00000000 0x08000000 0x00000000 0xc8000000 0x00000000 0x08000000>;
>> +		#interrupt-cells = <1>;
>> +		interrupt-map-mask = <0xf800 0 0 7>;
>> +		interrupt-map = <0 0 0 1 &intc 47 3
>> +				 0 0 0 2 &intc 48 3
>> +				 0 0 0 3 &intc 49 3
>> +				 0 0 0 4 &intc 50 3>;
>> +		clocks = <&pcie0>;
>> +		clock-names = "pcie";
>> +		brcm,ssc;
>> +		brcm,log2-scb-sizes = <0x1e 0x1e 0x1e>;
>> +		vreg-wifi-pwr-supply-names = "vreg-wifi-pwr";
>> +		vreg-wifi-pwr-supply = <&vreg-wifi-pwr>;
> 
> The supply for the PCIE RC is called "vreg-wifi-pwr"? Seems a bit 
> strange.

It can be called anything, this just happens to be the example, but I
can certainly drop that, since a) this is optional and b) we need to
rework that in the driver anyway.
-- 
Florian
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v2 1/2] Documentation: DT: bindings: Add Broadcom STB PCIe bindings
@ 2016-05-09 23:15       ` Florian Fainelli
  0 siblings, 0 replies; 41+ messages in thread
From: Florian Fainelli @ 2016-05-09 23:15 UTC (permalink / raw)
  To: linux-arm-kernel

On 05/09/2016 12:26 PM, Rob Herring wrote:
> On Thu, May 05, 2016 at 12:14:59PM -0700, Florian Fainelli wrote:
>> From: Jim Quinlan <jim2101024@gmail.com>
>>
>> This patchs adds the Device Tree bindings for the Broadcom STB PCIe root
>> complex hardware.
>>
>> Signed-off-by: Jim Quinlan <jim2101024@gmail.com>
>> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
>> ---
>> Changes in v2:
>>
>> - rewrite the binding document almost from scratch to include many more
>>   references to existing documents
>> - describe missing properties
>> - give better examples
>>
>>  .../devicetree/bindings/pci/brcm,brcmstb-pcie.txt  | 98 ++++++++++++++++++++++
>>  1 file changed, 98 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
>>
>> diff --git a/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt b/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
>> new file mode 100644
>> index 000000000000..3682b0f0bc26
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
>> @@ -0,0 +1,98 @@
>> +Broadcom STB PCIe Host Controller Device Tree Bindings
>> +
>> +This document describes the binding of the PCIe Root Complex hardware found in
>> +Broadcom Set Top Box System-on-Chips such as BCM7425 (MIPS), BCM7435 (MIPS) and
>> +BCM7445 (ARMv7).
>> +
>> +Required properties:
>> +- compatible: must be one of: "brcm,bcm7425-pcie"
>> +			      "brcm,bcm7435-pcie"
>> +			      "brcm,bcm7445-pcie"
>> +
>> +- reg: specifies the physical base address of the controller registers and
>> +  its length
>> +
>> +- interrupt-parent: must be a reference (phandle) to the parent interrupt
>> +  controller in the system (7038-l1-intc on MIPS, GIC on ARM/ARM64)
>> +
>> +- interrrupts: first interrupt must be the Level 1 interrupt number corresponding
>> +  to the main PCIe RC interrupt, second interrupt must be the MSI interrupt
>> +  See the interrupt-parent documentation for the number of cells and their meaning:
>> +  MIPS: Documentation/devicetree/bindings/interrupt-controller/brcm,bcm7038-l1-intc.txt
>> +  ARM/ARM64: Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt
>> +
>> +- interrupt-names: must be "pcie", and if present "msi"
>> +
>> +- interrupt-map: see pci.txt
>> +
>> +- interrupt-map-mask: see pci.txt
>> +
>> +- #address-cells: must be set to <3>, see pci.txt
>> +
>> +- #size-cells: must be set to <2>, see pci.txt
>> +
>> +- ranges: ranges for the PCI outbound windows, no I/O or prefetchable windows
>> +  must be specified here, only non-prefetchable. 32-bits windows or 64-bits
>> +  windows are allowed based on the host processor's capabilities (ARM w/ LPAE,
>> +  ARM64).
>> +
>> +- #interrupt-cells: set to <1>, see pci.txt
>> +
>> +- brcm,log2-scb-sizes: log2 size of the SCB window that is mapped to PCIe space
>> +  there must be exactly one value per memory controller present in the system
>> +  (ranges from 1 to 3)
>> +
>> +Optional properties:
>> +
>> +- msi-controller: indicates that this is a MSI controller node (when supported)
>> +
>> +- clocks: phandle to the functional clock that feeds into the PCIe RC block
>> +
>> +- clock-names: the name(s) of the clocks specified in 'clocks'.  Note
>> +  that if the 'clocks' property is given, 'clock-names' is mandatory,
>> +  and the name of the clock is expected to be "pcie".
>> +
>> +- brcm,ssc: boolean that indicates usage of spread-spectrum clocking
> 
> Shouldn't this be a property of the phy? Is there no separate phy to 
> control?

No, the PHY is baked into the PCIe root complex, which is why this is a
property of the root complex node since the two are conflated.

> 
>> +
>> +- brcm,gen: integer that indicates desired forced generation of link: 1 => 2.5
>> +  Gbps, 2 => 5.0 Gbps, 3 => 8.0 Gbps. Will override the auto-negotation if
>> +  specified.
>> +
>> +- <*>-supply: see Documentation/devicetree/bindings/regulator/regulator.txt
>> +
>> +- <*>-supply-names: see Documentation/devicetree/bindings/regulator/regulator.txt
>> +
>> +Example Node:
>> +
>> +This example assumes that the top-level #address-cells = <2> and #size-cells =
>> +<2>, e.g: ARM LPAE configuration.
>> +
>> +	pcie0: pcie-controller at f0460000 {
>> +		reg = <0x0 0xf0460000 0x0 0x9310>;
>> +		interrupts = <0x0 0x33 0x4>, <0x0 0x34, 0x4>;
>                                                       ^
> typo

Whoops, thanks.

> 
>> +		interrupt-names = "pcie", "msi";
>> +		compatible = "brcm,bcm7445-pcie";
>> +		#address-cells = <3>;
>> +		#size-cells = <2>;
>> +
>> +		/* Two non-prefetchable 32-bits memory space, each of 128MB
>> + 		 * with the following mapping:
>> +		 * PCIe address		=> CPU physical address space
>> +		 * 0x00_0000_0000	=> 0x00_C000_0000
>> +		 * 0x00_0800_0000	=> 0x00_C800_0000
>> +		 */
>> +		ranges = <0x02000000 0x00000000 0x00000000 0x00000000 0xc0000000 0x00000000 0x08000000>,
>> +			 <0x02000000 0x00000000 0x08000000 0x00000000 0xc8000000 0x00000000 0x08000000>;
>> +		#interrupt-cells = <1>;
>> +		interrupt-map-mask = <0xf800 0 0 7>;
>> +		interrupt-map = <0 0 0 1 &intc 47 3
>> +				 0 0 0 2 &intc 48 3
>> +				 0 0 0 3 &intc 49 3
>> +				 0 0 0 4 &intc 50 3>;
>> +		clocks = <&pcie0>;
>> +		clock-names = "pcie";
>> +		brcm,ssc;
>> +		brcm,log2-scb-sizes = <0x1e 0x1e 0x1e>;
>> +		vreg-wifi-pwr-supply-names = "vreg-wifi-pwr";
>> +		vreg-wifi-pwr-supply = <&vreg-wifi-pwr>;
> 
> The supply for the PCIE RC is called "vreg-wifi-pwr"? Seems a bit 
> strange.

It can be called anything, this just happens to be the example, but I
can certainly drop that, since a) this is optional and b) we need to
rework that in the driver anyway.
-- 
Florian

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

* Re: [PATCH v2 1/2] Documentation: DT: bindings: Add Broadcom STB PCIe bindings
  2016-05-09 19:26     ` Rob Herring
@ 2016-05-09 23:15       ` Florian Fainelli
  -1 siblings, 0 replies; 41+ messages in thread
From: Florian Fainelli @ 2016-05-09 23:15 UTC (permalink / raw)
  To: Rob Herring, Florian Fainelli
  Cc: linux-pci, linux-kernel, devicetree, linux-arm-kernel,
	bcm-kernel-feedback-list, jim2101024, bhelgaas, arnd

On 05/09/2016 12:26 PM, Rob Herring wrote:
> On Thu, May 05, 2016 at 12:14:59PM -0700, Florian Fainelli wrote:
>> From: Jim Quinlan <jim2101024@gmail.com>
>>
>> This patchs adds the Device Tree bindings for the Broadcom STB PCIe root
>> complex hardware.
>>
>> Signed-off-by: Jim Quinlan <jim2101024@gmail.com>
>> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
>> ---
>> Changes in v2:
>>
>> - rewrite the binding document almost from scratch to include many more
>>   references to existing documents
>> - describe missing properties
>> - give better examples
>>
>>  .../devicetree/bindings/pci/brcm,brcmstb-pcie.txt  | 98 ++++++++++++++++++++++
>>  1 file changed, 98 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
>>
>> diff --git a/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt b/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
>> new file mode 100644
>> index 000000000000..3682b0f0bc26
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
>> @@ -0,0 +1,98 @@
>> +Broadcom STB PCIe Host Controller Device Tree Bindings
>> +
>> +This document describes the binding of the PCIe Root Complex hardware found in
>> +Broadcom Set Top Box System-on-Chips such as BCM7425 (MIPS), BCM7435 (MIPS) and
>> +BCM7445 (ARMv7).
>> +
>> +Required properties:
>> +- compatible: must be one of: "brcm,bcm7425-pcie"
>> +			      "brcm,bcm7435-pcie"
>> +			      "brcm,bcm7445-pcie"
>> +
>> +- reg: specifies the physical base address of the controller registers and
>> +  its length
>> +
>> +- interrupt-parent: must be a reference (phandle) to the parent interrupt
>> +  controller in the system (7038-l1-intc on MIPS, GIC on ARM/ARM64)
>> +
>> +- interrrupts: first interrupt must be the Level 1 interrupt number corresponding
>> +  to the main PCIe RC interrupt, second interrupt must be the MSI interrupt
>> +  See the interrupt-parent documentation for the number of cells and their meaning:
>> +  MIPS: Documentation/devicetree/bindings/interrupt-controller/brcm,bcm7038-l1-intc.txt
>> +  ARM/ARM64: Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt
>> +
>> +- interrupt-names: must be "pcie", and if present "msi"
>> +
>> +- interrupt-map: see pci.txt
>> +
>> +- interrupt-map-mask: see pci.txt
>> +
>> +- #address-cells: must be set to <3>, see pci.txt
>> +
>> +- #size-cells: must be set to <2>, see pci.txt
>> +
>> +- ranges: ranges for the PCI outbound windows, no I/O or prefetchable windows
>> +  must be specified here, only non-prefetchable. 32-bits windows or 64-bits
>> +  windows are allowed based on the host processor's capabilities (ARM w/ LPAE,
>> +  ARM64).
>> +
>> +- #interrupt-cells: set to <1>, see pci.txt
>> +
>> +- brcm,log2-scb-sizes: log2 size of the SCB window that is mapped to PCIe space
>> +  there must be exactly one value per memory controller present in the system
>> +  (ranges from 1 to 3)
>> +
>> +Optional properties:
>> +
>> +- msi-controller: indicates that this is a MSI controller node (when supported)
>> +
>> +- clocks: phandle to the functional clock that feeds into the PCIe RC block
>> +
>> +- clock-names: the name(s) of the clocks specified in 'clocks'.  Note
>> +  that if the 'clocks' property is given, 'clock-names' is mandatory,
>> +  and the name of the clock is expected to be "pcie".
>> +
>> +- brcm,ssc: boolean that indicates usage of spread-spectrum clocking
> 
> Shouldn't this be a property of the phy? Is there no separate phy to 
> control?

No, the PHY is baked into the PCIe root complex, which is why this is a
property of the root complex node since the two are conflated.

> 
>> +
>> +- brcm,gen: integer that indicates desired forced generation of link: 1 => 2.5
>> +  Gbps, 2 => 5.0 Gbps, 3 => 8.0 Gbps. Will override the auto-negotation if
>> +  specified.
>> +
>> +- <*>-supply: see Documentation/devicetree/bindings/regulator/regulator.txt
>> +
>> +- <*>-supply-names: see Documentation/devicetree/bindings/regulator/regulator.txt
>> +
>> +Example Node:
>> +
>> +This example assumes that the top-level #address-cells = <2> and #size-cells =
>> +<2>, e.g: ARM LPAE configuration.
>> +
>> +	pcie0: pcie-controller@f0460000 {
>> +		reg = <0x0 0xf0460000 0x0 0x9310>;
>> +		interrupts = <0x0 0x33 0x4>, <0x0 0x34, 0x4>;
>                                                       ^
> typo

Whoops, thanks.

> 
>> +		interrupt-names = "pcie", "msi";
>> +		compatible = "brcm,bcm7445-pcie";
>> +		#address-cells = <3>;
>> +		#size-cells = <2>;
>> +
>> +		/* Two non-prefetchable 32-bits memory space, each of 128MB
>> + 		 * with the following mapping:
>> +		 * PCIe address		=> CPU physical address space
>> +		 * 0x00_0000_0000	=> 0x00_C000_0000
>> +		 * 0x00_0800_0000	=> 0x00_C800_0000
>> +		 */
>> +		ranges = <0x02000000 0x00000000 0x00000000 0x00000000 0xc0000000 0x00000000 0x08000000>,
>> +			 <0x02000000 0x00000000 0x08000000 0x00000000 0xc8000000 0x00000000 0x08000000>;
>> +		#interrupt-cells = <1>;
>> +		interrupt-map-mask = <0xf800 0 0 7>;
>> +		interrupt-map = <0 0 0 1 &intc 47 3
>> +				 0 0 0 2 &intc 48 3
>> +				 0 0 0 3 &intc 49 3
>> +				 0 0 0 4 &intc 50 3>;
>> +		clocks = <&pcie0>;
>> +		clock-names = "pcie";
>> +		brcm,ssc;
>> +		brcm,log2-scb-sizes = <0x1e 0x1e 0x1e>;
>> +		vreg-wifi-pwr-supply-names = "vreg-wifi-pwr";
>> +		vreg-wifi-pwr-supply = <&vreg-wifi-pwr>;
> 
> The supply for the PCIE RC is called "vreg-wifi-pwr"? Seems a bit 
> strange.

It can be called anything, this just happens to be the example, but I
can certainly drop that, since a) this is optional and b) we need to
rework that in the driver anyway.
-- 
Florian

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

* [PATCH v2 1/2] Documentation: DT: bindings: Add Broadcom STB PCIe bindings
@ 2016-05-09 23:15       ` Florian Fainelli
  0 siblings, 0 replies; 41+ messages in thread
From: Florian Fainelli @ 2016-05-09 23:15 UTC (permalink / raw)
  To: linux-arm-kernel

On 05/09/2016 12:26 PM, Rob Herring wrote:
> On Thu, May 05, 2016 at 12:14:59PM -0700, Florian Fainelli wrote:
>> From: Jim Quinlan <jim2101024@gmail.com>
>>
>> This patchs adds the Device Tree bindings for the Broadcom STB PCIe root
>> complex hardware.
>>
>> Signed-off-by: Jim Quinlan <jim2101024@gmail.com>
>> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
>> ---
>> Changes in v2:
>>
>> - rewrite the binding document almost from scratch to include many more
>>   references to existing documents
>> - describe missing properties
>> - give better examples
>>
>>  .../devicetree/bindings/pci/brcm,brcmstb-pcie.txt  | 98 ++++++++++++++++++++++
>>  1 file changed, 98 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
>>
>> diff --git a/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt b/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
>> new file mode 100644
>> index 000000000000..3682b0f0bc26
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
>> @@ -0,0 +1,98 @@
>> +Broadcom STB PCIe Host Controller Device Tree Bindings
>> +
>> +This document describes the binding of the PCIe Root Complex hardware found in
>> +Broadcom Set Top Box System-on-Chips such as BCM7425 (MIPS), BCM7435 (MIPS) and
>> +BCM7445 (ARMv7).
>> +
>> +Required properties:
>> +- compatible: must be one of: "brcm,bcm7425-pcie"
>> +			      "brcm,bcm7435-pcie"
>> +			      "brcm,bcm7445-pcie"
>> +
>> +- reg: specifies the physical base address of the controller registers and
>> +  its length
>> +
>> +- interrupt-parent: must be a reference (phandle) to the parent interrupt
>> +  controller in the system (7038-l1-intc on MIPS, GIC on ARM/ARM64)
>> +
>> +- interrrupts: first interrupt must be the Level 1 interrupt number corresponding
>> +  to the main PCIe RC interrupt, second interrupt must be the MSI interrupt
>> +  See the interrupt-parent documentation for the number of cells and their meaning:
>> +  MIPS: Documentation/devicetree/bindings/interrupt-controller/brcm,bcm7038-l1-intc.txt
>> +  ARM/ARM64: Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt
>> +
>> +- interrupt-names: must be "pcie", and if present "msi"
>> +
>> +- interrupt-map: see pci.txt
>> +
>> +- interrupt-map-mask: see pci.txt
>> +
>> +- #address-cells: must be set to <3>, see pci.txt
>> +
>> +- #size-cells: must be set to <2>, see pci.txt
>> +
>> +- ranges: ranges for the PCI outbound windows, no I/O or prefetchable windows
>> +  must be specified here, only non-prefetchable. 32-bits windows or 64-bits
>> +  windows are allowed based on the host processor's capabilities (ARM w/ LPAE,
>> +  ARM64).
>> +
>> +- #interrupt-cells: set to <1>, see pci.txt
>> +
>> +- brcm,log2-scb-sizes: log2 size of the SCB window that is mapped to PCIe space
>> +  there must be exactly one value per memory controller present in the system
>> +  (ranges from 1 to 3)
>> +
>> +Optional properties:
>> +
>> +- msi-controller: indicates that this is a MSI controller node (when supported)
>> +
>> +- clocks: phandle to the functional clock that feeds into the PCIe RC block
>> +
>> +- clock-names: the name(s) of the clocks specified in 'clocks'.  Note
>> +  that if the 'clocks' property is given, 'clock-names' is mandatory,
>> +  and the name of the clock is expected to be "pcie".
>> +
>> +- brcm,ssc: boolean that indicates usage of spread-spectrum clocking
> 
> Shouldn't this be a property of the phy? Is there no separate phy to 
> control?

No, the PHY is baked into the PCIe root complex, which is why this is a
property of the root complex node since the two are conflated.

> 
>> +
>> +- brcm,gen: integer that indicates desired forced generation of link: 1 => 2.5
>> +  Gbps, 2 => 5.0 Gbps, 3 => 8.0 Gbps. Will override the auto-negotation if
>> +  specified.
>> +
>> +- <*>-supply: see Documentation/devicetree/bindings/regulator/regulator.txt
>> +
>> +- <*>-supply-names: see Documentation/devicetree/bindings/regulator/regulator.txt
>> +
>> +Example Node:
>> +
>> +This example assumes that the top-level #address-cells = <2> and #size-cells =
>> +<2>, e.g: ARM LPAE configuration.
>> +
>> +	pcie0: pcie-controller at f0460000 {
>> +		reg = <0x0 0xf0460000 0x0 0x9310>;
>> +		interrupts = <0x0 0x33 0x4>, <0x0 0x34, 0x4>;
>                                                       ^
> typo

Whoops, thanks.

> 
>> +		interrupt-names = "pcie", "msi";
>> +		compatible = "brcm,bcm7445-pcie";
>> +		#address-cells = <3>;
>> +		#size-cells = <2>;
>> +
>> +		/* Two non-prefetchable 32-bits memory space, each of 128MB
>> + 		 * with the following mapping:
>> +		 * PCIe address		=> CPU physical address space
>> +		 * 0x00_0000_0000	=> 0x00_C000_0000
>> +		 * 0x00_0800_0000	=> 0x00_C800_0000
>> +		 */
>> +		ranges = <0x02000000 0x00000000 0x00000000 0x00000000 0xc0000000 0x00000000 0x08000000>,
>> +			 <0x02000000 0x00000000 0x08000000 0x00000000 0xc8000000 0x00000000 0x08000000>;
>> +		#interrupt-cells = <1>;
>> +		interrupt-map-mask = <0xf800 0 0 7>;
>> +		interrupt-map = <0 0 0 1 &intc 47 3
>> +				 0 0 0 2 &intc 48 3
>> +				 0 0 0 3 &intc 49 3
>> +				 0 0 0 4 &intc 50 3>;
>> +		clocks = <&pcie0>;
>> +		clock-names = "pcie";
>> +		brcm,ssc;
>> +		brcm,log2-scb-sizes = <0x1e 0x1e 0x1e>;
>> +		vreg-wifi-pwr-supply-names = "vreg-wifi-pwr";
>> +		vreg-wifi-pwr-supply = <&vreg-wifi-pwr>;
> 
> The supply for the PCIE RC is called "vreg-wifi-pwr"? Seems a bit 
> strange.

It can be called anything, this just happens to be the example, but I
can certainly drop that, since a) this is optional and b) we need to
rework that in the driver anyway.
-- 
Florian

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

* Re: [PATCH v2 1/2] Documentation: DT: bindings: Add Broadcom STB PCIe bindings
  2016-05-05 21:15     ` Arnd Bergmann
@ 2016-05-10 17:00       ` Florian Fainelli
  -1 siblings, 0 replies; 41+ messages in thread
From: Florian Fainelli @ 2016-05-10 17:00 UTC (permalink / raw)
  To: Arnd Bergmann, Florian Fainelli
  Cc: linux-pci, linux-kernel, devicetree, linux-arm-kernel,
	bcm-kernel-feedback-list, jim2101024, bhelgaas

On 05/05/2016 02:15 PM, Arnd Bergmann wrote:
>> +Required properties:
>> +- compatible: must be one of: "brcm,bcm7425-pcie"
>> +			      "brcm,bcm7435-pcie"
>> +			      "brcm,bcm7445-pcie"
>> +
>> +- reg: specifies the physical base address of the controller registers and
>> +  its length
>> +
>> +- interrupt-parent: must be a reference (phandle) to the parent interrupt
>> +  controller in the system (7038-l1-intc on MIPS, GIC on ARM/ARM64)
>> +
>> +- interrrupts: first interrupt must be the Level 1 interrupt number corresponding
>> +  to the main PCIe RC interrupt, second interrupt must be the MSI interrupt
>> +  See the interrupt-parent documentation for the number of cells and their meaning:
>> +  MIPS: Documentation/devicetree/bindings/interrupt-controller/brcm,bcm7038-l1-intc.txt
>> +  ARM/ARM64: Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt
>> +
>> +- interrupt-names: must be "pcie", and if present "msi"
> 
> When I suggested splitting out the MSI support, I was thinking (but not writing)
> that you'd use an msi-parent property to refer to the node that holds the
> msi-controller as well.

Oh got it now, and it can actually refer to iself.

> 
>> +- ranges: ranges for the PCI outbound windows, no I/O or prefetchable windows
>> +  must be specified here, only non-prefetchable. 32-bits windows or 64-bits
>> +  windows are allowed based on the host processor's capabilities (ARM w/ LPAE,
>> +  ARM64).
> 
> So this supports 64-bit non-prefetchable windows? Usually 64-bit windows
> are prefetchable.

I have yet to verify this, but on ARM64-based STB this should indeed be
the case.

> 
>> +- brcm,log2-scb-sizes: log2 size of the SCB window that is mapped to PCIe space
>> +  there must be exactly one value per memory controller present in the system
>> +  (ranges from 1 to 3)
> 
> I'm still not too happy with this property. I see no reason for the log2
> format (rather than length in bytes, or offset/length tuples, or dma-ranges,
> or phandles pointing to the memory controllers). I think we need to discuss
> this some more.

The two critical pieces of information that the PCIe RC needs are:

- number of memory controllers present in the system to avoid
configuring a window to a non-existing or non-populated memory controller

- size of the memory populated on the memory controller

You would think that we should somehow be able to derive this
information from the "memory" node, but there are a few caveats:

- on MIPS platforms, we have discontiguous physical memory ranges (256MB
@ 0x0, then 768MB or 1792MB @ 0x 0x20000000 and 1GB @ 0x90000000), yet
the PCIe RC does not know about the hole(s)

- on ARM platforms, we have an identiy mapping for the PAs below 4GB,
but when we cross it, we have additional non-linear memory regions

Both of these memory nodes would imply we know how to identify which
physical address belongs to which memory controller, while this is
actually possible and known, it creates a dependency on another piece of
driver to provide that information.

We do have memory controller nodes populated in the Device Tree, however
their binding (out of tree for the moment) does only specify their
programmable register interface, and not how how much physical memory
and where they provide to the system.

It does seem like we should be able to utilize the "dma-ranges" property
to determine both the memory controller number and their respective
populated memory sizes.

In the case where we have an identiy mapping though, this seems a little
redundant, but less of a stretch than our custom properties and nodes.

Does that sound reasonable to you?
-- 
Florian

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

* [PATCH v2 1/2] Documentation: DT: bindings: Add Broadcom STB PCIe bindings
@ 2016-05-10 17:00       ` Florian Fainelli
  0 siblings, 0 replies; 41+ messages in thread
From: Florian Fainelli @ 2016-05-10 17:00 UTC (permalink / raw)
  To: linux-arm-kernel

On 05/05/2016 02:15 PM, Arnd Bergmann wrote:
>> +Required properties:
>> +- compatible: must be one of: "brcm,bcm7425-pcie"
>> +			      "brcm,bcm7435-pcie"
>> +			      "brcm,bcm7445-pcie"
>> +
>> +- reg: specifies the physical base address of the controller registers and
>> +  its length
>> +
>> +- interrupt-parent: must be a reference (phandle) to the parent interrupt
>> +  controller in the system (7038-l1-intc on MIPS, GIC on ARM/ARM64)
>> +
>> +- interrrupts: first interrupt must be the Level 1 interrupt number corresponding
>> +  to the main PCIe RC interrupt, second interrupt must be the MSI interrupt
>> +  See the interrupt-parent documentation for the number of cells and their meaning:
>> +  MIPS: Documentation/devicetree/bindings/interrupt-controller/brcm,bcm7038-l1-intc.txt
>> +  ARM/ARM64: Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt
>> +
>> +- interrupt-names: must be "pcie", and if present "msi"
> 
> When I suggested splitting out the MSI support, I was thinking (but not writing)
> that you'd use an msi-parent property to refer to the node that holds the
> msi-controller as well.

Oh got it now, and it can actually refer to iself.

> 
>> +- ranges: ranges for the PCI outbound windows, no I/O or prefetchable windows
>> +  must be specified here, only non-prefetchable. 32-bits windows or 64-bits
>> +  windows are allowed based on the host processor's capabilities (ARM w/ LPAE,
>> +  ARM64).
> 
> So this supports 64-bit non-prefetchable windows? Usually 64-bit windows
> are prefetchable.

I have yet to verify this, but on ARM64-based STB this should indeed be
the case.

> 
>> +- brcm,log2-scb-sizes: log2 size of the SCB window that is mapped to PCIe space
>> +  there must be exactly one value per memory controller present in the system
>> +  (ranges from 1 to 3)
> 
> I'm still not too happy with this property. I see no reason for the log2
> format (rather than length in bytes, or offset/length tuples, or dma-ranges,
> or phandles pointing to the memory controllers). I think we need to discuss
> this some more.

The two critical pieces of information that the PCIe RC needs are:

- number of memory controllers present in the system to avoid
configuring a window to a non-existing or non-populated memory controller

- size of the memory populated on the memory controller

You would think that we should somehow be able to derive this
information from the "memory" node, but there are a few caveats:

- on MIPS platforms, we have discontiguous physical memory ranges (256MB
@ 0x0, then 768MB or 1792MB @ 0x 0x20000000 and 1GB @ 0x90000000), yet
the PCIe RC does not know about the hole(s)

- on ARM platforms, we have an identiy mapping for the PAs below 4GB,
but when we cross it, we have additional non-linear memory regions

Both of these memory nodes would imply we know how to identify which
physical address belongs to which memory controller, while this is
actually possible and known, it creates a dependency on another piece of
driver to provide that information.

We do have memory controller nodes populated in the Device Tree, however
their binding (out of tree for the moment) does only specify their
programmable register interface, and not how how much physical memory
and where they provide to the system.

It does seem like we should be able to utilize the "dma-ranges" property
to determine both the memory controller number and their respective
populated memory sizes.

In the case where we have an identiy mapping though, this seems a little
redundant, but less of a stretch than our custom properties and nodes.

Does that sound reasonable to you?
-- 
Florian

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

* Re: [PATCH v2 1/2] Documentation: DT: bindings: Add Broadcom STB PCIe bindings
  2016-05-10 17:00       ` Florian Fainelli
@ 2016-05-10 19:51         ` Arnd Bergmann
  -1 siblings, 0 replies; 41+ messages in thread
From: Arnd Bergmann @ 2016-05-10 19:51 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: linux-pci, linux-kernel, devicetree, linux-arm-kernel,
	bcm-kernel-feedback-list, jim2101024, bhelgaas

On Tuesday 10 May 2016 10:00:12 Florian Fainelli wrote:
> 
> The two critical pieces of information that the PCIe RC needs are:
> 
> - number of memory controllers present in the system to avoid
> configuring a window to a non-existing or non-populated memory controller
> 
> - size of the memory populated on the memory controller
> 
> You would think that we should somehow be able to derive this
> information from the "memory" node, but there are a few caveats:
> 
> - on MIPS platforms, we have discontiguous physical memory ranges (256MB
> @ 0x0, then 768MB or 1792MB @ 0x 0x20000000 and 1GB @ 0x90000000), yet
> the PCIe RC does not know about the hole(s)

That sounds like you need a dma-ranges property anyway to describe how
the DMA addresses are mapped.

> - on ARM platforms, we have an identiy mapping for the PAs below 4GB,
> but when we cross it, we have additional non-linear memory regions
> 
> Both of these memory nodes would imply we know how to identify which
> physical address belongs to which memory controller, while this is
> actually possible and known, it creates a dependency on another piece of
> driver to provide that information.
> 
> We do have memory controller nodes populated in the Device Tree, however
> their binding (out of tree for the moment) does only specify their
> programmable register interface, and not how how much physical memory
> and where they provide to the system.
> 
> It does seem like we should be able to utilize the "dma-ranges" property
> to determine both the memory controller number and their respective
> populated memory sizes.
> 
> In the case where we have an identiy mapping though, this seems a little
> redundant, but less of a stretch than our custom properties and nodes.
> 
> Does that sound reasonable to you?

I'd have to look at an example first. Ideally, each line in the
dma-ranges property would refer to one memory controller, and
that would be very easy to mandate, but it sounds like in the MIPS
case you end up with an extra entry for the first 256MB that is
on the same memory controller as the second 768MB.

	Arnd

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

* [PATCH v2 1/2] Documentation: DT: bindings: Add Broadcom STB PCIe bindings
@ 2016-05-10 19:51         ` Arnd Bergmann
  0 siblings, 0 replies; 41+ messages in thread
From: Arnd Bergmann @ 2016-05-10 19:51 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 10 May 2016 10:00:12 Florian Fainelli wrote:
> 
> The two critical pieces of information that the PCIe RC needs are:
> 
> - number of memory controllers present in the system to avoid
> configuring a window to a non-existing or non-populated memory controller
> 
> - size of the memory populated on the memory controller
> 
> You would think that we should somehow be able to derive this
> information from the "memory" node, but there are a few caveats:
> 
> - on MIPS platforms, we have discontiguous physical memory ranges (256MB
> @ 0x0, then 768MB or 1792MB @ 0x 0x20000000 and 1GB @ 0x90000000), yet
> the PCIe RC does not know about the hole(s)

That sounds like you need a dma-ranges property anyway to describe how
the DMA addresses are mapped.

> - on ARM platforms, we have an identiy mapping for the PAs below 4GB,
> but when we cross it, we have additional non-linear memory regions
> 
> Both of these memory nodes would imply we know how to identify which
> physical address belongs to which memory controller, while this is
> actually possible and known, it creates a dependency on another piece of
> driver to provide that information.
> 
> We do have memory controller nodes populated in the Device Tree, however
> their binding (out of tree for the moment) does only specify their
> programmable register interface, and not how how much physical memory
> and where they provide to the system.
> 
> It does seem like we should be able to utilize the "dma-ranges" property
> to determine both the memory controller number and their respective
> populated memory sizes.
> 
> In the case where we have an identiy mapping though, this seems a little
> redundant, but less of a stretch than our custom properties and nodes.
> 
> Does that sound reasonable to you?

I'd have to look at an example first. Ideally, each line in the
dma-ranges property would refer to one memory controller, and
that would be very easy to mandate, but it sounds like in the MIPS
case you end up with an extra entry for the first 256MB that is
on the same memory controller as the second 768MB.

	Arnd

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

* RE: [PATCH v2 1/2] Documentation: DT: bindings: Add Broadcom STB PCIe bindings
  2016-05-05 19:14   ` Florian Fainelli
  (?)
  (?)
@ 2016-05-11 14:45     ` Bharat Kumar Gogada
  -1 siblings, 0 replies; 41+ messages in thread
From: Bharat Kumar Gogada @ 2016-05-11 14:45 UTC (permalink / raw)
  To: Florian Fainelli, linux-pci
  Cc: linux-kernel, devicetree, linux-arm-kernel,
	bcm-kernel-feedback-list, jim2101024, bhelgaas, arnd

> 
>  .../devicetree/bindings/pci/brcm,brcmstb-pcie.txt  | 98
> ++++++++++++++++++++++
>  1 file changed, 98 insertions(+)
>  create mode 100644
> Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
> 
> diff --git a/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
> b/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
> new file mode 100644
> index 000000000000..3682b0f0bc26
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
> @@ -0,0 +1,98 @@
> +Broadcom STB PCIe Host Controller Device Tree Bindings
> +
> +This document describes the binding of the PCIe Root Complex hardware
> +found in Broadcom Set Top Box System-on-Chips such as BCM7425 (MIPS),
> +BCM7435 (MIPS) and
> +BCM7445 (ARMv7).
> +
> +Required properties:
> +- compatible: must be one of: "brcm,bcm7425-pcie"
> +			      "brcm,bcm7435-pcie"
> +			      "brcm,bcm7445-pcie"
> +
> +- reg: specifies the physical base address of the controller registers
> +and
> +  its length
> +
> +- interrupt-parent: must be a reference (phandle) to the parent
> +interrupt
> +  controller in the system (7038-l1-intc on MIPS, GIC on ARM/ARM64)
> +
> +- interrrupts: first interrupt must be the Level 1 interrupt number
> +corresponding
> +  to the main PCIe RC interrupt, second interrupt must be the MSI
> +interrupt
> +  See the interrupt-parent documentation for the number of cells and their
> meaning:
> +  MIPS:
> +Documentation/devicetree/bindings/interrupt-controller/brcm,bcm7038-
> l1-
> +intc.txt
> +  ARM/ARM64:
> +Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt
> +
> +- interrupt-names: must be "pcie", and if present "msi"
> +
> +- interrupt-map: see pci.txt
> +
> +- interrupt-map-mask: see pci.txt
> +
> +- #address-cells: must be set to <3>, see pci.txt
> +
> +- #size-cells: must be set to <2>, see pci.txt
> +
> +- ranges: ranges for the PCI outbound windows, no I/O or prefetchable
> +windows
> +  must be specified here, only non-prefetchable. 32-bits windows or
> +64-bits
> +  windows are allowed based on the host processor's capabilities (ARM
> +w/ LPAE,
> +  ARM64).
> +
> +- #interrupt-cells: set to <1>, see pci.txt
> +
> +- brcm,log2-scb-sizes: log2 size of the SCB window that is mapped to
> +PCIe space
> +  there must be exactly one value per memory controller present in the
> +system
> +  (ranges from 1 to 3)

Can you please give more insight on what does this property do ?

Bharat
> +
> +Optional properties:
> +
> +- msi-controller: indicates that this is a MSI controller node (when
> +supported)
> +
> +- clocks: phandle to the functional clock that feeds into the PCIe RC
> +block
> +
> +- clock-names: the name(s) of the clocks specified in 'clocks'.  Note
> +  that if the 'clocks' property is given, 'clock-names' is mandatory,
> +  and the name of the clock is expected to be "pcie".
> +
> +- brcm,ssc: boolean that indicates usage of spread-spectrum clocking
> +
> +- brcm,gen: integer that indicates desired forced generation of link: 1
> +=> 2.5
> +  Gbps, 2 => 5.0 Gbps, 3 => 8.0 Gbps. Will override the auto-negotation
> +if
> +  specified.
> +
> +- <*>-supply: see
> +Documentation/devicetree/bindings/regulator/regulator.txt
> +
> +- <*>-supply-names: see
> +Documentation/devicetree/bindings/regulator/regulator.txt
> +
> +Example Node:
> +
> +This example assumes that the top-level #address-cells = <2> and
> +#size-cells = <2>, e.g: ARM LPAE configuration.
> +
> +	pcie0: pcie-controller@f0460000 {
> +		reg = <0x0 0xf0460000 0x0 0x9310>;
> +		interrupts = <0x0 0x33 0x4>, <0x0 0x34, 0x4>;
> +		interrupt-names = "pcie", "msi";
> +		compatible = "brcm,bcm7445-pcie";
> +		#address-cells = <3>;
> +		#size-cells = <2>;
> +
> +		/* Two non-prefetchable 32-bits memory space, each of
> 128MB
> + 		 * with the following mapping:
> +		 * PCIe address		=> CPU physical address space
> +		 * 0x00_0000_0000	=> 0x00_C000_0000
> +		 * 0x00_0800_0000	=> 0x00_C800_0000
> +		 */
> +		ranges = <0x02000000 0x00000000 0x00000000 0x00000000
> 0xc0000000 0x00000000 0x08000000>,
> +			 <0x02000000 0x00000000 0x08000000 0x00000000
> 0xc8000000 0x00000000 0x08000000>;
> +		#interrupt-cells = <1>;
> +		interrupt-map-mask = <0xf800 0 0 7>;
> +		interrupt-map = <0 0 0 1 &intc 47 3
> +				 0 0 0 2 &intc 48 3
> +				 0 0 0 3 &intc 49 3
> +				 0 0 0 4 &intc 50 3>;
> +		clocks = <&pcie0>;
> +		clock-names = "pcie";
> +		brcm,ssc;
> +		brcm,log2-scb-sizes = <0x1e 0x1e 0x1e>;
> +		vreg-wifi-pwr-supply-names = "vreg-wifi-pwr";
> +		vreg-wifi-pwr-supply = <&vreg-wifi-pwr>;
> +	};
> --
> 2.1.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in the
> body of a message to majordomo@vger.kernel.org More majordomo info at
> http://vger.kernel.org/majordomo-info.html

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

* RE: [PATCH v2 1/2] Documentation: DT: bindings: Add Broadcom STB PCIe bindings
@ 2016-05-11 14:45     ` Bharat Kumar Gogada
  0 siblings, 0 replies; 41+ messages in thread
From: Bharat Kumar Gogada @ 2016-05-11 14:45 UTC (permalink / raw)
  To: Florian Fainelli, linux-pci
  Cc: devicetree, arnd, linux-kernel, jim2101024,
	bcm-kernel-feedback-list, bhelgaas, linux-arm-kernel

> 
>  .../devicetree/bindings/pci/brcm,brcmstb-pcie.txt  | 98
> ++++++++++++++++++++++
>  1 file changed, 98 insertions(+)
>  create mode 100644
> Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
> 
> diff --git a/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
> b/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
> new file mode 100644
> index 000000000000..3682b0f0bc26
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
> @@ -0,0 +1,98 @@
> +Broadcom STB PCIe Host Controller Device Tree Bindings
> +
> +This document describes the binding of the PCIe Root Complex hardware
> +found in Broadcom Set Top Box System-on-Chips such as BCM7425 (MIPS),
> +BCM7435 (MIPS) and
> +BCM7445 (ARMv7).
> +
> +Required properties:
> +- compatible: must be one of: "brcm,bcm7425-pcie"
> +			      "brcm,bcm7435-pcie"
> +			      "brcm,bcm7445-pcie"
> +
> +- reg: specifies the physical base address of the controller registers
> +and
> +  its length
> +
> +- interrupt-parent: must be a reference (phandle) to the parent
> +interrupt
> +  controller in the system (7038-l1-intc on MIPS, GIC on ARM/ARM64)
> +
> +- interrrupts: first interrupt must be the Level 1 interrupt number
> +corresponding
> +  to the main PCIe RC interrupt, second interrupt must be the MSI
> +interrupt
> +  See the interrupt-parent documentation for the number of cells and their
> meaning:
> +  MIPS:
> +Documentation/devicetree/bindings/interrupt-controller/brcm,bcm7038-
> l1-
> +intc.txt
> +  ARM/ARM64:
> +Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt
> +
> +- interrupt-names: must be "pcie", and if present "msi"
> +
> +- interrupt-map: see pci.txt
> +
> +- interrupt-map-mask: see pci.txt
> +
> +- #address-cells: must be set to <3>, see pci.txt
> +
> +- #size-cells: must be set to <2>, see pci.txt
> +
> +- ranges: ranges for the PCI outbound windows, no I/O or prefetchable
> +windows
> +  must be specified here, only non-prefetchable. 32-bits windows or
> +64-bits
> +  windows are allowed based on the host processor's capabilities (ARM
> +w/ LPAE,
> +  ARM64).
> +
> +- #interrupt-cells: set to <1>, see pci.txt
> +
> +- brcm,log2-scb-sizes: log2 size of the SCB window that is mapped to
> +PCIe space
> +  there must be exactly one value per memory controller present in the
> +system
> +  (ranges from 1 to 3)

Can you please give more insight on what does this property do ?

Bharat
> +
> +Optional properties:
> +
> +- msi-controller: indicates that this is a MSI controller node (when
> +supported)
> +
> +- clocks: phandle to the functional clock that feeds into the PCIe RC
> +block
> +
> +- clock-names: the name(s) of the clocks specified in 'clocks'.  Note
> +  that if the 'clocks' property is given, 'clock-names' is mandatory,
> +  and the name of the clock is expected to be "pcie".
> +
> +- brcm,ssc: boolean that indicates usage of spread-spectrum clocking
> +
> +- brcm,gen: integer that indicates desired forced generation of link: 1
> +=> 2.5
> +  Gbps, 2 => 5.0 Gbps, 3 => 8.0 Gbps. Will override the auto-negotation
> +if
> +  specified.
> +
> +- <*>-supply: see
> +Documentation/devicetree/bindings/regulator/regulator.txt
> +
> +- <*>-supply-names: see
> +Documentation/devicetree/bindings/regulator/regulator.txt
> +
> +Example Node:
> +
> +This example assumes that the top-level #address-cells = <2> and
> +#size-cells = <2>, e.g: ARM LPAE configuration.
> +
> +	pcie0: pcie-controller@f0460000 {
> +		reg = <0x0 0xf0460000 0x0 0x9310>;
> +		interrupts = <0x0 0x33 0x4>, <0x0 0x34, 0x4>;
> +		interrupt-names = "pcie", "msi";
> +		compatible = "brcm,bcm7445-pcie";
> +		#address-cells = <3>;
> +		#size-cells = <2>;
> +
> +		/* Two non-prefetchable 32-bits memory space, each of
> 128MB
> + 		 * with the following mapping:
> +		 * PCIe address		=> CPU physical address space
> +		 * 0x00_0000_0000	=> 0x00_C000_0000
> +		 * 0x00_0800_0000	=> 0x00_C800_0000
> +		 */
> +		ranges = <0x02000000 0x00000000 0x00000000 0x00000000
> 0xc0000000 0x00000000 0x08000000>,
> +			 <0x02000000 0x00000000 0x08000000 0x00000000
> 0xc8000000 0x00000000 0x08000000>;
> +		#interrupt-cells = <1>;
> +		interrupt-map-mask = <0xf800 0 0 7>;
> +		interrupt-map = <0 0 0 1 &intc 47 3
> +				 0 0 0 2 &intc 48 3
> +				 0 0 0 3 &intc 49 3
> +				 0 0 0 4 &intc 50 3>;
> +		clocks = <&pcie0>;
> +		clock-names = "pcie";
> +		brcm,ssc;
> +		brcm,log2-scb-sizes = <0x1e 0x1e 0x1e>;
> +		vreg-wifi-pwr-supply-names = "vreg-wifi-pwr";
> +		vreg-wifi-pwr-supply = <&vreg-wifi-pwr>;
> +	};
> --
> 2.1.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in the
> body of a message to majordomo@vger.kernel.org More majordomo info at
> http://vger.kernel.org/majordomo-info.html

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

* RE: [PATCH v2 1/2] Documentation: DT: bindings: Add Broadcom STB PCIe bindings
@ 2016-05-11 14:45     ` Bharat Kumar Gogada
  0 siblings, 0 replies; 41+ messages in thread
From: Bharat Kumar Gogada @ 2016-05-11 14:45 UTC (permalink / raw)
  To: Florian Fainelli, linux-pci
  Cc: devicetree, arnd, linux-kernel, jim2101024,
	bcm-kernel-feedback-list, bhelgaas, linux-arm-kernel

> 
>  .../devicetree/bindings/pci/brcm,brcmstb-pcie.txt  | 98
> ++++++++++++++++++++++
>  1 file changed, 98 insertions(+)
>  create mode 100644
> Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
> 
> diff --git a/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
> b/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
> new file mode 100644
> index 000000000000..3682b0f0bc26
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
> @@ -0,0 +1,98 @@
> +Broadcom STB PCIe Host Controller Device Tree Bindings
> +
> +This document describes the binding of the PCIe Root Complex hardware
> +found in Broadcom Set Top Box System-on-Chips such as BCM7425 (MIPS),
> +BCM7435 (MIPS) and
> +BCM7445 (ARMv7).
> +
> +Required properties:
> +- compatible: must be one of: "brcm,bcm7425-pcie"
> +			      "brcm,bcm7435-pcie"
> +			      "brcm,bcm7445-pcie"
> +
> +- reg: specifies the physical base address of the controller registers
> +and
> +  its length
> +
> +- interrupt-parent: must be a reference (phandle) to the parent
> +interrupt
> +  controller in the system (7038-l1-intc on MIPS, GIC on ARM/ARM64)
> +
> +- interrrupts: first interrupt must be the Level 1 interrupt number
> +corresponding
> +  to the main PCIe RC interrupt, second interrupt must be the MSI
> +interrupt
> +  See the interrupt-parent documentation for the number of cells and their
> meaning:
> +  MIPS:
> +Documentation/devicetree/bindings/interrupt-controller/brcm,bcm7038-
> l1-
> +intc.txt
> +  ARM/ARM64:
> +Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt
> +
> +- interrupt-names: must be "pcie", and if present "msi"
> +
> +- interrupt-map: see pci.txt
> +
> +- interrupt-map-mask: see pci.txt
> +
> +- #address-cells: must be set to <3>, see pci.txt
> +
> +- #size-cells: must be set to <2>, see pci.txt
> +
> +- ranges: ranges for the PCI outbound windows, no I/O or prefetchable
> +windows
> +  must be specified here, only non-prefetchable. 32-bits windows or
> +64-bits
> +  windows are allowed based on the host processor's capabilities (ARM
> +w/ LPAE,
> +  ARM64).
> +
> +- #interrupt-cells: set to <1>, see pci.txt
> +
> +- brcm,log2-scb-sizes: log2 size of the SCB window that is mapped to
> +PCIe space
> +  there must be exactly one value per memory controller present in the
> +system
> +  (ranges from 1 to 3)

Can you please give more insight on what does this property do ?

Bharat
> +
> +Optional properties:
> +
> +- msi-controller: indicates that this is a MSI controller node (when
> +supported)
> +
> +- clocks: phandle to the functional clock that feeds into the PCIe RC
> +block
> +
> +- clock-names: the name(s) of the clocks specified in 'clocks'.  Note
> +  that if the 'clocks' property is given, 'clock-names' is mandatory,
> +  and the name of the clock is expected to be "pcie".
> +
> +- brcm,ssc: boolean that indicates usage of spread-spectrum clocking
> +
> +- brcm,gen: integer that indicates desired forced generation of link: 1
> +=> 2.5
> +  Gbps, 2 => 5.0 Gbps, 3 => 8.0 Gbps. Will override the auto-negotation
> +if
> +  specified.
> +
> +- <*>-supply: see
> +Documentation/devicetree/bindings/regulator/regulator.txt
> +
> +- <*>-supply-names: see
> +Documentation/devicetree/bindings/regulator/regulator.txt
> +
> +Example Node:
> +
> +This example assumes that the top-level #address-cells = <2> and
> +#size-cells = <2>, e.g: ARM LPAE configuration.
> +
> +	pcie0: pcie-controller@f0460000 {
> +		reg = <0x0 0xf0460000 0x0 0x9310>;
> +		interrupts = <0x0 0x33 0x4>, <0x0 0x34, 0x4>;
> +		interrupt-names = "pcie", "msi";
> +		compatible = "brcm,bcm7445-pcie";
> +		#address-cells = <3>;
> +		#size-cells = <2>;
> +
> +		/* Two non-prefetchable 32-bits memory space, each of
> 128MB
> + 		 * with the following mapping:
> +		 * PCIe address		=> CPU physical address space
> +		 * 0x00_0000_0000	=> 0x00_C000_0000
> +		 * 0x00_0800_0000	=> 0x00_C800_0000
> +		 */
> +		ranges = <0x02000000 0x00000000 0x00000000 0x00000000
> 0xc0000000 0x00000000 0x08000000>,
> +			 <0x02000000 0x00000000 0x08000000 0x00000000
> 0xc8000000 0x00000000 0x08000000>;
> +		#interrupt-cells = <1>;
> +		interrupt-map-mask = <0xf800 0 0 7>;
> +		interrupt-map = <0 0 0 1 &intc 47 3
> +				 0 0 0 2 &intc 48 3
> +				 0 0 0 3 &intc 49 3
> +				 0 0 0 4 &intc 50 3>;
> +		clocks = <&pcie0>;
> +		clock-names = "pcie";
> +		brcm,ssc;
> +		brcm,log2-scb-sizes = <0x1e 0x1e 0x1e>;
> +		vreg-wifi-pwr-supply-names = "vreg-wifi-pwr";
> +		vreg-wifi-pwr-supply = <&vreg-wifi-pwr>;
> +	};
> --
> 2.1.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in the
> body of a message to majordomo@vger.kernel.org More majordomo info at
> http://vger.kernel.org/majordomo-info.html

_______________________________________________
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] 41+ messages in thread

* [PATCH v2 1/2] Documentation: DT: bindings: Add Broadcom STB PCIe bindings
@ 2016-05-11 14:45     ` Bharat Kumar Gogada
  0 siblings, 0 replies; 41+ messages in thread
From: Bharat Kumar Gogada @ 2016-05-11 14:45 UTC (permalink / raw)
  To: linux-arm-kernel

> 
>  .../devicetree/bindings/pci/brcm,brcmstb-pcie.txt  | 98
> ++++++++++++++++++++++
>  1 file changed, 98 insertions(+)
>  create mode 100644
> Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
> 
> diff --git a/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
> b/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
> new file mode 100644
> index 000000000000..3682b0f0bc26
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/brcm,brcmstb-pcie.txt
> @@ -0,0 +1,98 @@
> +Broadcom STB PCIe Host Controller Device Tree Bindings
> +
> +This document describes the binding of the PCIe Root Complex hardware
> +found in Broadcom Set Top Box System-on-Chips such as BCM7425 (MIPS),
> +BCM7435 (MIPS) and
> +BCM7445 (ARMv7).
> +
> +Required properties:
> +- compatible: must be one of: "brcm,bcm7425-pcie"
> +			      "brcm,bcm7435-pcie"
> +			      "brcm,bcm7445-pcie"
> +
> +- reg: specifies the physical base address of the controller registers
> +and
> +  its length
> +
> +- interrupt-parent: must be a reference (phandle) to the parent
> +interrupt
> +  controller in the system (7038-l1-intc on MIPS, GIC on ARM/ARM64)
> +
> +- interrrupts: first interrupt must be the Level 1 interrupt number
> +corresponding
> +  to the main PCIe RC interrupt, second interrupt must be the MSI
> +interrupt
> +  See the interrupt-parent documentation for the number of cells and their
> meaning:
> +  MIPS:
> +Documentation/devicetree/bindings/interrupt-controller/brcm,bcm7038-
> l1-
> +intc.txt
> +  ARM/ARM64:
> +Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt
> +
> +- interrupt-names: must be "pcie", and if present "msi"
> +
> +- interrupt-map: see pci.txt
> +
> +- interrupt-map-mask: see pci.txt
> +
> +- #address-cells: must be set to <3>, see pci.txt
> +
> +- #size-cells: must be set to <2>, see pci.txt
> +
> +- ranges: ranges for the PCI outbound windows, no I/O or prefetchable
> +windows
> +  must be specified here, only non-prefetchable. 32-bits windows or
> +64-bits
> +  windows are allowed based on the host processor's capabilities (ARM
> +w/ LPAE,
> +  ARM64).
> +
> +- #interrupt-cells: set to <1>, see pci.txt
> +
> +- brcm,log2-scb-sizes: log2 size of the SCB window that is mapped to
> +PCIe space
> +  there must be exactly one value per memory controller present in the
> +system
> +  (ranges from 1 to 3)

Can you please give more insight on what does this property do ?

Bharat
> +
> +Optional properties:
> +
> +- msi-controller: indicates that this is a MSI controller node (when
> +supported)
> +
> +- clocks: phandle to the functional clock that feeds into the PCIe RC
> +block
> +
> +- clock-names: the name(s) of the clocks specified in 'clocks'.  Note
> +  that if the 'clocks' property is given, 'clock-names' is mandatory,
> +  and the name of the clock is expected to be "pcie".
> +
> +- brcm,ssc: boolean that indicates usage of spread-spectrum clocking
> +
> +- brcm,gen: integer that indicates desired forced generation of link: 1
> +=> 2.5
> +  Gbps, 2 => 5.0 Gbps, 3 => 8.0 Gbps. Will override the auto-negotation
> +if
> +  specified.
> +
> +- <*>-supply: see
> +Documentation/devicetree/bindings/regulator/regulator.txt
> +
> +- <*>-supply-names: see
> +Documentation/devicetree/bindings/regulator/regulator.txt
> +
> +Example Node:
> +
> +This example assumes that the top-level #address-cells = <2> and
> +#size-cells = <2>, e.g: ARM LPAE configuration.
> +
> +	pcie0: pcie-controller at f0460000 {
> +		reg = <0x0 0xf0460000 0x0 0x9310>;
> +		interrupts = <0x0 0x33 0x4>, <0x0 0x34, 0x4>;
> +		interrupt-names = "pcie", "msi";
> +		compatible = "brcm,bcm7445-pcie";
> +		#address-cells = <3>;
> +		#size-cells = <2>;
> +
> +		/* Two non-prefetchable 32-bits memory space, each of
> 128MB
> + 		 * with the following mapping:
> +		 * PCIe address		=> CPU physical address space
> +		 * 0x00_0000_0000	=> 0x00_C000_0000
> +		 * 0x00_0800_0000	=> 0x00_C800_0000
> +		 */
> +		ranges = <0x02000000 0x00000000 0x00000000 0x00000000
> 0xc0000000 0x00000000 0x08000000>,
> +			 <0x02000000 0x00000000 0x08000000 0x00000000
> 0xc8000000 0x00000000 0x08000000>;
> +		#interrupt-cells = <1>;
> +		interrupt-map-mask = <0xf800 0 0 7>;
> +		interrupt-map = <0 0 0 1 &intc 47 3
> +				 0 0 0 2 &intc 48 3
> +				 0 0 0 3 &intc 49 3
> +				 0 0 0 4 &intc 50 3>;
> +		clocks = <&pcie0>;
> +		clock-names = "pcie";
> +		brcm,ssc;
> +		brcm,log2-scb-sizes = <0x1e 0x1e 0x1e>;
> +		vreg-wifi-pwr-supply-names = "vreg-wifi-pwr";
> +		vreg-wifi-pwr-supply = <&vreg-wifi-pwr>;
> +	};
> --
> 2.1.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in the
> body of a message to majordomo at vger.kernel.org More majordomo info at
> http://vger.kernel.org/majordomo-info.html

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

* RE: [PATCH v2 2/2] pci: host: Add Broadcom STB PCIE RC controller
  2016-05-05 19:15   ` Florian Fainelli
  (?)
  (?)
@ 2016-05-11 14:47     ` Bharat Kumar Gogada
  -1 siblings, 0 replies; 41+ messages in thread
From: Bharat Kumar Gogada @ 2016-05-11 14:47 UTC (permalink / raw)
  To: Florian Fainelli, linux-pci
  Cc: linux-kernel, devicetree, linux-arm-kernel,
	bcm-kernel-feedback-list, jim2101024, bhelgaas, arnd

> +
> +static struct pci_ops brcm_pcie_ops = {
> +	.read = brcm_pcie_read_config,
> +	.write = brcm_pcie_write_config,
> +};
> +
> +static int brcm_pcie_probe(struct platform_device *pdev) {
> +	struct device_node *dn = pdev->dev.of_node;
> +	const u32 *log2_scb_sizes, *dma_ranges;
> +	const struct brcm_pcie_cfg_data *data;
> +	const struct of_device_id *of_id;
> +	struct brcm_pcie *pcie;
> +	void __iomem *base;
> +	struct resource *r;
> +	int i, rlen, ret;
> +	u32 tmp;
> +
> +	pcie = devm_kzalloc(&pdev->dev, sizeof(struct brcm_pcie),
> GFP_KERNEL);
> +	if (!pcie)
> +		return -ENOMEM;
> +
> +	of_id = of_match_node(brcm_pcie_match, dn);
> +	if (!of_id)
> +		return -EINVAL;
> +
> +	data = of_id->data;
> +	pcie->type = data->type;
> +	pcie->ops = &data->ops;
> +
> +	platform_set_drvdata(pdev, pcie);
> +
> +	INIT_LIST_HEAD(&pcie->resource);
> +
> +	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	base = devm_ioremap_resource(&pdev->dev, r);
> +	if (IS_ERR(base))
> +		return PTR_ERR(base);
> +
> +	ret = of_alias_get_id(dn, "pcie");
> +	if (ret >= 0)
> +		pcie->num = ret;
> +
> +	pcie->clk = devm_clk_get(&pdev->dev, "pcie");
> +	if (IS_ERR(pcie->clk)) {
> +		dev_err(&pdev->dev, "could not get clock\n");
> +		pcie->clk = NULL;
> +	}
> +
> +	ret = clk_prepare_enable(pcie->clk);
> +	if (ret) {
> +		dev_err(&pdev->dev, "could not enable clock\n");
> +		return ret;
> +	}
> +
> +	pcie->dn = dn;
> +	pcie->base = base;
> +	pcie->dev = &pdev->dev;
> +	pcie->dev->of_node = dn;
> +	pcie->gen = 0;
> +
> +	ret = of_property_read_u32(dn, "brcm,gen", &tmp);
> +	if (ret == 0) {
> +		if (tmp > 0 && tmp < 3)
> +			pcie->gen = (int)tmp;
> +		else
> +			dev_warn(pcie->dev, "bad DT value for prop
> 'brcm,gen");
> +	} else if (ret != -EINVAL) {
> +		dev_warn(pcie->dev, "error reading DT prop 'brcm,gen");
> +	}
> +
> +	pcie->ssc = of_property_read_bool(dn, "brcm,ssc");
> +
> +	/* Get the value for the log2 of the scb sizes. Subtract 15 from
> +	 * each because the target register field has 0==disabled and 1==6KB.
> +	 */
> +	log2_scb_sizes = of_get_property(dn, "brcm,log2-scb-sizes", &rlen);
> +	if (log2_scb_sizes) {
> +		for (i = 0; i < rlen / sizeof(u32); i++) {
> +			pcie->scb_size_vals[i]
> +				= (int)of_read_number(log2_scb_sizes + i, 1)
> +					- 15;
> +			pcie->num_memc++;
> +		}
> +	}
In your device tree documentation this is required property, what if this property 
is missing ?
> +
> +	/* Look for the dma-ranges property.  If it exists, issue a warning
> +	 * as PCIe drivers may not work.  This is because the identity
> +	 * mapping between system memory and PCIe space is not
> preserved,
> +	 * and we need Linux to massage the dma_addr_t values it gets
> +	 * from dma memory allocation.  This functionality will be added
> +	 * in the near future.
> +	 */
> +	dma_ranges = of_get_property(dn, "dma-ranges", &rlen);
> +	if (dma_ranges != NULL)
> +		dev_warn(pcie->dev, "no identity map; PCI drivers may fail");
> +
> +	if (IS_ENABLED(CONFIG_PCI_MSI)) {
> +		ret = irq_of_parse_and_map(pdev->dev.of_node, 1);
> +		if (ret == 0)
> +			dev_warn(pcie->dev, "cannot get msi intr; MSI
> disabled\n");
> +		else
> +			pcie->msi_irq = ret;
> +	}
> +
> +	ret = of_pci_get_host_bridge_resources(dn, 0, 0xff,
> +					       &pcie->resource, NULL);
> +	if (ret) {
> +		dev_err(pcie->dev, "ranges parsing failed\n");
> +		return ret;
> +	}
> +
> +	ret = brcm_pcie_setup_early(pcie);
> +	if (ret)
> +		goto out_err_clk;
> +
> +	/* If setup bridge fails, it cleans up behind itself */
> +	ret = brcm_setup_pcie_bridge(pcie);
> +	if (ret)
> +		goto out_err;
> +
> +	pcie->bus = pci_scan_root_bus(pcie->dev, pcie->num,
> &brcm_pcie_ops,
> +				      pcie, &pcie->resource);
> +	if (!pcie->bus) {
> +		ret = -ENOMEM;
> +		goto out_err_bus;
> +	}
> +
> +	if (IS_ENABLED(CONFIG_PCI_MSI))
> +		brcm_pcie_msi_chip_set(pcie);
> +
> +	pci_bus_size_bridges(pcie->bus);
> +	pci_bus_assign_resources(pcie->bus);
> +
> +	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
> +	pci_bus_add_devices(pcie->bus);
> +
> +	return 0;
> +
> +out_err_bus:
> +	brcm_pcie_enter_l23(pcie);
> +	brcm_pcie_turn_off(pcie);
> +out_err_clk:
> +	clk_disable_unprepare(pcie->clk);
> +out_err:
> +	return ret;
> +}
> +
> +static int brcm_pcie_remove(struct platform_device *pdev) {
> +	return brcm_pcie_suspend(&pdev->dev);
> +}
> +
> +static struct platform_driver brcm_pcie_driver = {
> +	.probe = brcm_pcie_probe,
> +	.remove = brcm_pcie_remove,
> +	.driver = {
> +		.name = "brcm-pcie",
> +		.owner = THIS_MODULE,
> +		.of_match_table = brcm_pcie_match,
> +		.pm = &brcm_pcie_pm_ops,
> +	},
> +};
> +module_platform_driver(brcm_pcie_driver);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_DESCRIPTION("Broadcom STB PCIE RC driver");
> +MODULE_AUTHOR("Broadcom");
> diff --git a/drivers/pci/host/pcie-brcmstb.h b/drivers/pci/host/pcie-
> brcmstb.h new file mode 100644 index 000000000000..b4a507423bb0
> --- /dev/null
> +++ b/drivers/pci/host/pcie-brcmstb.h
> @@ -0,0 +1,160 @@
> +#ifndef __PCIE_BRCMSTB_H
> +#define __PCIE_BRCMSTB_H
> +
> +#include <linux/io.h>
> +
> +/* Broadcom PCIE Offsets */
> +#define PCIE_RC_CFG_PCIE_LINK_CAPABILITY		0x00b8
> +#define PCIE_RC_CFG_PCIE_LINK_STATUS_CONTROL
> 	0x00bc
> +#define PCIE_RC_CFG_PCIE_ROOT_CAP_CONTROL		0x00c8
> +#define PCIE_RC_CFG_PCIE_LINK_STATUS_CONTROL_2
> 	0x00dc
> +#define PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1
> 	0x0188
> +#define PCIE_RC_CFG_PRIV1_ID_VAL3			0x043c
> +#define PCIE_RC_DL_MDIO_ADDR				0x1100
> +#define PCIE_RC_DL_MDIO_WR_DATA
> 	0x1104
> +#define PCIE_RC_DL_MDIO_RD_DATA
> 	0x1108
> +#define PCIE_MISC_MISC_CTRL				0x4008
> +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO		0x400c
> +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI		0x4010
> +#define PCIE_MISC_RC_BAR1_CONFIG_LO			0x402c
> +#define PCIE_MISC_RC_BAR1_CONFIG_HI			0x4030
> +#define PCIE_MISC_RC_BAR2_CONFIG_LO			0x4034
> +#define PCIE_MISC_RC_BAR2_CONFIG_HI			0x4038
> +#define PCIE_MISC_RC_BAR3_CONFIG_LO			0x403c
> +#define PCIE_MISC_RC_BAR3_CONFIG_HI			0x4040
> +#define PCIE_MISC_MSI_BAR_CONFIG_LO			0x4044
> +#define PCIE_MISC_MSI_BAR_CONFIG_HI			0x4048
> +#define PCIE_MISC_MSI_DATA_CONFIG			0x404c
> +#define PCIE_MISC_PCIE_CTRL				0x4064
> +#define PCIE_MISC_PCIE_STATUS				0x4068
> +#define PCIE_MISC_REVISION				0x406c
> +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT	0x4070
> +#define PCIE_MISC_HARD_PCIE_HARD_DEBUG
> 	0x4204
> +#define PCIE_INTR2_CPU_BASE				0x4300
> +#define PCIE_MSI_INTR2_BASE				0x4500
> +
> +#define PCIE_RGR1_SW_INIT_1				0x9210
> +#define PCIE_EXT_CFG_INDEX				0x9000
> +#define PCIE_EXT_CFG_DATA				0x9004
> +
> +/* BCM7425 specific register offsets */
> +#define BCM7425_PCIE_RGR1_SW_INIT_1			0x8010
> +#define BCM7425_PCIE_EXT_CFG_INDEX			0x8300
> +#define BCM7425_PCIE_EXT_CFG_DATA			0x8304
> +
> +#define PCI_BUSNUM_SHIFT		20
> +#define PCI_SLOT_SHIFT			15
> +#define PCI_FUNC_SHIFT			12
> +
> +#define BRCM_NUM_PCI_OUT_WINS		4
> +#define BRCM_MAX_SCB			4
> +
> +/* Offsets from PCIE_INTR2_CPU_BASE and PCIE_MSI_INTR2_BASE */
> +#define STATUS				0x0
> +#define SET				0x4
> +#define CLR				0x8
> +#define MASK_STATUS			0xc
> +#define MASK_SET			0x10
> +#define MASK_CLR			0x14
> +
> +enum brcm_pcie_type {
> +	BCM7425,
> +	BCM7435,
> +	GENERIC,
> +};
> +
> +struct brcm_pcie;
> +
> +/* Chip-specific PCIe operations (read/write config and reset) */
> +struct brcm_pcie_ll_ops {
> +	u32 (*read_config)(struct brcm_pcie *pcie, int cfg_idx);
> +	void (*write_config)(struct brcm_pcie *pcie, int cfg_idx, u32 val);
> +	void (*rgr1_sw_init)(struct brcm_pcie *pcie, u32 mask,
> +			     int shift, u32 val);
> +};
> +
> +struct brcm_pcie_cfg_data {
> +	const enum brcm_pcie_type type;
> +	const struct brcm_pcie_ll_ops ops;
> +};
> +
> +struct brcm_msi;
> +
> +/* Internal Bus Controller Information.*/ struct brcm_pcie {
> +	void __iomem		*base;
> +	bool			suspended;
> +	struct clk		*clk;
> +	struct device_node	*dn;
> +	bool			ssc;
> +	int			gen;
> +	int			scb_size_vals[BRCM_MAX_SCB];
> +	struct pci_bus		*bus;
> +	struct device		*dev;
> +	struct list_head	resource;
> +	int			msi_irq;
> +	struct brcm_msi		*msi;
> +	unsigned int		rev;
> +	unsigned int		num;
> +	bool			bridge_setup_done;
> +	enum brcm_pcie_type	type;
> +	const struct brcm_pcie_ll_ops *ops;
> +	unsigned int		num_memc;
> +};
> +
> +/* Helper functions to access read/write config space and software init
> +which
> + * are chip-specific
> + */
> +static inline u32 brcm_pcie_ll_read_config(struct brcm_pcie *pcie, int
> +cfg_idx) {
> +	return pcie->ops->read_config(pcie, cfg_idx); }
> +
> +static inline void brcm_pcie_ll_write_config(struct brcm_pcie *pcie,
> +					     int cfg_idx, u32 val)
> +{
> +	pcie->ops->write_config(pcie, cfg_idx, val); }
> +
> +static inline void brcm_pcie_rgr1_sw_init(struct brcm_pcie *pcie, u32 mask,
> +					  int shift, u32 val)
> +{
> +	pcie->ops->rgr1_sw_init(pcie, mask, shift, val); }
> +
> +/*
> + * MIPS endianness is configured by boot strap, which also reverses all
> + * bus endianness (i.e., big-endian CPU + big endian bus ==> native
> + * endian I/O).
> + *
> + * Other architectures (e.g., ARM) either do not support big endian, or
> + * else leave I/O in little endian mode.
> + */
> +static inline u32 bpcie_readl(void __iomem *base) {
> +	if (IS_ENABLED(CONFIG_MIPS))
> +		return __raw_readl(base);
> +	else
> +		return readl(base);
> +}
> +
> +static inline void bpcie_writel(u32 val, void __iomem *base) {
> +	if (IS_ENABLED(CONFIG_MIPS))
> +		__raw_writel(val, base);
> +	else
> +		writel(val, base);
> +}
> +
> +#ifdef CONFIG_PCIE_BRCMSTB_MSI
> +int brcm_pcie_enable_msi(struct brcm_pcie *pcie, int nr); void
> +brcm_pcie_msi_chip_set(struct brcm_pcie *pcie); #else static inline int
> +brcm_pcie_enable_msi(struct brcm_pcie *pcie, int nr) {
> +	return 0;
> +}
> +static inline void brcm_pcie_msi_chip_set(struct brcm_pcie *pcie) { }
> +#endif
> +
> +#endif /* __PCIE_BRCMSTB_H */
> --
> 2.1.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in the
> body of a message to majordomo@vger.kernel.org More majordomo info at
> http://vger.kernel.org/majordomo-info.html

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

* RE: [PATCH v2 2/2] pci: host: Add Broadcom STB PCIE RC controller
@ 2016-05-11 14:47     ` Bharat Kumar Gogada
  0 siblings, 0 replies; 41+ messages in thread
From: Bharat Kumar Gogada @ 2016-05-11 14:47 UTC (permalink / raw)
  To: Florian Fainelli, linux-pci
  Cc: devicetree, arnd, linux-kernel, jim2101024,
	bcm-kernel-feedback-list, bhelgaas, linux-arm-kernel

> +
> +static struct pci_ops brcm_pcie_ops = {
> +	.read = brcm_pcie_read_config,
> +	.write = brcm_pcie_write_config,
> +};
> +
> +static int brcm_pcie_probe(struct platform_device *pdev) {
> +	struct device_node *dn = pdev->dev.of_node;
> +	const u32 *log2_scb_sizes, *dma_ranges;
> +	const struct brcm_pcie_cfg_data *data;
> +	const struct of_device_id *of_id;
> +	struct brcm_pcie *pcie;
> +	void __iomem *base;
> +	struct resource *r;
> +	int i, rlen, ret;
> +	u32 tmp;
> +
> +	pcie = devm_kzalloc(&pdev->dev, sizeof(struct brcm_pcie),
> GFP_KERNEL);
> +	if (!pcie)
> +		return -ENOMEM;
> +
> +	of_id = of_match_node(brcm_pcie_match, dn);
> +	if (!of_id)
> +		return -EINVAL;
> +
> +	data = of_id->data;
> +	pcie->type = data->type;
> +	pcie->ops = &data->ops;
> +
> +	platform_set_drvdata(pdev, pcie);
> +
> +	INIT_LIST_HEAD(&pcie->resource);
> +
> +	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	base = devm_ioremap_resource(&pdev->dev, r);
> +	if (IS_ERR(base))
> +		return PTR_ERR(base);
> +
> +	ret = of_alias_get_id(dn, "pcie");
> +	if (ret >= 0)
> +		pcie->num = ret;
> +
> +	pcie->clk = devm_clk_get(&pdev->dev, "pcie");
> +	if (IS_ERR(pcie->clk)) {
> +		dev_err(&pdev->dev, "could not get clock\n");
> +		pcie->clk = NULL;
> +	}
> +
> +	ret = clk_prepare_enable(pcie->clk);
> +	if (ret) {
> +		dev_err(&pdev->dev, "could not enable clock\n");
> +		return ret;
> +	}
> +
> +	pcie->dn = dn;
> +	pcie->base = base;
> +	pcie->dev = &pdev->dev;
> +	pcie->dev->of_node = dn;
> +	pcie->gen = 0;
> +
> +	ret = of_property_read_u32(dn, "brcm,gen", &tmp);
> +	if (ret == 0) {
> +		if (tmp > 0 && tmp < 3)
> +			pcie->gen = (int)tmp;
> +		else
> +			dev_warn(pcie->dev, "bad DT value for prop
> 'brcm,gen");
> +	} else if (ret != -EINVAL) {
> +		dev_warn(pcie->dev, "error reading DT prop 'brcm,gen");
> +	}
> +
> +	pcie->ssc = of_property_read_bool(dn, "brcm,ssc");
> +
> +	/* Get the value for the log2 of the scb sizes. Subtract 15 from
> +	 * each because the target register field has 0==disabled and 1==6KB.
> +	 */
> +	log2_scb_sizes = of_get_property(dn, "brcm,log2-scb-sizes", &rlen);
> +	if (log2_scb_sizes) {
> +		for (i = 0; i < rlen / sizeof(u32); i++) {
> +			pcie->scb_size_vals[i]
> +				= (int)of_read_number(log2_scb_sizes + i, 1)
> +					- 15;
> +			pcie->num_memc++;
> +		}
> +	}
In your device tree documentation this is required property, what if this property 
is missing ?
> +
> +	/* Look for the dma-ranges property.  If it exists, issue a warning
> +	 * as PCIe drivers may not work.  This is because the identity
> +	 * mapping between system memory and PCIe space is not
> preserved,
> +	 * and we need Linux to massage the dma_addr_t values it gets
> +	 * from dma memory allocation.  This functionality will be added
> +	 * in the near future.
> +	 */
> +	dma_ranges = of_get_property(dn, "dma-ranges", &rlen);
> +	if (dma_ranges != NULL)
> +		dev_warn(pcie->dev, "no identity map; PCI drivers may fail");
> +
> +	if (IS_ENABLED(CONFIG_PCI_MSI)) {
> +		ret = irq_of_parse_and_map(pdev->dev.of_node, 1);
> +		if (ret == 0)
> +			dev_warn(pcie->dev, "cannot get msi intr; MSI
> disabled\n");
> +		else
> +			pcie->msi_irq = ret;
> +	}
> +
> +	ret = of_pci_get_host_bridge_resources(dn, 0, 0xff,
> +					       &pcie->resource, NULL);
> +	if (ret) {
> +		dev_err(pcie->dev, "ranges parsing failed\n");
> +		return ret;
> +	}
> +
> +	ret = brcm_pcie_setup_early(pcie);
> +	if (ret)
> +		goto out_err_clk;
> +
> +	/* If setup bridge fails, it cleans up behind itself */
> +	ret = brcm_setup_pcie_bridge(pcie);
> +	if (ret)
> +		goto out_err;
> +
> +	pcie->bus = pci_scan_root_bus(pcie->dev, pcie->num,
> &brcm_pcie_ops,
> +				      pcie, &pcie->resource);
> +	if (!pcie->bus) {
> +		ret = -ENOMEM;
> +		goto out_err_bus;
> +	}
> +
> +	if (IS_ENABLED(CONFIG_PCI_MSI))
> +		brcm_pcie_msi_chip_set(pcie);
> +
> +	pci_bus_size_bridges(pcie->bus);
> +	pci_bus_assign_resources(pcie->bus);
> +
> +	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
> +	pci_bus_add_devices(pcie->bus);
> +
> +	return 0;
> +
> +out_err_bus:
> +	brcm_pcie_enter_l23(pcie);
> +	brcm_pcie_turn_off(pcie);
> +out_err_clk:
> +	clk_disable_unprepare(pcie->clk);
> +out_err:
> +	return ret;
> +}
> +
> +static int brcm_pcie_remove(struct platform_device *pdev) {
> +	return brcm_pcie_suspend(&pdev->dev);
> +}
> +
> +static struct platform_driver brcm_pcie_driver = {
> +	.probe = brcm_pcie_probe,
> +	.remove = brcm_pcie_remove,
> +	.driver = {
> +		.name = "brcm-pcie",
> +		.owner = THIS_MODULE,
> +		.of_match_table = brcm_pcie_match,
> +		.pm = &brcm_pcie_pm_ops,
> +	},
> +};
> +module_platform_driver(brcm_pcie_driver);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_DESCRIPTION("Broadcom STB PCIE RC driver");
> +MODULE_AUTHOR("Broadcom");
> diff --git a/drivers/pci/host/pcie-brcmstb.h b/drivers/pci/host/pcie-
> brcmstb.h new file mode 100644 index 000000000000..b4a507423bb0
> --- /dev/null
> +++ b/drivers/pci/host/pcie-brcmstb.h
> @@ -0,0 +1,160 @@
> +#ifndef __PCIE_BRCMSTB_H
> +#define __PCIE_BRCMSTB_H
> +
> +#include <linux/io.h>
> +
> +/* Broadcom PCIE Offsets */
> +#define PCIE_RC_CFG_PCIE_LINK_CAPABILITY		0x00b8
> +#define PCIE_RC_CFG_PCIE_LINK_STATUS_CONTROL
> 	0x00bc
> +#define PCIE_RC_CFG_PCIE_ROOT_CAP_CONTROL		0x00c8
> +#define PCIE_RC_CFG_PCIE_LINK_STATUS_CONTROL_2
> 	0x00dc
> +#define PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1
> 	0x0188
> +#define PCIE_RC_CFG_PRIV1_ID_VAL3			0x043c
> +#define PCIE_RC_DL_MDIO_ADDR				0x1100
> +#define PCIE_RC_DL_MDIO_WR_DATA
> 	0x1104
> +#define PCIE_RC_DL_MDIO_RD_DATA
> 	0x1108
> +#define PCIE_MISC_MISC_CTRL				0x4008
> +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO		0x400c
> +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI		0x4010
> +#define PCIE_MISC_RC_BAR1_CONFIG_LO			0x402c
> +#define PCIE_MISC_RC_BAR1_CONFIG_HI			0x4030
> +#define PCIE_MISC_RC_BAR2_CONFIG_LO			0x4034
> +#define PCIE_MISC_RC_BAR2_CONFIG_HI			0x4038
> +#define PCIE_MISC_RC_BAR3_CONFIG_LO			0x403c
> +#define PCIE_MISC_RC_BAR3_CONFIG_HI			0x4040
> +#define PCIE_MISC_MSI_BAR_CONFIG_LO			0x4044
> +#define PCIE_MISC_MSI_BAR_CONFIG_HI			0x4048
> +#define PCIE_MISC_MSI_DATA_CONFIG			0x404c
> +#define PCIE_MISC_PCIE_CTRL				0x4064
> +#define PCIE_MISC_PCIE_STATUS				0x4068
> +#define PCIE_MISC_REVISION				0x406c
> +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT	0x4070
> +#define PCIE_MISC_HARD_PCIE_HARD_DEBUG
> 	0x4204
> +#define PCIE_INTR2_CPU_BASE				0x4300
> +#define PCIE_MSI_INTR2_BASE				0x4500
> +
> +#define PCIE_RGR1_SW_INIT_1				0x9210
> +#define PCIE_EXT_CFG_INDEX				0x9000
> +#define PCIE_EXT_CFG_DATA				0x9004
> +
> +/* BCM7425 specific register offsets */
> +#define BCM7425_PCIE_RGR1_SW_INIT_1			0x8010
> +#define BCM7425_PCIE_EXT_CFG_INDEX			0x8300
> +#define BCM7425_PCIE_EXT_CFG_DATA			0x8304
> +
> +#define PCI_BUSNUM_SHIFT		20
> +#define PCI_SLOT_SHIFT			15
> +#define PCI_FUNC_SHIFT			12
> +
> +#define BRCM_NUM_PCI_OUT_WINS		4
> +#define BRCM_MAX_SCB			4
> +
> +/* Offsets from PCIE_INTR2_CPU_BASE and PCIE_MSI_INTR2_BASE */
> +#define STATUS				0x0
> +#define SET				0x4
> +#define CLR				0x8
> +#define MASK_STATUS			0xc
> +#define MASK_SET			0x10
> +#define MASK_CLR			0x14
> +
> +enum brcm_pcie_type {
> +	BCM7425,
> +	BCM7435,
> +	GENERIC,
> +};
> +
> +struct brcm_pcie;
> +
> +/* Chip-specific PCIe operations (read/write config and reset) */
> +struct brcm_pcie_ll_ops {
> +	u32 (*read_config)(struct brcm_pcie *pcie, int cfg_idx);
> +	void (*write_config)(struct brcm_pcie *pcie, int cfg_idx, u32 val);
> +	void (*rgr1_sw_init)(struct brcm_pcie *pcie, u32 mask,
> +			     int shift, u32 val);
> +};
> +
> +struct brcm_pcie_cfg_data {
> +	const enum brcm_pcie_type type;
> +	const struct brcm_pcie_ll_ops ops;
> +};
> +
> +struct brcm_msi;
> +
> +/* Internal Bus Controller Information.*/ struct brcm_pcie {
> +	void __iomem		*base;
> +	bool			suspended;
> +	struct clk		*clk;
> +	struct device_node	*dn;
> +	bool			ssc;
> +	int			gen;
> +	int			scb_size_vals[BRCM_MAX_SCB];
> +	struct pci_bus		*bus;
> +	struct device		*dev;
> +	struct list_head	resource;
> +	int			msi_irq;
> +	struct brcm_msi		*msi;
> +	unsigned int		rev;
> +	unsigned int		num;
> +	bool			bridge_setup_done;
> +	enum brcm_pcie_type	type;
> +	const struct brcm_pcie_ll_ops *ops;
> +	unsigned int		num_memc;
> +};
> +
> +/* Helper functions to access read/write config space and software init
> +which
> + * are chip-specific
> + */
> +static inline u32 brcm_pcie_ll_read_config(struct brcm_pcie *pcie, int
> +cfg_idx) {
> +	return pcie->ops->read_config(pcie, cfg_idx); }
> +
> +static inline void brcm_pcie_ll_write_config(struct brcm_pcie *pcie,
> +					     int cfg_idx, u32 val)
> +{
> +	pcie->ops->write_config(pcie, cfg_idx, val); }
> +
> +static inline void brcm_pcie_rgr1_sw_init(struct brcm_pcie *pcie, u32 mask,
> +					  int shift, u32 val)
> +{
> +	pcie->ops->rgr1_sw_init(pcie, mask, shift, val); }
> +
> +/*
> + * MIPS endianness is configured by boot strap, which also reverses all
> + * bus endianness (i.e., big-endian CPU + big endian bus ==> native
> + * endian I/O).
> + *
> + * Other architectures (e.g., ARM) either do not support big endian, or
> + * else leave I/O in little endian mode.
> + */
> +static inline u32 bpcie_readl(void __iomem *base) {
> +	if (IS_ENABLED(CONFIG_MIPS))
> +		return __raw_readl(base);
> +	else
> +		return readl(base);
> +}
> +
> +static inline void bpcie_writel(u32 val, void __iomem *base) {
> +	if (IS_ENABLED(CONFIG_MIPS))
> +		__raw_writel(val, base);
> +	else
> +		writel(val, base);
> +}
> +
> +#ifdef CONFIG_PCIE_BRCMSTB_MSI
> +int brcm_pcie_enable_msi(struct brcm_pcie *pcie, int nr); void
> +brcm_pcie_msi_chip_set(struct brcm_pcie *pcie); #else static inline int
> +brcm_pcie_enable_msi(struct brcm_pcie *pcie, int nr) {
> +	return 0;
> +}
> +static inline void brcm_pcie_msi_chip_set(struct brcm_pcie *pcie) { }
> +#endif
> +
> +#endif /* __PCIE_BRCMSTB_H */
> --
> 2.1.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in the
> body of a message to majordomo@vger.kernel.org More majordomo info at
> http://vger.kernel.org/majordomo-info.html

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

* RE: [PATCH v2 2/2] pci: host: Add Broadcom STB PCIE RC controller
@ 2016-05-11 14:47     ` Bharat Kumar Gogada
  0 siblings, 0 replies; 41+ messages in thread
From: Bharat Kumar Gogada @ 2016-05-11 14:47 UTC (permalink / raw)
  To: Florian Fainelli, linux-pci
  Cc: devicetree, arnd, linux-kernel, jim2101024,
	bcm-kernel-feedback-list, bhelgaas, linux-arm-kernel

> +
> +static struct pci_ops brcm_pcie_ops = {
> +	.read = brcm_pcie_read_config,
> +	.write = brcm_pcie_write_config,
> +};
> +
> +static int brcm_pcie_probe(struct platform_device *pdev) {
> +	struct device_node *dn = pdev->dev.of_node;
> +	const u32 *log2_scb_sizes, *dma_ranges;
> +	const struct brcm_pcie_cfg_data *data;
> +	const struct of_device_id *of_id;
> +	struct brcm_pcie *pcie;
> +	void __iomem *base;
> +	struct resource *r;
> +	int i, rlen, ret;
> +	u32 tmp;
> +
> +	pcie = devm_kzalloc(&pdev->dev, sizeof(struct brcm_pcie),
> GFP_KERNEL);
> +	if (!pcie)
> +		return -ENOMEM;
> +
> +	of_id = of_match_node(brcm_pcie_match, dn);
> +	if (!of_id)
> +		return -EINVAL;
> +
> +	data = of_id->data;
> +	pcie->type = data->type;
> +	pcie->ops = &data->ops;
> +
> +	platform_set_drvdata(pdev, pcie);
> +
> +	INIT_LIST_HEAD(&pcie->resource);
> +
> +	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	base = devm_ioremap_resource(&pdev->dev, r);
> +	if (IS_ERR(base))
> +		return PTR_ERR(base);
> +
> +	ret = of_alias_get_id(dn, "pcie");
> +	if (ret >= 0)
> +		pcie->num = ret;
> +
> +	pcie->clk = devm_clk_get(&pdev->dev, "pcie");
> +	if (IS_ERR(pcie->clk)) {
> +		dev_err(&pdev->dev, "could not get clock\n");
> +		pcie->clk = NULL;
> +	}
> +
> +	ret = clk_prepare_enable(pcie->clk);
> +	if (ret) {
> +		dev_err(&pdev->dev, "could not enable clock\n");
> +		return ret;
> +	}
> +
> +	pcie->dn = dn;
> +	pcie->base = base;
> +	pcie->dev = &pdev->dev;
> +	pcie->dev->of_node = dn;
> +	pcie->gen = 0;
> +
> +	ret = of_property_read_u32(dn, "brcm,gen", &tmp);
> +	if (ret == 0) {
> +		if (tmp > 0 && tmp < 3)
> +			pcie->gen = (int)tmp;
> +		else
> +			dev_warn(pcie->dev, "bad DT value for prop
> 'brcm,gen");
> +	} else if (ret != -EINVAL) {
> +		dev_warn(pcie->dev, "error reading DT prop 'brcm,gen");
> +	}
> +
> +	pcie->ssc = of_property_read_bool(dn, "brcm,ssc");
> +
> +	/* Get the value for the log2 of the scb sizes. Subtract 15 from
> +	 * each because the target register field has 0==disabled and 1==6KB.
> +	 */
> +	log2_scb_sizes = of_get_property(dn, "brcm,log2-scb-sizes", &rlen);
> +	if (log2_scb_sizes) {
> +		for (i = 0; i < rlen / sizeof(u32); i++) {
> +			pcie->scb_size_vals[i]
> +				= (int)of_read_number(log2_scb_sizes + i, 1)
> +					- 15;
> +			pcie->num_memc++;
> +		}
> +	}
In your device tree documentation this is required property, what if this property 
is missing ?
> +
> +	/* Look for the dma-ranges property.  If it exists, issue a warning
> +	 * as PCIe drivers may not work.  This is because the identity
> +	 * mapping between system memory and PCIe space is not
> preserved,
> +	 * and we need Linux to massage the dma_addr_t values it gets
> +	 * from dma memory allocation.  This functionality will be added
> +	 * in the near future.
> +	 */
> +	dma_ranges = of_get_property(dn, "dma-ranges", &rlen);
> +	if (dma_ranges != NULL)
> +		dev_warn(pcie->dev, "no identity map; PCI drivers may fail");
> +
> +	if (IS_ENABLED(CONFIG_PCI_MSI)) {
> +		ret = irq_of_parse_and_map(pdev->dev.of_node, 1);
> +		if (ret == 0)
> +			dev_warn(pcie->dev, "cannot get msi intr; MSI
> disabled\n");
> +		else
> +			pcie->msi_irq = ret;
> +	}
> +
> +	ret = of_pci_get_host_bridge_resources(dn, 0, 0xff,
> +					       &pcie->resource, NULL);
> +	if (ret) {
> +		dev_err(pcie->dev, "ranges parsing failed\n");
> +		return ret;
> +	}
> +
> +	ret = brcm_pcie_setup_early(pcie);
> +	if (ret)
> +		goto out_err_clk;
> +
> +	/* If setup bridge fails, it cleans up behind itself */
> +	ret = brcm_setup_pcie_bridge(pcie);
> +	if (ret)
> +		goto out_err;
> +
> +	pcie->bus = pci_scan_root_bus(pcie->dev, pcie->num,
> &brcm_pcie_ops,
> +				      pcie, &pcie->resource);
> +	if (!pcie->bus) {
> +		ret = -ENOMEM;
> +		goto out_err_bus;
> +	}
> +
> +	if (IS_ENABLED(CONFIG_PCI_MSI))
> +		brcm_pcie_msi_chip_set(pcie);
> +
> +	pci_bus_size_bridges(pcie->bus);
> +	pci_bus_assign_resources(pcie->bus);
> +
> +	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
> +	pci_bus_add_devices(pcie->bus);
> +
> +	return 0;
> +
> +out_err_bus:
> +	brcm_pcie_enter_l23(pcie);
> +	brcm_pcie_turn_off(pcie);
> +out_err_clk:
> +	clk_disable_unprepare(pcie->clk);
> +out_err:
> +	return ret;
> +}
> +
> +static int brcm_pcie_remove(struct platform_device *pdev) {
> +	return brcm_pcie_suspend(&pdev->dev);
> +}
> +
> +static struct platform_driver brcm_pcie_driver = {
> +	.probe = brcm_pcie_probe,
> +	.remove = brcm_pcie_remove,
> +	.driver = {
> +		.name = "brcm-pcie",
> +		.owner = THIS_MODULE,
> +		.of_match_table = brcm_pcie_match,
> +		.pm = &brcm_pcie_pm_ops,
> +	},
> +};
> +module_platform_driver(brcm_pcie_driver);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_DESCRIPTION("Broadcom STB PCIE RC driver");
> +MODULE_AUTHOR("Broadcom");
> diff --git a/drivers/pci/host/pcie-brcmstb.h b/drivers/pci/host/pcie-
> brcmstb.h new file mode 100644 index 000000000000..b4a507423bb0
> --- /dev/null
> +++ b/drivers/pci/host/pcie-brcmstb.h
> @@ -0,0 +1,160 @@
> +#ifndef __PCIE_BRCMSTB_H
> +#define __PCIE_BRCMSTB_H
> +
> +#include <linux/io.h>
> +
> +/* Broadcom PCIE Offsets */
> +#define PCIE_RC_CFG_PCIE_LINK_CAPABILITY		0x00b8
> +#define PCIE_RC_CFG_PCIE_LINK_STATUS_CONTROL
> 	0x00bc
> +#define PCIE_RC_CFG_PCIE_ROOT_CAP_CONTROL		0x00c8
> +#define PCIE_RC_CFG_PCIE_LINK_STATUS_CONTROL_2
> 	0x00dc
> +#define PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1
> 	0x0188
> +#define PCIE_RC_CFG_PRIV1_ID_VAL3			0x043c
> +#define PCIE_RC_DL_MDIO_ADDR				0x1100
> +#define PCIE_RC_DL_MDIO_WR_DATA
> 	0x1104
> +#define PCIE_RC_DL_MDIO_RD_DATA
> 	0x1108
> +#define PCIE_MISC_MISC_CTRL				0x4008
> +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO		0x400c
> +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI		0x4010
> +#define PCIE_MISC_RC_BAR1_CONFIG_LO			0x402c
> +#define PCIE_MISC_RC_BAR1_CONFIG_HI			0x4030
> +#define PCIE_MISC_RC_BAR2_CONFIG_LO			0x4034
> +#define PCIE_MISC_RC_BAR2_CONFIG_HI			0x4038
> +#define PCIE_MISC_RC_BAR3_CONFIG_LO			0x403c
> +#define PCIE_MISC_RC_BAR3_CONFIG_HI			0x4040
> +#define PCIE_MISC_MSI_BAR_CONFIG_LO			0x4044
> +#define PCIE_MISC_MSI_BAR_CONFIG_HI			0x4048
> +#define PCIE_MISC_MSI_DATA_CONFIG			0x404c
> +#define PCIE_MISC_PCIE_CTRL				0x4064
> +#define PCIE_MISC_PCIE_STATUS				0x4068
> +#define PCIE_MISC_REVISION				0x406c
> +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT	0x4070
> +#define PCIE_MISC_HARD_PCIE_HARD_DEBUG
> 	0x4204
> +#define PCIE_INTR2_CPU_BASE				0x4300
> +#define PCIE_MSI_INTR2_BASE				0x4500
> +
> +#define PCIE_RGR1_SW_INIT_1				0x9210
> +#define PCIE_EXT_CFG_INDEX				0x9000
> +#define PCIE_EXT_CFG_DATA				0x9004
> +
> +/* BCM7425 specific register offsets */
> +#define BCM7425_PCIE_RGR1_SW_INIT_1			0x8010
> +#define BCM7425_PCIE_EXT_CFG_INDEX			0x8300
> +#define BCM7425_PCIE_EXT_CFG_DATA			0x8304
> +
> +#define PCI_BUSNUM_SHIFT		20
> +#define PCI_SLOT_SHIFT			15
> +#define PCI_FUNC_SHIFT			12
> +
> +#define BRCM_NUM_PCI_OUT_WINS		4
> +#define BRCM_MAX_SCB			4
> +
> +/* Offsets from PCIE_INTR2_CPU_BASE and PCIE_MSI_INTR2_BASE */
> +#define STATUS				0x0
> +#define SET				0x4
> +#define CLR				0x8
> +#define MASK_STATUS			0xc
> +#define MASK_SET			0x10
> +#define MASK_CLR			0x14
> +
> +enum brcm_pcie_type {
> +	BCM7425,
> +	BCM7435,
> +	GENERIC,
> +};
> +
> +struct brcm_pcie;
> +
> +/* Chip-specific PCIe operations (read/write config and reset) */
> +struct brcm_pcie_ll_ops {
> +	u32 (*read_config)(struct brcm_pcie *pcie, int cfg_idx);
> +	void (*write_config)(struct brcm_pcie *pcie, int cfg_idx, u32 val);
> +	void (*rgr1_sw_init)(struct brcm_pcie *pcie, u32 mask,
> +			     int shift, u32 val);
> +};
> +
> +struct brcm_pcie_cfg_data {
> +	const enum brcm_pcie_type type;
> +	const struct brcm_pcie_ll_ops ops;
> +};
> +
> +struct brcm_msi;
> +
> +/* Internal Bus Controller Information.*/ struct brcm_pcie {
> +	void __iomem		*base;
> +	bool			suspended;
> +	struct clk		*clk;
> +	struct device_node	*dn;
> +	bool			ssc;
> +	int			gen;
> +	int			scb_size_vals[BRCM_MAX_SCB];
> +	struct pci_bus		*bus;
> +	struct device		*dev;
> +	struct list_head	resource;
> +	int			msi_irq;
> +	struct brcm_msi		*msi;
> +	unsigned int		rev;
> +	unsigned int		num;
> +	bool			bridge_setup_done;
> +	enum brcm_pcie_type	type;
> +	const struct brcm_pcie_ll_ops *ops;
> +	unsigned int		num_memc;
> +};
> +
> +/* Helper functions to access read/write config space and software init
> +which
> + * are chip-specific
> + */
> +static inline u32 brcm_pcie_ll_read_config(struct brcm_pcie *pcie, int
> +cfg_idx) {
> +	return pcie->ops->read_config(pcie, cfg_idx); }
> +
> +static inline void brcm_pcie_ll_write_config(struct brcm_pcie *pcie,
> +					     int cfg_idx, u32 val)
> +{
> +	pcie->ops->write_config(pcie, cfg_idx, val); }
> +
> +static inline void brcm_pcie_rgr1_sw_init(struct brcm_pcie *pcie, u32 mask,
> +					  int shift, u32 val)
> +{
> +	pcie->ops->rgr1_sw_init(pcie, mask, shift, val); }
> +
> +/*
> + * MIPS endianness is configured by boot strap, which also reverses all
> + * bus endianness (i.e., big-endian CPU + big endian bus ==> native
> + * endian I/O).
> + *
> + * Other architectures (e.g., ARM) either do not support big endian, or
> + * else leave I/O in little endian mode.
> + */
> +static inline u32 bpcie_readl(void __iomem *base) {
> +	if (IS_ENABLED(CONFIG_MIPS))
> +		return __raw_readl(base);
> +	else
> +		return readl(base);
> +}
> +
> +static inline void bpcie_writel(u32 val, void __iomem *base) {
> +	if (IS_ENABLED(CONFIG_MIPS))
> +		__raw_writel(val, base);
> +	else
> +		writel(val, base);
> +}
> +
> +#ifdef CONFIG_PCIE_BRCMSTB_MSI
> +int brcm_pcie_enable_msi(struct brcm_pcie *pcie, int nr); void
> +brcm_pcie_msi_chip_set(struct brcm_pcie *pcie); #else static inline int
> +brcm_pcie_enable_msi(struct brcm_pcie *pcie, int nr) {
> +	return 0;
> +}
> +static inline void brcm_pcie_msi_chip_set(struct brcm_pcie *pcie) { }
> +#endif
> +
> +#endif /* __PCIE_BRCMSTB_H */
> --
> 2.1.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in the
> body of a message to majordomo@vger.kernel.org More majordomo info at
> http://vger.kernel.org/majordomo-info.html

_______________________________________________
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] 41+ messages in thread

* [PATCH v2 2/2] pci: host: Add Broadcom STB PCIE RC controller
@ 2016-05-11 14:47     ` Bharat Kumar Gogada
  0 siblings, 0 replies; 41+ messages in thread
From: Bharat Kumar Gogada @ 2016-05-11 14:47 UTC (permalink / raw)
  To: linux-arm-kernel

> +
> +static struct pci_ops brcm_pcie_ops = {
> +	.read = brcm_pcie_read_config,
> +	.write = brcm_pcie_write_config,
> +};
> +
> +static int brcm_pcie_probe(struct platform_device *pdev) {
> +	struct device_node *dn = pdev->dev.of_node;
> +	const u32 *log2_scb_sizes, *dma_ranges;
> +	const struct brcm_pcie_cfg_data *data;
> +	const struct of_device_id *of_id;
> +	struct brcm_pcie *pcie;
> +	void __iomem *base;
> +	struct resource *r;
> +	int i, rlen, ret;
> +	u32 tmp;
> +
> +	pcie = devm_kzalloc(&pdev->dev, sizeof(struct brcm_pcie),
> GFP_KERNEL);
> +	if (!pcie)
> +		return -ENOMEM;
> +
> +	of_id = of_match_node(brcm_pcie_match, dn);
> +	if (!of_id)
> +		return -EINVAL;
> +
> +	data = of_id->data;
> +	pcie->type = data->type;
> +	pcie->ops = &data->ops;
> +
> +	platform_set_drvdata(pdev, pcie);
> +
> +	INIT_LIST_HEAD(&pcie->resource);
> +
> +	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	base = devm_ioremap_resource(&pdev->dev, r);
> +	if (IS_ERR(base))
> +		return PTR_ERR(base);
> +
> +	ret = of_alias_get_id(dn, "pcie");
> +	if (ret >= 0)
> +		pcie->num = ret;
> +
> +	pcie->clk = devm_clk_get(&pdev->dev, "pcie");
> +	if (IS_ERR(pcie->clk)) {
> +		dev_err(&pdev->dev, "could not get clock\n");
> +		pcie->clk = NULL;
> +	}
> +
> +	ret = clk_prepare_enable(pcie->clk);
> +	if (ret) {
> +		dev_err(&pdev->dev, "could not enable clock\n");
> +		return ret;
> +	}
> +
> +	pcie->dn = dn;
> +	pcie->base = base;
> +	pcie->dev = &pdev->dev;
> +	pcie->dev->of_node = dn;
> +	pcie->gen = 0;
> +
> +	ret = of_property_read_u32(dn, "brcm,gen", &tmp);
> +	if (ret == 0) {
> +		if (tmp > 0 && tmp < 3)
> +			pcie->gen = (int)tmp;
> +		else
> +			dev_warn(pcie->dev, "bad DT value for prop
> 'brcm,gen");
> +	} else if (ret != -EINVAL) {
> +		dev_warn(pcie->dev, "error reading DT prop 'brcm,gen");
> +	}
> +
> +	pcie->ssc = of_property_read_bool(dn, "brcm,ssc");
> +
> +	/* Get the value for the log2 of the scb sizes. Subtract 15 from
> +	 * each because the target register field has 0==disabled and 1==6KB.
> +	 */
> +	log2_scb_sizes = of_get_property(dn, "brcm,log2-scb-sizes", &rlen);
> +	if (log2_scb_sizes) {
> +		for (i = 0; i < rlen / sizeof(u32); i++) {
> +			pcie->scb_size_vals[i]
> +				= (int)of_read_number(log2_scb_sizes + i, 1)
> +					- 15;
> +			pcie->num_memc++;
> +		}
> +	}
In your device tree documentation this is required property, what if this property 
is missing ?
> +
> +	/* Look for the dma-ranges property.  If it exists, issue a warning
> +	 * as PCIe drivers may not work.  This is because the identity
> +	 * mapping between system memory and PCIe space is not
> preserved,
> +	 * and we need Linux to massage the dma_addr_t values it gets
> +	 * from dma memory allocation.  This functionality will be added
> +	 * in the near future.
> +	 */
> +	dma_ranges = of_get_property(dn, "dma-ranges", &rlen);
> +	if (dma_ranges != NULL)
> +		dev_warn(pcie->dev, "no identity map; PCI drivers may fail");
> +
> +	if (IS_ENABLED(CONFIG_PCI_MSI)) {
> +		ret = irq_of_parse_and_map(pdev->dev.of_node, 1);
> +		if (ret == 0)
> +			dev_warn(pcie->dev, "cannot get msi intr; MSI
> disabled\n");
> +		else
> +			pcie->msi_irq = ret;
> +	}
> +
> +	ret = of_pci_get_host_bridge_resources(dn, 0, 0xff,
> +					       &pcie->resource, NULL);
> +	if (ret) {
> +		dev_err(pcie->dev, "ranges parsing failed\n");
> +		return ret;
> +	}
> +
> +	ret = brcm_pcie_setup_early(pcie);
> +	if (ret)
> +		goto out_err_clk;
> +
> +	/* If setup bridge fails, it cleans up behind itself */
> +	ret = brcm_setup_pcie_bridge(pcie);
> +	if (ret)
> +		goto out_err;
> +
> +	pcie->bus = pci_scan_root_bus(pcie->dev, pcie->num,
> &brcm_pcie_ops,
> +				      pcie, &pcie->resource);
> +	if (!pcie->bus) {
> +		ret = -ENOMEM;
> +		goto out_err_bus;
> +	}
> +
> +	if (IS_ENABLED(CONFIG_PCI_MSI))
> +		brcm_pcie_msi_chip_set(pcie);
> +
> +	pci_bus_size_bridges(pcie->bus);
> +	pci_bus_assign_resources(pcie->bus);
> +
> +	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
> +	pci_bus_add_devices(pcie->bus);
> +
> +	return 0;
> +
> +out_err_bus:
> +	brcm_pcie_enter_l23(pcie);
> +	brcm_pcie_turn_off(pcie);
> +out_err_clk:
> +	clk_disable_unprepare(pcie->clk);
> +out_err:
> +	return ret;
> +}
> +
> +static int brcm_pcie_remove(struct platform_device *pdev) {
> +	return brcm_pcie_suspend(&pdev->dev);
> +}
> +
> +static struct platform_driver brcm_pcie_driver = {
> +	.probe = brcm_pcie_probe,
> +	.remove = brcm_pcie_remove,
> +	.driver = {
> +		.name = "brcm-pcie",
> +		.owner = THIS_MODULE,
> +		.of_match_table = brcm_pcie_match,
> +		.pm = &brcm_pcie_pm_ops,
> +	},
> +};
> +module_platform_driver(brcm_pcie_driver);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_DESCRIPTION("Broadcom STB PCIE RC driver");
> +MODULE_AUTHOR("Broadcom");
> diff --git a/drivers/pci/host/pcie-brcmstb.h b/drivers/pci/host/pcie-
> brcmstb.h new file mode 100644 index 000000000000..b4a507423bb0
> --- /dev/null
> +++ b/drivers/pci/host/pcie-brcmstb.h
> @@ -0,0 +1,160 @@
> +#ifndef __PCIE_BRCMSTB_H
> +#define __PCIE_BRCMSTB_H
> +
> +#include <linux/io.h>
> +
> +/* Broadcom PCIE Offsets */
> +#define PCIE_RC_CFG_PCIE_LINK_CAPABILITY		0x00b8
> +#define PCIE_RC_CFG_PCIE_LINK_STATUS_CONTROL
> 	0x00bc
> +#define PCIE_RC_CFG_PCIE_ROOT_CAP_CONTROL		0x00c8
> +#define PCIE_RC_CFG_PCIE_LINK_STATUS_CONTROL_2
> 	0x00dc
> +#define PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1
> 	0x0188
> +#define PCIE_RC_CFG_PRIV1_ID_VAL3			0x043c
> +#define PCIE_RC_DL_MDIO_ADDR				0x1100
> +#define PCIE_RC_DL_MDIO_WR_DATA
> 	0x1104
> +#define PCIE_RC_DL_MDIO_RD_DATA
> 	0x1108
> +#define PCIE_MISC_MISC_CTRL				0x4008
> +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO		0x400c
> +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI		0x4010
> +#define PCIE_MISC_RC_BAR1_CONFIG_LO			0x402c
> +#define PCIE_MISC_RC_BAR1_CONFIG_HI			0x4030
> +#define PCIE_MISC_RC_BAR2_CONFIG_LO			0x4034
> +#define PCIE_MISC_RC_BAR2_CONFIG_HI			0x4038
> +#define PCIE_MISC_RC_BAR3_CONFIG_LO			0x403c
> +#define PCIE_MISC_RC_BAR3_CONFIG_HI			0x4040
> +#define PCIE_MISC_MSI_BAR_CONFIG_LO			0x4044
> +#define PCIE_MISC_MSI_BAR_CONFIG_HI			0x4048
> +#define PCIE_MISC_MSI_DATA_CONFIG			0x404c
> +#define PCIE_MISC_PCIE_CTRL				0x4064
> +#define PCIE_MISC_PCIE_STATUS				0x4068
> +#define PCIE_MISC_REVISION				0x406c
> +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT	0x4070
> +#define PCIE_MISC_HARD_PCIE_HARD_DEBUG
> 	0x4204
> +#define PCIE_INTR2_CPU_BASE				0x4300
> +#define PCIE_MSI_INTR2_BASE				0x4500
> +
> +#define PCIE_RGR1_SW_INIT_1				0x9210
> +#define PCIE_EXT_CFG_INDEX				0x9000
> +#define PCIE_EXT_CFG_DATA				0x9004
> +
> +/* BCM7425 specific register offsets */
> +#define BCM7425_PCIE_RGR1_SW_INIT_1			0x8010
> +#define BCM7425_PCIE_EXT_CFG_INDEX			0x8300
> +#define BCM7425_PCIE_EXT_CFG_DATA			0x8304
> +
> +#define PCI_BUSNUM_SHIFT		20
> +#define PCI_SLOT_SHIFT			15
> +#define PCI_FUNC_SHIFT			12
> +
> +#define BRCM_NUM_PCI_OUT_WINS		4
> +#define BRCM_MAX_SCB			4
> +
> +/* Offsets from PCIE_INTR2_CPU_BASE and PCIE_MSI_INTR2_BASE */
> +#define STATUS				0x0
> +#define SET				0x4
> +#define CLR				0x8
> +#define MASK_STATUS			0xc
> +#define MASK_SET			0x10
> +#define MASK_CLR			0x14
> +
> +enum brcm_pcie_type {
> +	BCM7425,
> +	BCM7435,
> +	GENERIC,
> +};
> +
> +struct brcm_pcie;
> +
> +/* Chip-specific PCIe operations (read/write config and reset) */
> +struct brcm_pcie_ll_ops {
> +	u32 (*read_config)(struct brcm_pcie *pcie, int cfg_idx);
> +	void (*write_config)(struct brcm_pcie *pcie, int cfg_idx, u32 val);
> +	void (*rgr1_sw_init)(struct brcm_pcie *pcie, u32 mask,
> +			     int shift, u32 val);
> +};
> +
> +struct brcm_pcie_cfg_data {
> +	const enum brcm_pcie_type type;
> +	const struct brcm_pcie_ll_ops ops;
> +};
> +
> +struct brcm_msi;
> +
> +/* Internal Bus Controller Information.*/ struct brcm_pcie {
> +	void __iomem		*base;
> +	bool			suspended;
> +	struct clk		*clk;
> +	struct device_node	*dn;
> +	bool			ssc;
> +	int			gen;
> +	int			scb_size_vals[BRCM_MAX_SCB];
> +	struct pci_bus		*bus;
> +	struct device		*dev;
> +	struct list_head	resource;
> +	int			msi_irq;
> +	struct brcm_msi		*msi;
> +	unsigned int		rev;
> +	unsigned int		num;
> +	bool			bridge_setup_done;
> +	enum brcm_pcie_type	type;
> +	const struct brcm_pcie_ll_ops *ops;
> +	unsigned int		num_memc;
> +};
> +
> +/* Helper functions to access read/write config space and software init
> +which
> + * are chip-specific
> + */
> +static inline u32 brcm_pcie_ll_read_config(struct brcm_pcie *pcie, int
> +cfg_idx) {
> +	return pcie->ops->read_config(pcie, cfg_idx); }
> +
> +static inline void brcm_pcie_ll_write_config(struct brcm_pcie *pcie,
> +					     int cfg_idx, u32 val)
> +{
> +	pcie->ops->write_config(pcie, cfg_idx, val); }
> +
> +static inline void brcm_pcie_rgr1_sw_init(struct brcm_pcie *pcie, u32 mask,
> +					  int shift, u32 val)
> +{
> +	pcie->ops->rgr1_sw_init(pcie, mask, shift, val); }
> +
> +/*
> + * MIPS endianness is configured by boot strap, which also reverses all
> + * bus endianness (i.e., big-endian CPU + big endian bus ==> native
> + * endian I/O).
> + *
> + * Other architectures (e.g., ARM) either do not support big endian, or
> + * else leave I/O in little endian mode.
> + */
> +static inline u32 bpcie_readl(void __iomem *base) {
> +	if (IS_ENABLED(CONFIG_MIPS))
> +		return __raw_readl(base);
> +	else
> +		return readl(base);
> +}
> +
> +static inline void bpcie_writel(u32 val, void __iomem *base) {
> +	if (IS_ENABLED(CONFIG_MIPS))
> +		__raw_writel(val, base);
> +	else
> +		writel(val, base);
> +}
> +
> +#ifdef CONFIG_PCIE_BRCMSTB_MSI
> +int brcm_pcie_enable_msi(struct brcm_pcie *pcie, int nr); void
> +brcm_pcie_msi_chip_set(struct brcm_pcie *pcie); #else static inline int
> +brcm_pcie_enable_msi(struct brcm_pcie *pcie, int nr) {
> +	return 0;
> +}
> +static inline void brcm_pcie_msi_chip_set(struct brcm_pcie *pcie) { }
> +#endif
> +
> +#endif /* __PCIE_BRCMSTB_H */
> --
> 2.1.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in the
> body of a message to majordomo at vger.kernel.org More majordomo info at
> http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH v2 2/2] pci: host: Add Broadcom STB PCIE RC controller
  2016-05-11 14:47     ` Bharat Kumar Gogada
  (?)
  (?)
@ 2016-05-17  1:50       ` Florian Fainelli
  -1 siblings, 0 replies; 41+ messages in thread
From: Florian Fainelli @ 2016-05-17  1:50 UTC (permalink / raw)
  To: Bharat Kumar Gogada, linux-pci
  Cc: linux-kernel, devicetree, linux-arm-kernel,
	bcm-kernel-feedback-list, jim2101024, bhelgaas, arnd

On 05/11/2016 07:47 AM, Bharat Kumar Gogada wrote:

[snip]

>> +	/* Get the value for the log2 of the scb sizes. Subtract 15 from
>> +	 * each because the target register field has 0==disabled and 1==6KB.
>> +	 */
>> +	log2_scb_sizes = of_get_property(dn, "brcm,log2-scb-sizes", &rlen);
>> +	if (log2_scb_sizes) {
>> +		for (i = 0; i < rlen / sizeof(u32); i++) {
>> +			pcie->scb_size_vals[i]
>> +				= (int)of_read_number(log2_scb_sizes + i, 1)
>> +					- 15;
>> +			pcie->num_memc++;
>> +		}
>> +	}
> In your device tree documentation this is required property, what if this property 
> is missing ?

If you look at the driver, you will see that it assumes a 1GB SCB window
size if this property is absent.

PS: Do you mind trimming your replies in the future just to quote the
relevant part? Pretty much like I just did, this greatly improves the
ability to jump right to where the comments are. Thanks
-- 
Florian

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

* Re: [PATCH v2 2/2] pci: host: Add Broadcom STB PCIE RC controller
@ 2016-05-17  1:50       ` Florian Fainelli
  0 siblings, 0 replies; 41+ messages in thread
From: Florian Fainelli @ 2016-05-17  1:50 UTC (permalink / raw)
  To: Bharat Kumar Gogada, linux-pci
  Cc: linux-kernel, devicetree, linux-arm-kernel,
	bcm-kernel-feedback-list, jim2101024, bhelgaas, arnd

On 05/11/2016 07:47 AM, Bharat Kumar Gogada wrote:

[snip]

>> +	/* Get the value for the log2 of the scb sizes. Subtract 15 from
>> +	 * each because the target register field has 0==disabled and 1==6KB.
>> +	 */
>> +	log2_scb_sizes = of_get_property(dn, "brcm,log2-scb-sizes", &rlen);
>> +	if (log2_scb_sizes) {
>> +		for (i = 0; i < rlen / sizeof(u32); i++) {
>> +			pcie->scb_size_vals[i]
>> +				= (int)of_read_number(log2_scb_sizes + i, 1)
>> +					- 15;
>> +			pcie->num_memc++;
>> +		}
>> +	}
> In your device tree documentation this is required property, what if this property 
> is missing ?

If you look at the driver, you will see that it assumes a 1GB SCB window
size if this property is absent.

PS: Do you mind trimming your replies in the future just to quote the
relevant part? Pretty much like I just did, this greatly improves the
ability to jump right to where the comments are. Thanks
-- 
Florian

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

* Re: [PATCH v2 2/2] pci: host: Add Broadcom STB PCIE RC controller
@ 2016-05-17  1:50       ` Florian Fainelli
  0 siblings, 0 replies; 41+ messages in thread
From: Florian Fainelli @ 2016-05-17  1:50 UTC (permalink / raw)
  To: Bharat Kumar Gogada, linux-pci
  Cc: devicetree, arnd, linux-kernel, jim2101024,
	bcm-kernel-feedback-list, bhelgaas, linux-arm-kernel

On 05/11/2016 07:47 AM, Bharat Kumar Gogada wrote:

[snip]

>> +	/* Get the value for the log2 of the scb sizes. Subtract 15 from
>> +	 * each because the target register field has 0==disabled and 1==6KB.
>> +	 */
>> +	log2_scb_sizes = of_get_property(dn, "brcm,log2-scb-sizes", &rlen);
>> +	if (log2_scb_sizes) {
>> +		for (i = 0; i < rlen / sizeof(u32); i++) {
>> +			pcie->scb_size_vals[i]
>> +				= (int)of_read_number(log2_scb_sizes + i, 1)
>> +					- 15;
>> +			pcie->num_memc++;
>> +		}
>> +	}
> In your device tree documentation this is required property, what if this property 
> is missing ?

If you look at the driver, you will see that it assumes a 1GB SCB window
size if this property is absent.

PS: Do you mind trimming your replies in the future just to quote the
relevant part? Pretty much like I just did, this greatly improves the
ability to jump right to where the comments are. Thanks
-- 
Florian

_______________________________________________
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] 41+ messages in thread

* [PATCH v2 2/2] pci: host: Add Broadcom STB PCIE RC controller
@ 2016-05-17  1:50       ` Florian Fainelli
  0 siblings, 0 replies; 41+ messages in thread
From: Florian Fainelli @ 2016-05-17  1:50 UTC (permalink / raw)
  To: linux-arm-kernel

On 05/11/2016 07:47 AM, Bharat Kumar Gogada wrote:

[snip]

>> +	/* Get the value for the log2 of the scb sizes. Subtract 15 from
>> +	 * each because the target register field has 0==disabled and 1==6KB.
>> +	 */
>> +	log2_scb_sizes = of_get_property(dn, "brcm,log2-scb-sizes", &rlen);
>> +	if (log2_scb_sizes) {
>> +		for (i = 0; i < rlen / sizeof(u32); i++) {
>> +			pcie->scb_size_vals[i]
>> +				= (int)of_read_number(log2_scb_sizes + i, 1)
>> +					- 15;
>> +			pcie->num_memc++;
>> +		}
>> +	}
> In your device tree documentation this is required property, what if this property 
> is missing ?

If you look at the driver, you will see that it assumes a 1GB SCB window
size if this property is absent.

PS: Do you mind trimming your replies in the future just to quote the
relevant part? Pretty much like I just did, this greatly improves the
ability to jump right to where the comments are. Thanks
-- 
Florian

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

* Re: [PATCH v2 1/2] Documentation: DT: bindings: Add Broadcom STB PCIe bindings
  2016-05-11 14:45     ` Bharat Kumar Gogada
  (?)
@ 2016-05-17  1:52       ` Florian Fainelli
  -1 siblings, 0 replies; 41+ messages in thread
From: Florian Fainelli @ 2016-05-17  1:52 UTC (permalink / raw)
  To: Bharat Kumar Gogada, linux-pci
  Cc: linux-kernel, devicetree, linux-arm-kernel,
	bcm-kernel-feedback-list, jim2101024, bhelgaas, arnd

On 05/11/2016 07:45 AM, Bharat Kumar Gogada wrote:
>> +- brcm,log2-scb-sizes: log2 size of the SCB window that is mapped to
>> +PCIe space
>> +  there must be exactly one value per memory controller present in the
>> +system
>> +  (ranges from 1 to 3)
> 
> Can you please give more insight on what does this property do ?

There is another part of the thread that should tell you a bit more what
this is about, here is where it starts:

http://www.spinics.net/lists/linux-pci/msg50973.html

And this is where we discuss what we should be doing about it:

http://www.spinics.net/lists/linux-pci/msg51070.html
-- 
Florian

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

* Re: [PATCH v2 1/2] Documentation: DT: bindings: Add Broadcom STB PCIe bindings
@ 2016-05-17  1:52       ` Florian Fainelli
  0 siblings, 0 replies; 41+ messages in thread
From: Florian Fainelli @ 2016-05-17  1:52 UTC (permalink / raw)
  To: Bharat Kumar Gogada, linux-pci
  Cc: linux-kernel, devicetree, linux-arm-kernel,
	bcm-kernel-feedback-list, jim2101024, bhelgaas, arnd

On 05/11/2016 07:45 AM, Bharat Kumar Gogada wrote:
>> +- brcm,log2-scb-sizes: log2 size of the SCB window that is mapped to
>> +PCIe space
>> +  there must be exactly one value per memory controller present in the
>> +system
>> +  (ranges from 1 to 3)
> 
> Can you please give more insight on what does this property do ?

There is another part of the thread that should tell you a bit more what
this is about, here is where it starts:

http://www.spinics.net/lists/linux-pci/msg50973.html

And this is where we discuss what we should be doing about it:

http://www.spinics.net/lists/linux-pci/msg51070.html
-- 
Florian

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

* [PATCH v2 1/2] Documentation: DT: bindings: Add Broadcom STB PCIe bindings
@ 2016-05-17  1:52       ` Florian Fainelli
  0 siblings, 0 replies; 41+ messages in thread
From: Florian Fainelli @ 2016-05-17  1:52 UTC (permalink / raw)
  To: linux-arm-kernel

On 05/11/2016 07:45 AM, Bharat Kumar Gogada wrote:
>> +- brcm,log2-scb-sizes: log2 size of the SCB window that is mapped to
>> +PCIe space
>> +  there must be exactly one value per memory controller present in the
>> +system
>> +  (ranges from 1 to 3)
> 
> Can you please give more insight on what does this property do ?

There is another part of the thread that should tell you a bit more what
this is about, here is where it starts:

http://www.spinics.net/lists/linux-pci/msg50973.html

And this is where we discuss what we should be doing about it:

http://www.spinics.net/lists/linux-pci/msg51070.html
-- 
Florian

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

* Re: [PATCH v2 0/2] pci: host: Broadcom STB PCIE RC controller support
  2016-05-05 19:14 ` Florian Fainelli
@ 2016-06-09 22:31   ` Bjorn Helgaas
  -1 siblings, 0 replies; 41+ messages in thread
From: Bjorn Helgaas @ 2016-06-09 22:31 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: linux-pci, linux-kernel, devicetree, linux-arm-kernel,
	bcm-kernel-feedback-list, jim2101024, bhelgaas, arnd

On Thu, May 05, 2016 at 12:14:58PM -0700, Florian Fainelli wrote:
> Hi all,
> 
> This patch series adds support for Broadcom STB SoC's PCIe root complex driver.
> 
> This was primarily tested on BCM7445 (ARM) and BCM7435 (MIPS).
> 
> Jim is the original author, and I picked up our downstream 4.1 driver and
> updated it to utilize the non-ARM hw_pci functions as well as made some
> stylistic changes.
> 
> Thanks!
> 
> Jim Quinlan (2):
>   Documentation: DT: bindings: Add Broadcom STB PCIe bindings
>   pci: host: Add Broadcom STB PCIE RC controller

Hi Florian,

There was some discussion about these patches, so I assume you'll post
a new version addressing that.  When you do, can you include
/proc/iomem and /proc/ioports contents?

I'm looking to avoid problems like this:
http://lkml.kernel.org/r/20160606230537.20936.2892.stgit@bhelgaas-glaptop2.roam.corp.google.com

Also, it will save me time if you take note of this:
http://lkml.kernel.org/r/20160607231326.GA4759@localhost

Bjorn

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

* [PATCH v2 0/2] pci: host: Broadcom STB PCIE RC controller support
@ 2016-06-09 22:31   ` Bjorn Helgaas
  0 siblings, 0 replies; 41+ messages in thread
From: Bjorn Helgaas @ 2016-06-09 22:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, May 05, 2016 at 12:14:58PM -0700, Florian Fainelli wrote:
> Hi all,
> 
> This patch series adds support for Broadcom STB SoC's PCIe root complex driver.
> 
> This was primarily tested on BCM7445 (ARM) and BCM7435 (MIPS).
> 
> Jim is the original author, and I picked up our downstream 4.1 driver and
> updated it to utilize the non-ARM hw_pci functions as well as made some
> stylistic changes.
> 
> Thanks!
> 
> Jim Quinlan (2):
>   Documentation: DT: bindings: Add Broadcom STB PCIe bindings
>   pci: host: Add Broadcom STB PCIE RC controller

Hi Florian,

There was some discussion about these patches, so I assume you'll post
a new version addressing that.  When you do, can you include
/proc/iomem and /proc/ioports contents?

I'm looking to avoid problems like this:
http://lkml.kernel.org/r/20160606230537.20936.2892.stgit at bhelgaas-glaptop2.roam.corp.google.com

Also, it will save me time if you take note of this:
http://lkml.kernel.org/r/20160607231326.GA4759 at localhost

Bjorn

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

end of thread, other threads:[~2016-06-09 22:31 UTC | newest]

Thread overview: 41+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-05 19:14 [PATCH v2 0/2] pci: host: Broadcom STB PCIE RC controller support Florian Fainelli
2016-05-05 19:14 ` Florian Fainelli
2016-05-05 19:14 ` [PATCH v2 1/2] Documentation: DT: bindings: Add Broadcom STB PCIe bindings Florian Fainelli
2016-05-05 19:14   ` Florian Fainelli
2016-05-05 19:14   ` Florian Fainelli
2016-05-05 21:15   ` Arnd Bergmann
2016-05-05 21:15     ` Arnd Bergmann
2016-05-05 21:46     ` Florian Fainelli
2016-05-05 21:46       ` Florian Fainelli
2016-05-09 13:12       ` Arnd Bergmann
2016-05-09 13:12         ` Arnd Bergmann
2016-05-10 17:00     ` Florian Fainelli
2016-05-10 17:00       ` Florian Fainelli
2016-05-10 19:51       ` Arnd Bergmann
2016-05-10 19:51         ` Arnd Bergmann
2016-05-09 19:26   ` Rob Herring
2016-05-09 19:26     ` Rob Herring
2016-05-09 23:15     ` Florian Fainelli
2016-05-09 23:15       ` Florian Fainelli
2016-05-09 23:15       ` Florian Fainelli
2016-05-09 23:15     ` Florian Fainelli
2016-05-09 23:15       ` Florian Fainelli
2016-05-11 14:45   ` Bharat Kumar Gogada
2016-05-11 14:45     ` Bharat Kumar Gogada
2016-05-11 14:45     ` Bharat Kumar Gogada
2016-05-11 14:45     ` Bharat Kumar Gogada
2016-05-17  1:52     ` Florian Fainelli
2016-05-17  1:52       ` Florian Fainelli
2016-05-17  1:52       ` Florian Fainelli
2016-05-05 19:15 ` [PATCH v2 2/2] pci: host: Add Broadcom STB PCIE RC controller Florian Fainelli
2016-05-05 19:15   ` Florian Fainelli
2016-05-11 14:47   ` Bharat Kumar Gogada
2016-05-11 14:47     ` Bharat Kumar Gogada
2016-05-11 14:47     ` Bharat Kumar Gogada
2016-05-11 14:47     ` Bharat Kumar Gogada
2016-05-17  1:50     ` Florian Fainelli
2016-05-17  1:50       ` Florian Fainelli
2016-05-17  1:50       ` Florian Fainelli
2016-05-17  1:50       ` Florian Fainelli
2016-06-09 22:31 ` [PATCH v2 0/2] pci: host: Broadcom STB PCIE RC controller support Bjorn Helgaas
2016-06-09 22:31   ` Bjorn Helgaas

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.