devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCHv7 00/17] PCIe support for the Armada 370 and Armada XP SoCs
@ 2013-03-27 14:40 Thomas Petazzoni
  2013-03-27 14:40 ` [PATCHv7 01/17] of/pci: Provide support for parsing PCI DT ranges property Thomas Petazzoni
                   ` (19 more replies)
  0 siblings, 20 replies; 37+ messages in thread
From: Thomas Petazzoni @ 2013-03-27 14:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Grant Likely, Russell King
  Cc: linux-pci, linux-arm-kernel, devicetree-discuss, Lior Amsalem,
	Andrew Lunn, Jason Cooper, Arnd Bergmann, Maen Suleiman,
	Thierry Reding, Gregory Clement, Ezequiel Garcia, Olof Johansson,
	Tawfik Bayouk, Jason Gunthorpe, Mitch Bradley, Andrew Murray

Hello,

This series of patches introduces PCIe support for the Marvell Armada
370 and Armada XP. In the future, we plan to extend the driver to
cover Kirkwood platforms, and possibly other Marvell EBU platforms as
well.

As we are approaching 3.10, I would now like to get formal Acked-by,
or disagreements from the following maintainers/developers :

 * Grant Likely, as the OF maintainer, for patches 1, 2 and 3

   [PATCH v5 01/17] of/pci: Provide support for parsing PCI DT ranges
   [PATCH v5 02/17] of/pci: Add of_pci_get_devfn() function
   [PATCH v5 03/17] of/pci: Add of_pci_parse_bus_range() function

 * Bjorn Helgaas, as the PCI maintainer, for patches 4 and 8

   [PATCH v5 04/17] pci: infrastructure to add drivers in drivers/pci/host
   [PATCH v5 08/17] pci: PCIe driver for Marvell Armada 370/XP systems

 * Russell King, as the ARM maintainer, for patch 5

   [PATCH v5 05/17] arm: pci: add a align_resource hook

 * Arnd Bergmann, Mitch Bradley and Jason Gunthorpe, for patch 8 (the
   PCIe driver itself), and specifically the Device Tree binding.

   [PATCH v5 08/17] pci: PCIe driver for Marvell Armada 370/XP systems

This patch set depends on:

 * The arm-soc/mvebu/cleanup branch in Arnd and Olof arm-soc tree

 * [PATCH v3 for 3.10] Introduce a Marvell EBU MBus driver
   http://lists.infradead.org/pipermail/linux-arm-kernel/2013-March/156883.html

For easier testing, the code has been pushed to:

  git://github.com/MISL-EBU-System-SW/mainline-public.git marvell-pcie-v7

This PATCHv7 follows:
 * PATCHv6, sent on March, 26st 2013
 * PATCHv5, sent on March, 21st 2013
 * PATCHv4, sent on March, 8th 2013
 * PATCHv3, sent on February, 12th 2013
 * PATCHv2, sent on January, 28th 2013
 * RFCv1, sent on December, 7th 2012

Changes between v6 and v7:

 * Use assigned-addresses in the DT subnodes for the MMIO PCIe
   registers, in order to align with what Thierry is doing on the
   Tegra PCIe driver.

 * Added empty 'ranges;' properties in the subnodes, as requested by
   Arnd. Note that due to this, it is not possible to remove the
   #address-cells and #size-cells properties from the subnodes, as
   Jason Gunthorpe requested, otherwise the DT compiler complains with:

     Warning (ranges_format): /soc/pcie-controller/pcie@1,0 has empty
     "ranges" property but its #address-cells (2) differs from
     /soc/pcie-controller (3)

     Warning (ranges_format): /soc/pcie-controller/pcie@1,0 has empty
     "ranges" property but its #size-cells (1) differs from
     /soc/pcie-controller (2)

 * Use the new RFCv3 patch from Andrew Murray for 'of/pci: Provide
   support for parsing PCI DT ranges property'.

 * Updated the DT binding documentation accordingly.

Changes between v5 and v6:

 * Use pci_create_root_bus() + pci_scan_child_bus() instead of
   pci_scan_root_bus(). This is needed to be able to add MSI support
   later on. Moreover Thierry Reding suggested that
   pci_scan_root_bus() "does a pci_bus_add_devices(), which is called
   again in pci_common_init() in the ARM code". Thanks Thierry for
   pointing out this issue.

Changes between v4 and v5:

 * Rebased on top of 3.9-rc2 + the new mvebu-mbus driver (v3).

 * Changed the names of the PCI DT sub-nodes to match the OF
   specifications: they should be named pcie@DD,FF where DD is the
   device number and FF the function number. Requested by Mitch
   Bradley.

 * Add the device_type = "pci" property at the pcie-controller
   level. Requested by Mitch Bradley.

 * Drop patch 'of/pci: Add of_pci_get_bus() function' because it
   wasn't actually used in the rest of the patch series.

 * Updated the patch 'of/pci: Provide support for parsing PCI DT
   ranges property' to use the latest version proposed by Andrew
   Murray on the devicetree-discuss@ mailing list.

Changes between v3 and v4:

 * Rebased on top of 3.9-rc1.

 * Drop patch "ARM: pci: Allow passing per-controller private data"
   because it was merged in 3.9.

 * Drop patch "lib: devres: don't enclose pcim_*() functions in
   CONFIG_HAS_IOPORT", because it was merged in 3.9.

 * Added CONFIG_PCI_MVEBU=y in mvebu_defconfig, so that the right PCI
   host controller driver is automatically enabled.

 * Instead of using the DT 'ranges' property to encode the PCIe
   register ranges, use a 'reg' property on the main PCIe controller
   DT node together with a 'reg-names' property. Suggested by Jason
   Gunthorpe.

 * Don't select PCI_SW_HOST_BRIDGE and PCI_SW_PCI_PCI_BRIDGE, they
   don't exist anymore. Reported by Bjorn Helgaas.

 * Added support for the Armada XP GP board.

 * Fix the 'ranges' property so that the memory range is an identity
   map between CPU addresses and bus addresses. Suggested by Arnd
   Bergmann.

 * Changed the 'ranges' property to have the I/O region after the
   memory region.

 * Use the new mvebu-mbus driver API to create/remove address decoding
   windows when needed. This remove the need to include
   <mach/addr-map.h>. Requested by Arnd Bergmann.

 * Include directly into the driver the few common PCIe functions we
   were using from arch/arm/plat-orion/pcie.c. This allows to remove
   the inclusion of <plat/pcie.h>. Requested by Arnd Bergmann.

 * Directly set up the address decoding windows when the memory
   base/limit and I/O base/limit are configured in the PCI-to-PCI
   bridge instead of relying on the memory and I/O accesses being
   enabled in the PCI_COMMAND register. Suggested by Bjorn Helgaas.

 * Added some comments on top of the calculations of the I/O
   base/limit and memory base/limit. Suggested by Arnd Bergmann.

 * Changed a bit the way the "realio" resource is created, from
   suggestions given by Arnd Bergmann.

 * Updated the Device Tree binding documentation. Reported by Jason
   Gunthorpe.

 * Instead of using "marvell,armada-370-xp-pcie" as the DT compatible
   string, use two separate compatible strings:
   "marvell,armada-370-pcie" and "marvell,armada-xp-pcie". For now,
   the driver does the same thing for both.

Changes between v2 and v3:

 * Use of_irq_map_pci() instead of of_irq_map_raw(), as suggested by
   Andrew Murray. In order to do this, we moved the interrupt-map and
   interrupt-map-mask DT properties from the main PCIe controller node
   to the DT subnodes representing each PCIe interface.

 * Remove the usage of the emulated host bridge.

 * Move the emulated PCI-to-PCI bridge code into the Marvell PCI
   driver itself, in order to allow a tighter integration. Suggested
   by Bjorn Helgaas and Jason Gunthorpe.

 * Make the allocation of address decoding windows dynamic: it's when
   memory accesses or I/O accesses are enabled at the PCI-to-PCI
   bridge level that we allocate and setup the corresponding address
   decoding window. Requested by Bjorn Helgaas.

 * Fixed the implementation of I/O accesses to use I/O addresses that
   fall within the normal IO_SPACE_LIMIT. This required using the
   "remap" functionality of address decoding windows, and therefore
   some changes in the address decoding window allocator. Follows a
   long discussion about I/O accesses.

 * Set up a correct bus number in the configuration of the PCIe
   interfaces so that we don't have to fake bus numbers
   anymore. Requested by Jason Gunthorpe.

 * Fix the of_pci_get_devfn() implementation according to Stephen
   Warren's comment.

 * Use CFLAGS_ instead of ccflags to add the mach-mvebu and plat-orion
   include paths when building the pci-mvebu driver. This ensures that
   the include paths are only added when building this specific
   driver. Requested by Stephen Warren.

 * Fix the ->resource_align() to only apply on bus 0 (the one on which
   the emulated PCI-to-PCI bridges sit), and to request an alignment
   on the size of the window (and not only 64 KB for I/O windows and 1
   MB for memory windows).

 * Clarified the commit log of "clk: mvebu: create parent-child
   relation for PCIe clocks on Armada 370"

Thanks,

Thomas

Andrew Murray (1):
  of/pci: Provide support for parsing PCI DT ranges property

Thierry Reding (2):
  of/pci: Add of_pci_get_devfn() function
  of/pci: Add of_pci_parse_bus_range() function

Thomas Petazzoni (14):
  pci: infrastructure to add drivers in drivers/pci/host
  arm: pci: add a align_resource hook
  clk: mvebu: create parent-child relation for PCIe clocks on Armada
    370
  clk: mvebu: add more PCIe clocks for Armada XP
  pci: PCIe driver for Marvell Armada 370/XP systems
  arm: mvebu: PCIe support is now available on mvebu
  arm: mvebu: add PCIe Device Tree informations for Armada 370
  arm: mvebu: add PCIe Device Tree informations for Armada XP
  arm: mvebu: PCIe Device Tree informations for OpenBlocks AX3-4
  arm: mvebu: PCIe Device Tree informations for Armada XP DB
  arm: mvebu: PCIe Device Tree informations for Armada 370 Mirabox
  arm: mvebu: PCIe Device Tree informations for Armada 370 DB
  arm: mvebu: PCIe Device Tree informations for Armada XP GP
  arm: mvebu: update defconfig with PCI and USB support

 .../devicetree/bindings/pci/mvebu-pci.txt          |  220 +++++
 arch/arm/boot/dts/armada-370-db.dts                |   17 +
 arch/arm/boot/dts/armada-370-mirabox.dts           |   16 +
 arch/arm/boot/dts/armada-370.dtsi                  |   51 ++
 arch/arm/boot/dts/armada-xp-db.dts                 |   33 +
 arch/arm/boot/dts/armada-xp-gp.dts                 |   21 +
 arch/arm/boot/dts/armada-xp-mv78230.dtsi           |  104 +++
 arch/arm/boot/dts/armada-xp-mv78260.dtsi           |  122 +++
 arch/arm/boot/dts/armada-xp-mv78460.dtsi           |  188 ++++
 arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts   |    9 +
 arch/arm/configs/mvebu_defconfig                   |    3 +
 arch/arm/include/asm/mach/pci.h                    |   11 +
 arch/arm/kernel/bios32.c                           |    6 +
 arch/arm/mach-mvebu/Kconfig                        |    2 +
 arch/microblaze/pci/pci-common.c                   |  110 +--
 arch/mips/pci/pci.c                                |   50 +-
 arch/powerpc/kernel/pci-common.c                   |   99 +--
 drivers/clk/mvebu/clk-gating-ctrl.c                |   18 +-
 drivers/of/address.c                               |   63 ++
 drivers/of/of_pci.c                                |   59 +-
 drivers/pci/Kconfig                                |    2 +
 drivers/pci/Makefile                               |    3 +
 drivers/pci/host/Kconfig                           |    8 +
 drivers/pci/host/Makefile                          |    4 +
 drivers/pci/host/pci-mvebu.c                       |  927 ++++++++++++++++++++
 include/linux/of_address.h                         |   42 +
 include/linux/of_pci.h                             |    2 +
 27 files changed, 2009 insertions(+), 181 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pci/mvebu-pci.txt
 create mode 100644 drivers/pci/host/Kconfig
 create mode 100644 drivers/pci/host/Makefile
 create mode 100644 drivers/pci/host/pci-mvebu.c

-- 
1.7.9.5

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

* [PATCHv7 01/17] of/pci: Provide support for parsing PCI DT ranges property
  2013-03-27 14:40 [PATCHv7 00/17] PCIe support for the Armada 370 and Armada XP SoCs Thomas Petazzoni
@ 2013-03-27 14:40 ` Thomas Petazzoni
  2013-03-27 14:40 ` [PATCHv7 02/17] of/pci: Add of_pci_get_devfn() function Thomas Petazzoni
                   ` (18 subsequent siblings)
  19 siblings, 0 replies; 37+ messages in thread
From: Thomas Petazzoni @ 2013-03-27 14:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Grant Likely, Russell King
  Cc: linux-pci, linux-arm-kernel, devicetree-discuss, Lior Amsalem,
	Andrew Lunn, Jason Cooper, Arnd Bergmann, Maen Suleiman,
	Thierry Reding, Gregory Clement, Ezequiel Garcia, Olof Johansson,
	Tawfik Bayouk, Jason Gunthorpe, Mitch Bradley, Andrew Murray,
	Andrew Murray, Liviu Dudau

From: Andrew Murray <Andrew.Murray@arm.com>

This patch factors out common implementation patterns to reduce overall kernel
code and provide a means for host bridge drivers to directly obtain struct
resources from the DT's ranges property without relying on architecture specific
DT handling. This will make it easier to write archiecture independent host bridge
drivers and mitigate against further duplication of DT parsing code.

This patch can be used in the following way:

	struct of_pci_range_parser parser;
	struct of_pci_range range;

	if (of_pci_range_parser(&parser, np))
		; //no ranges property

	for_each_of_pci_range(&parser, &range) {

		/*
			directly access properties of the address range, e.g.:
			range.pci_space, range.pci_addr, range.cpu_addr,
			range.size, range.flags

			alternatively obtain a struct resource, e.g.:
			struct resource res;
			of_pci_range_to_resource(&range, np, &res);
		*/
	}

Additionally the implementation takes care of adjacent ranges and merges them
into a single range (as was the case with powerpc and microblaze).

The modifications to microblaze, mips and powerpc have not been tested.

Signed-off-by: Andrew Murray <Andrew.Murray@arm.com>
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Tested-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
 arch/microblaze/pci/pci-common.c |  110 ++++++++++++++------------------------
 arch/mips/pci/pci.c              |   50 ++++++-----------
 arch/powerpc/kernel/pci-common.c |   99 ++++++++++++----------------------
 drivers/of/address.c             |   63 ++++++++++++++++++++++
 include/linux/of_address.h       |   42 +++++++++++++++
 5 files changed, 194 insertions(+), 170 deletions(-)

diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
index 9ea521e..17a7ad1 100644
--- a/arch/microblaze/pci/pci-common.c
+++ b/arch/microblaze/pci/pci-common.c
@@ -658,67 +658,43 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar,
 void pci_process_bridge_OF_ranges(struct pci_controller *hose,
 				  struct device_node *dev, int primary)
 {
-	const u32 *ranges;
-	int rlen;
-	int pna = of_n_addr_cells(dev);
-	int np = pna + 5;
 	int memno = 0, isa_hole = -1;
-	u32 pci_space;
-	unsigned long long pci_addr, cpu_addr, pci_next, cpu_next, size;
 	unsigned long long isa_mb = 0;
 	struct resource *res;
+	struct of_pci_range range;
+	struct of_pci_range_parser parser;
+	u32 res_type;
 
 	pr_info("PCI host bridge %s %s ranges:\n",
 	       dev->full_name, primary ? "(primary)" : "");
 
-	/* Get ranges property */
-	ranges = of_get_property(dev, "ranges", &rlen);
-	if (ranges == NULL)
+	/* Check for ranges property */
+	if (of_pci_range_parser(&parser, dev))
 		return;
 
-	/* Parse it */
 	pr_debug("Parsing ranges property...\n");
-	while ((rlen -= np * 4) >= 0) {
+	for_each_of_pci_range(&parser, &range) {
 		/* Read next ranges element */
-		pci_space = ranges[0];
-		pci_addr = of_read_number(ranges + 1, 2);
-		cpu_addr = of_translate_address(dev, ranges + 3);
-		size = of_read_number(ranges + pna + 3, 2);
-
-		pr_debug("pci_space: 0x%08x pci_addr:0x%016llx ",
-				pci_space, pci_addr);
-		pr_debug("cpu_addr:0x%016llx size:0x%016llx\n",
-					cpu_addr, size);
-
-		ranges += np;
+		pr_debug("pci_space: 0x%08x pci_addr: 0x%016llx ",
+				range.pci_space, range.pci_addr);
+		pr_debug("cpu_addr: 0x%016llx size: 0x%016llx\n",
+				range.cpu_addr, range.size);
 
 		/* If we failed translation or got a zero-sized region
 		 * (some FW try to feed us with non sensical zero sized regions
 		 * such as power3 which look like some kind of attempt
 		 * at exposing the VGA memory hole)
 		 */
-		if (cpu_addr == OF_BAD_ADDR || size == 0)
+		if (range.cpu_addr == OF_BAD_ADDR || range.size == 0)
 			continue;
 
-		/* Now consume following elements while they are contiguous */
-		for (; rlen >= np * sizeof(u32);
-		     ranges += np, rlen -= np * 4) {
-			if (ranges[0] != pci_space)
-				break;
-			pci_next = of_read_number(ranges + 1, 2);
-			cpu_next = of_translate_address(dev, ranges + 3);
-			if (pci_next != pci_addr + size ||
-			    cpu_next != cpu_addr + size)
-				break;
-			size += of_read_number(ranges + pna + 3, 2);
-		}
-
 		/* Act based on address space type */
 		res = NULL;
-		switch ((pci_space >> 24) & 0x3) {
-		case 1:		/* PCI IO space */
+		res_type = range.flags & IORESOURCE_TYPE_BITS;
+		if (res_type == IORESOURCE_IO) {
 			pr_info("  IO 0x%016llx..0x%016llx -> 0x%016llx\n",
-			       cpu_addr, cpu_addr + size - 1, pci_addr);
+				range.cpu_addr, range.cpu_addr + range.size - 1,
+				range.pci_addr);
 
 			/* We support only one IO range */
 			if (hose->pci_io_size) {
@@ -726,11 +702,12 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose,
 				continue;
 			}
 			/* On 32 bits, limit I/O space to 16MB */
-			if (size > 0x01000000)
-				size = 0x01000000;
+			if (range.size > 0x01000000)
+				range.size = 0x01000000;
 
 			/* 32 bits needs to map IOs here */
-			hose->io_base_virt = ioremap(cpu_addr, size);
+			hose->io_base_virt = ioremap(range.cpu_addr,
+						range.size);
 
 			/* Expect trouble if pci_addr is not 0 */
 			if (primary)
@@ -739,19 +716,18 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose,
 			/* pci_io_size and io_base_phys always represent IO
 			 * space starting at 0 so we factor in pci_addr
 			 */
-			hose->pci_io_size = pci_addr + size;
-			hose->io_base_phys = cpu_addr - pci_addr;
+			hose->pci_io_size = range.pci_addr + range.size;
+			hose->io_base_phys = range.cpu_addr - range.pci_addr;
 
 			/* Build resource */
 			res = &hose->io_resource;
-			res->flags = IORESOURCE_IO;
-			res->start = pci_addr;
-			break;
-		case 2:		/* PCI Memory space */
-		case 3:		/* PCI 64 bits Memory space */
+			range.cpu_addr = range.pci_addr;
+		} else if (res_type == IORESOURCE_MEM) {
 			pr_info(" MEM 0x%016llx..0x%016llx -> 0x%016llx %s\n",
-			       cpu_addr, cpu_addr + size - 1, pci_addr,
-			       (pci_space & 0x40000000) ? "Prefetch" : "");
+				range.cpu_addr, range.cpu_addr + range.size - 1,
+				range.pci_addr,
+				(range.pci_space & 0x40000000) ?
+				"Prefetch" : "");
 
 			/* We support only 3 memory ranges */
 			if (memno >= 3) {
@@ -759,13 +735,13 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose,
 				continue;
 			}
 			/* Handles ISA memory hole space here */
-			if (pci_addr == 0) {
+			if (range.pci_addr == 0) {
 				isa_mb = cpu_addr;
 				isa_hole = memno;
 				if (primary || isa_mem_base == 0)
-					isa_mem_base = cpu_addr;
-				hose->isa_mem_phys = cpu_addr;
-				hose->isa_mem_size = size;
+					isa_mem_base = range.cpu_addr;
+				hose->isa_mem_phys = range.cpu_addr;
+				hose->isa_mem_size = range.size;
 			}
 
 			/* We get the PCI/Mem offset from the first range or
@@ -773,30 +749,22 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose,
 			 * hole. If they don't match, bugger.
 			 */
 			if (memno == 0 ||
-			    (isa_hole >= 0 && pci_addr != 0 &&
+			    (isa_hole >= 0 && range.pci_addr != 0 &&
 			     hose->pci_mem_offset == isa_mb))
-				hose->pci_mem_offset = cpu_addr - pci_addr;
-			else if (pci_addr != 0 &&
-				 hose->pci_mem_offset != cpu_addr - pci_addr) {
+				hose->pci_mem_offset = range.cpu_addr
+							- range.pci_addr;
+			else if (range.pci_addr != 0 &&
+				 hose->pci_mem_offset != range.cpu_addr
+							- range.pci_addr) {
 				pr_info(" \\--> Skipped (offset mismatch) !\n");
 				continue;
 			}
 
 			/* Build resource */
 			res = &hose->mem_resources[memno++];
-			res->flags = IORESOURCE_MEM;
-			if (pci_space & 0x40000000)
-				res->flags |= IORESOURCE_PREFETCH;
-			res->start = cpu_addr;
-			break;
-		}
-		if (res != NULL) {
-			res->name = dev->full_name;
-			res->end = res->start + size - 1;
-			res->parent = NULL;
-			res->sibling = NULL;
-			res->child = NULL;
 		}
+		if (res != NULL)
+			of_pci_range_to_resource(&range, dev, res);
 	}
 
 	/* If there's an ISA hole and the pci_mem_offset is -not- matching
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c
index 0872f12..bee49a4 100644
--- a/arch/mips/pci/pci.c
+++ b/arch/mips/pci/pci.c
@@ -122,51 +122,33 @@ static void pcibios_scanbus(struct pci_controller *hose)
 #ifdef CONFIG_OF
 void pci_load_of_ranges(struct pci_controller *hose, struct device_node *node)
 {
-	const __be32 *ranges;
-	int rlen;
-	int pna = of_n_addr_cells(node);
-	int np = pna + 5;
+	struct of_pci_range_range range;
+	struct of_pci_range_parser parser;
+	u32 res_type;
 
 	pr_info("PCI host bridge %s ranges:\n", node->full_name);
-	ranges = of_get_property(node, "ranges", &rlen);
-	if (ranges == NULL)
-		return;
 	hose->of_node = node;
 
-	while ((rlen -= np * 4) >= 0) {
-		u32 pci_space;
+	if (of_pci_range_parser(&parser, node))
+		return;
+
+	for_each_of_pci_range(&parser, &range) {
 		struct resource *res = NULL;
-		u64 addr, size;
-
-		pci_space = be32_to_cpup(&ranges[0]);
-		addr = of_translate_address(node, ranges + 3);
-		size = of_read_number(ranges + pna + 3, 2);
-		ranges += np;
-		switch ((pci_space >> 24) & 0x3) {
-		case 1:		/* PCI IO space */
+
+		res_type = range.flags & IORESOURCE_TYPE_BITS;
+		if (res_type == IORESOURCE_IO) {
 			pr_info("  IO 0x%016llx..0x%016llx\n",
-					addr, addr + size - 1);
+				range.addr, range.addr + range.size - 1);
 			hose->io_map_base =
-				(unsigned long)ioremap(addr, size);
+				(unsigned long)ioremap(range.addr, range.size);
 			res = hose->io_resource;
-			res->flags = IORESOURCE_IO;
-			break;
-		case 2:		/* PCI Memory space */
-		case 3:		/* PCI 64 bits Memory space */
+		} else if (res_type == IORESOURCE_MEM) {
 			pr_info(" MEM 0x%016llx..0x%016llx\n",
-					addr, addr + size - 1);
+				range.addr, range.addr + range.size - 1);
 			res = hose->mem_resource;
-			res->flags = IORESOURCE_MEM;
-			break;
-		}
-		if (res != NULL) {
-			res->start = addr;
-			res->name = node->full_name;
-			res->end = res->start + size - 1;
-			res->parent = NULL;
-			res->sibling = NULL;
-			res->child = NULL;
 		}
+		if (res != NULL)
+			of_pci_range_to_resource(&range, node, res);
 	}
 }
 #endif
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index fa12ae4..878d530 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -676,61 +676,37 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar,
 void pci_process_bridge_OF_ranges(struct pci_controller *hose,
 				  struct device_node *dev, int primary)
 {
-	const u32 *ranges;
-	int rlen;
-	int pna = of_n_addr_cells(dev);
-	int np = pna + 5;
 	int memno = 0, isa_hole = -1;
-	u32 pci_space;
-	unsigned long long pci_addr, cpu_addr, pci_next, cpu_next, size;
 	unsigned long long isa_mb = 0;
 	struct resource *res;
+	struct of_pci_range range;
+	struct of_pci_range_parser parser;
+	u32 res_type;
 
 	printk(KERN_INFO "PCI host bridge %s %s ranges:\n",
 	       dev->full_name, primary ? "(primary)" : "");
 
-	/* Get ranges property */
-	ranges = of_get_property(dev, "ranges", &rlen);
-	if (ranges == NULL)
+	/* Check for ranges property */
+	if (of_pci_range_parser(&parser, dev))
 		return;
 
-	/* Parse it */
-	while ((rlen -= np * 4) >= 0) {
-		/* Read next ranges element */
-		pci_space = ranges[0];
-		pci_addr = of_read_number(ranges + 1, 2);
-		cpu_addr = of_translate_address(dev, ranges + 3);
-		size = of_read_number(ranges + pna + 3, 2);
-		ranges += np;
-
+	for_each_of_pci_range(&parser, &range) {
 		/* If we failed translation or got a zero-sized region
 		 * (some FW try to feed us with non sensical zero sized regions
 		 * such as power3 which look like some kind of attempt at exposing
 		 * the VGA memory hole)
 		 */
-		if (cpu_addr == OF_BAD_ADDR || size == 0)
+		if (range.cpu_addr == OF_BAD_ADDR || range.size == 0)
 			continue;
 
-		/* Now consume following elements while they are contiguous */
-		for (; rlen >= np * sizeof(u32);
-		     ranges += np, rlen -= np * 4) {
-			if (ranges[0] != pci_space)
-				break;
-			pci_next = of_read_number(ranges + 1, 2);
-			cpu_next = of_translate_address(dev, ranges + 3);
-			if (pci_next != pci_addr + size ||
-			    cpu_next != cpu_addr + size)
-				break;
-			size += of_read_number(ranges + pna + 3, 2);
-		}
-
 		/* Act based on address space type */
 		res = NULL;
-		switch ((pci_space >> 24) & 0x3) {
-		case 1:		/* PCI IO space */
+		res_type = range.flags & IORESOURCE_TYPE_BITS;
+		if (res_type == IORESOURCE_IO) {
 			printk(KERN_INFO
 			       "  IO 0x%016llx..0x%016llx -> 0x%016llx\n",
-			       cpu_addr, cpu_addr + size - 1, pci_addr);
+				range.cpu_addr, range.cpu_addr + range.size - 1,
+				range.pci_addr);
 
 			/* We support only one IO range */
 			if (hose->pci_io_size) {
@@ -740,11 +716,12 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose,
 			}
 #ifdef CONFIG_PPC32
 			/* On 32 bits, limit I/O space to 16MB */
-			if (size > 0x01000000)
-				size = 0x01000000;
+			if (range.size > 0x01000000)
+				range.size = 0x01000000;
 
 			/* 32 bits needs to map IOs here */
-			hose->io_base_virt = ioremap(cpu_addr, size);
+			hose->io_base_virt = ioremap(range.cpu_addr,
+						range.size);
 
 			/* Expect trouble if pci_addr is not 0 */
 			if (primary)
@@ -754,20 +731,19 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose,
 			/* pci_io_size and io_base_phys always represent IO
 			 * space starting at 0 so we factor in pci_addr
 			 */
-			hose->pci_io_size = pci_addr + size;
-			hose->io_base_phys = cpu_addr - pci_addr;
+			hose->pci_io_size = range.pci_addr + range.size;
+			hose->io_base_phys = range.cpu_addr - range.pci_addr;
 
 			/* Build resource */
 			res = &hose->io_resource;
-			res->flags = IORESOURCE_IO;
-			res->start = pci_addr;
-			break;
-		case 2:		/* PCI Memory space */
-		case 3:		/* PCI 64 bits Memory space */
+			range.cpu_addr = range.pci_addr;
+		} else if (res_type == IORESOURCE_MEM) {
 			printk(KERN_INFO
 			       " MEM 0x%016llx..0x%016llx -> 0x%016llx %s\n",
-			       cpu_addr, cpu_addr + size - 1, pci_addr,
-			       (pci_space & 0x40000000) ? "Prefetch" : "");
+				range.cpu_addr, range.cpu_addr + range.size - 1,
+				range.pci_addr,
+				(range.pci_space & 0x40000000) ?
+				"Prefetch" : "");
 
 			/* We support only 3 memory ranges */
 			if (memno >= 3) {
@@ -776,13 +752,13 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose,
 				continue;
 			}
 			/* Handles ISA memory hole space here */
-			if (pci_addr == 0) {
+			if (range.pci_addr == 0) {
 				isa_mb = cpu_addr;
 				isa_hole = memno;
 				if (primary || isa_mem_base == 0)
-					isa_mem_base = cpu_addr;
-				hose->isa_mem_phys = cpu_addr;
-				hose->isa_mem_size = size;
+					isa_mem_base = range.cpu_addr;
+				hose->isa_mem_phys = range.cpu_addr;
+				hose->isa_mem_size = range.size;
 			}
 
 			/* We get the PCI/Mem offset from the first range or
@@ -790,11 +766,13 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose,
 			 * hole. If they don't match, bugger.
 			 */
 			if (memno == 0 ||
-			    (isa_hole >= 0 && pci_addr != 0 &&
+			(isa_hole >= 0 && range.pci_addr != 0 &&
 			     hose->pci_mem_offset == isa_mb))
-				hose->pci_mem_offset = cpu_addr - pci_addr;
+				hose->pci_mem_offset = range.cpu_addr -
+							range.pci_addr;
 			else if (pci_addr != 0 &&
-				 hose->pci_mem_offset != cpu_addr - pci_addr) {
+				hose->pci_mem_offset != range.cpu_addr -
+							range.pci_addr) {
 				printk(KERN_INFO
 				       " \\--> Skipped (offset mismatch) !\n");
 				continue;
@@ -802,19 +780,10 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose,
 
 			/* Build resource */
 			res = &hose->mem_resources[memno++];
-			res->flags = IORESOURCE_MEM;
-			if (pci_space & 0x40000000)
-				res->flags |= IORESOURCE_PREFETCH;
-			res->start = cpu_addr;
 			break;
 		}
-		if (res != NULL) {
-			res->name = dev->full_name;
-			res->end = res->start + size - 1;
-			res->parent = NULL;
-			res->sibling = NULL;
-			res->child = NULL;
-		}
+		if (res != NULL)
+			of_pci_range_to_resource(&range, dev, res);
 	}
 
 	/* If there's an ISA hole and the pci_mem_offset is -not- matching
diff --git a/drivers/of/address.c b/drivers/of/address.c
index 04da786..e87f45e 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -227,6 +227,69 @@ int of_pci_address_to_resource(struct device_node *dev, int bar,
 	return __of_address_to_resource(dev, addrp, size, flags, NULL, r);
 }
 EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
+
+int of_pci_range_parser(struct of_pci_range_parser *parser,
+			struct device_node *node)
+{
+	const int na = 3, ns = 2;
+	int rlen;
+
+	parser->node = node;
+	parser->pna = of_n_addr_cells(node);
+	parser->np = parser->pna + na + ns;
+
+	parser->range = of_get_property(node, "ranges", &rlen);
+	if (parser->range == NULL)
+		return -ENOENT;
+
+	parser->end = parser->range + rlen / sizeof(__be32);
+
+	return 0;
+}
+
+struct of_pci_range *of_pci_process_ranges(struct of_pci_range_parser *parser,
+						struct of_pci_range *range)
+{
+	const int na = 3, ns = 2;
+
+	if (!parser->range || parser->range + parser->np > parser->end)
+		return NULL;
+
+	range->pci_space = be32_to_cpup(parser->range);
+	range->flags = of_bus_pci_get_flags(parser->range);
+	range->pci_addr = of_read_number(parser->range + 1, ns);
+	range->cpu_addr = of_translate_address(parser->node,
+				parser->range + na);
+	range->size = of_read_number(parser->range + parser->pna + na, ns);
+
+	parser->range += parser->np;
+
+	/* Now consume following elements while they are contiguous */
+	while (parser->range + parser->np <= parser->end) {
+		u32 flags, pci_space;
+		u64 pci_addr, cpu_addr, size;
+
+		pci_space = be32_to_cpup(parser->range);
+		flags = of_bus_pci_get_flags(parser->range);
+		pci_addr = of_read_number(parser->range + 1, ns);
+		cpu_addr = of_translate_address(parser->node,
+				parser->range + na);
+		size = of_read_number(parser->range + parser->pna + na, ns);
+
+		if (flags != range->flags)
+			break;
+		if (pci_addr != range->pci_addr + range->size ||
+		    cpu_addr != range->cpu_addr + range->size)
+			break;
+
+		range->size += size;
+		parser->range += parser->np;
+	}
+
+	return range;
+}
+EXPORT_SYMBOL_GPL(of_pci_process_ranges);
+
 #endif /* CONFIG_PCI */
 
 /*
diff --git a/include/linux/of_address.h b/include/linux/of_address.h
index 0506eb5..c7003a3 100644
--- a/include/linux/of_address.h
+++ b/include/linux/of_address.h
@@ -4,6 +4,32 @@
 #include <linux/errno.h>
 #include <linux/of.h>
 
+struct of_pci_range_parser {
+	struct device_node *node;
+	const __be32 *range, *end;
+	int np, pna;
+};
+
+struct of_pci_range {
+	u32 pci_space;
+	u64 pci_addr;
+	u64 cpu_addr;
+	u64 size;
+	u32 flags;
+};
+
+#define for_each_of_pci_range(parser, range) \
+	for (; of_pci_process_ranges(parser, range);)
+
+#define of_pci_range_to_resource(range, np, res) \
+	do { \
+		(res)->flags = (range)->flags; \
+		(res)->start = (range)->cpu_addr; \
+		(res)->end = (range)->cpu_addr + (range)->size - 1; \
+		(res)->parent = (res)->child = (res)->sibling = NULL; \
+		(res)->name = (np)->full_name; \
+	} while (0)
+
 #ifdef CONFIG_OF_ADDRESS
 extern u64 of_translate_address(struct device_node *np, const __be32 *addr);
 extern bool of_can_translate_address(struct device_node *dev);
@@ -27,6 +53,10 @@ static inline unsigned long pci_address_to_pio(phys_addr_t addr) { return -1; }
 #define pci_address_to_pio pci_address_to_pio
 #endif
 
+int of_pci_range_parser(struct of_pci_range_parser *parser,
+			struct device_node *node);
+struct of_pci_range *of_pci_process_ranges(struct of_pci_range_parser *parser,
+						struct of_pci_range *range);
 #else /* CONFIG_OF_ADDRESS */
 #ifndef of_address_to_resource
 static inline int of_address_to_resource(struct device_node *dev, int index,
@@ -53,6 +83,18 @@ static inline const __be32 *of_get_address(struct device_node *dev, int index,
 {
 	return NULL;
 }
+
+int of_pci_range_parser(struct of_pci_range_parser *parser,
+			struct device_noed *node)
+{
+	return -1;
+}
+
+struct of_pci_range *of_pci_process_ranges(struct of_pci_range_parser *parser,
+						struct of_pci_range *range)
+{
+	return NULL;
+}
 #endif /* CONFIG_OF_ADDRESS */
 
 
-- 
1.7.9.5

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

* [PATCHv7 02/17] of/pci: Add of_pci_get_devfn() function
  2013-03-27 14:40 [PATCHv7 00/17] PCIe support for the Armada 370 and Armada XP SoCs Thomas Petazzoni
  2013-03-27 14:40 ` [PATCHv7 01/17] of/pci: Provide support for parsing PCI DT ranges property Thomas Petazzoni
@ 2013-03-27 14:40 ` Thomas Petazzoni
  2013-03-27 14:40 ` [PATCHv7 03/17] of/pci: Add of_pci_parse_bus_range() function Thomas Petazzoni
                   ` (17 subsequent siblings)
  19 siblings, 0 replies; 37+ messages in thread
From: Thomas Petazzoni @ 2013-03-27 14:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Grant Likely, Russell King
  Cc: linux-pci, linux-arm-kernel, devicetree-discuss, Lior Amsalem,
	Andrew Lunn, Jason Cooper, Arnd Bergmann, Maen Suleiman,
	Thierry Reding, Gregory Clement, Ezequiel Garcia, Olof Johansson,
	Tawfik Bayouk, Jason Gunthorpe, Mitch Bradley, Andrew Murray

From: Thierry Reding <thierry.reding@avionic-design.de>

This function can be used to parse the device and function number from a
standard 5-cell PCI resource. PCI_SLOT() and PCI_FUNC() can be used on
the returned value obtain the device and function numbers respectively.

Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
---
 drivers/of/of_pci.c    |   34 +++++++++++++++++++++++++++++-----
 include/linux/of_pci.h |    1 +
 2 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
index 13e37e2..4dd7b9b 100644
--- a/drivers/of/of_pci.c
+++ b/drivers/of/of_pci.c
@@ -5,14 +5,15 @@
 #include <asm/prom.h>
 
 static inline int __of_pci_pci_compare(struct device_node *node,
-				       unsigned int devfn)
+				       unsigned int data)
 {
-	unsigned int size;
-	const __be32 *reg = of_get_property(node, "reg", &size);
+	int devfn;
 
-	if (!reg || size < 5 * sizeof(__be32))
+	devfn = of_pci_get_devfn(node);
+	if (devfn < 0)
 		return 0;
-	return ((be32_to_cpup(&reg[0]) >> 8) & 0xff) == devfn;
+
+	return devfn == data;
 }
 
 struct device_node *of_pci_find_child_device(struct device_node *parent,
@@ -40,3 +41,26 @@ struct device_node *of_pci_find_child_device(struct device_node *parent,
 	return NULL;
 }
 EXPORT_SYMBOL_GPL(of_pci_find_child_device);
+
+/**
+ * of_pci_get_devfn() - Get device and function numbers for a device node
+ * @np: device node
+ *
+ * Parses a standard 5-cell PCI resource and returns an 8-bit value that can
+ * be passed to the PCI_SLOT() and PCI_FUNC() macros to extract the device
+ * and function numbers respectively. On error a negative error code is
+ * returned.
+ */
+int of_pci_get_devfn(struct device_node *np)
+{
+	unsigned int size;
+	const __be32 *reg;
+
+	reg = of_get_property(np, "reg", &size);
+
+	if (!reg || size < 5 * sizeof(__be32))
+		return -EINVAL;
+
+	return (be32_to_cpup(reg) >> 8) & 0xff;
+}
+EXPORT_SYMBOL_GPL(of_pci_get_devfn);
diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
index bb115de..91ec484 100644
--- a/include/linux/of_pci.h
+++ b/include/linux/of_pci.h
@@ -10,5 +10,6 @@ int of_irq_map_pci(const struct pci_dev *pdev, struct of_irq *out_irq);
 struct device_node;
 struct device_node *of_pci_find_child_device(struct device_node *parent,
 					     unsigned int devfn);
+int of_pci_get_devfn(struct device_node *np);
 
 #endif
-- 
1.7.9.5

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

* [PATCHv7 03/17] of/pci: Add of_pci_parse_bus_range() function
  2013-03-27 14:40 [PATCHv7 00/17] PCIe support for the Armada 370 and Armada XP SoCs Thomas Petazzoni
  2013-03-27 14:40 ` [PATCHv7 01/17] of/pci: Provide support for parsing PCI DT ranges property Thomas Petazzoni
  2013-03-27 14:40 ` [PATCHv7 02/17] of/pci: Add of_pci_get_devfn() function Thomas Petazzoni
@ 2013-03-27 14:40 ` Thomas Petazzoni
  2013-03-27 14:40 ` [PATCHv7 04/17] pci: infrastructure to add drivers in drivers/pci/host Thomas Petazzoni
                   ` (16 subsequent siblings)
  19 siblings, 0 replies; 37+ messages in thread
From: Thomas Petazzoni @ 2013-03-27 14:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Grant Likely, Russell King
  Cc: linux-pci, linux-arm-kernel, devicetree-discuss, Lior Amsalem,
	Andrew Lunn, Jason Cooper, Arnd Bergmann, Maen Suleiman,
	Thierry Reding, Gregory Clement, Ezequiel Garcia, Olof Johansson,
	Tawfik Bayouk, Jason Gunthorpe, Mitch Bradley, Andrew Murray

From: Thierry Reding <thierry.reding@avionic-design.de>

This function can be used to parse a bus-range property as specified by
device nodes representing PCI bridges.

Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
---
 drivers/of/of_pci.c    |   25 +++++++++++++++++++++++++
 include/linux/of_pci.h |    1 +
 2 files changed, 26 insertions(+)

diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
index 4dd7b9b..42c687a 100644
--- a/drivers/of/of_pci.c
+++ b/drivers/of/of_pci.c
@@ -64,3 +64,28 @@ int of_pci_get_devfn(struct device_node *np)
 	return (be32_to_cpup(reg) >> 8) & 0xff;
 }
 EXPORT_SYMBOL_GPL(of_pci_get_devfn);
+
+/**
+ * of_pci_parse_bus_range() - parse the bus-range property of a PCI device
+ * @node: device node
+ * @res: address to a struct resource to return the bus-range
+ *
+ * Returns 0 on success or a negative error-code on failure.
+ */
+int of_pci_parse_bus_range(struct device_node *node, struct resource *res)
+{
+	const __be32 *values;
+	int len;
+
+	values = of_get_property(node, "bus-range", &len);
+	if (!values || len < sizeof(*values) * 2)
+		return -EINVAL;
+
+	res->name = node->name;
+	res->start = be32_to_cpup(values++);
+	res->end = be32_to_cpup(values);
+	res->flags = IORESOURCE_BUS;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(of_pci_parse_bus_range);
diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
index 91ec484..7a04826 100644
--- a/include/linux/of_pci.h
+++ b/include/linux/of_pci.h
@@ -11,5 +11,6 @@ struct device_node;
 struct device_node *of_pci_find_child_device(struct device_node *parent,
 					     unsigned int devfn);
 int of_pci_get_devfn(struct device_node *np);
+int of_pci_parse_bus_range(struct device_node *node, struct resource *res);
 
 #endif
-- 
1.7.9.5

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

* [PATCHv7 04/17] pci: infrastructure to add drivers in drivers/pci/host
  2013-03-27 14:40 [PATCHv7 00/17] PCIe support for the Armada 370 and Armada XP SoCs Thomas Petazzoni
                   ` (2 preceding siblings ...)
  2013-03-27 14:40 ` [PATCHv7 03/17] of/pci: Add of_pci_parse_bus_range() function Thomas Petazzoni
@ 2013-03-27 14:40 ` Thomas Petazzoni
       [not found]   ` <CAAfodu2t4j4ZASzdaKV0QarffXRwMgkMESGy=dDq1oMfTANEeg@mail.gmail.com>
  2013-03-27 14:40 ` [PATCHv7 05/17] arm: pci: add a align_resource hook Thomas Petazzoni
                   ` (15 subsequent siblings)
  19 siblings, 1 reply; 37+ messages in thread
From: Thomas Petazzoni @ 2013-03-27 14:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Grant Likely, Russell King
  Cc: linux-pci, linux-arm-kernel, devicetree-discuss, Lior Amsalem,
	Andrew Lunn, Jason Cooper, Arnd Bergmann, Maen Suleiman,
	Thierry Reding, Gregory Clement, Ezequiel Garcia, Olof Johansson,
	Tawfik Bayouk, Jason Gunthorpe, Mitch Bradley, Andrew Murray

As agreed by the community, PCI host drivers will now be stored in
drivers/pci/host. This commit adds this directory and the related
Kconfig/Makefile changes to allow new drivers to be added in this
directory.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
 drivers/pci/Kconfig      |    2 ++
 drivers/pci/Makefile     |    3 +++
 drivers/pci/host/Kconfig |    4 ++++
 3 files changed, 9 insertions(+)
 create mode 100644 drivers/pci/host/Kconfig

diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 6d51aa6..ac45398 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -119,3 +119,5 @@ config PCI_IOAPIC
 config PCI_LABEL
 	def_bool y if (DMI || ACPI)
 	select NLS
+
+source "drivers/pci/host/Kconfig"
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 0c3efcf..6ebf5bf 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -67,3 +67,6 @@ obj-$(CONFIG_XEN_PCIDEV_FRONTEND) += xen-pcifront.o
 obj-$(CONFIG_OF) += of.o
 
 ccflags-$(CONFIG_PCI_DEBUG) := -DDEBUG
+
+# PCI host controller drivers
+obj-y += host/
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
new file mode 100644
index 0000000..cc3a1af
--- /dev/null
+++ b/drivers/pci/host/Kconfig
@@ -0,0 +1,4 @@
+menu "PCI host controller drivers"
+	depends on PCI
+
+endmenu
-- 
1.7.9.5

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

* [PATCHv7 05/17] arm: pci: add a align_resource hook
  2013-03-27 14:40 [PATCHv7 00/17] PCIe support for the Armada 370 and Armada XP SoCs Thomas Petazzoni
                   ` (3 preceding siblings ...)
  2013-03-27 14:40 ` [PATCHv7 04/17] pci: infrastructure to add drivers in drivers/pci/host Thomas Petazzoni
@ 2013-03-27 14:40 ` Thomas Petazzoni
  2013-03-27 14:40 ` [PATCHv7 06/17] clk: mvebu: create parent-child relation for PCIe clocks on Armada 370 Thomas Petazzoni
                   ` (14 subsequent siblings)
  19 siblings, 0 replies; 37+ messages in thread
From: Thomas Petazzoni @ 2013-03-27 14:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Grant Likely, Russell King
  Cc: linux-pci, linux-arm-kernel, devicetree-discuss, Lior Amsalem,
	Andrew Lunn, Jason Cooper, Arnd Bergmann, Maen Suleiman,
	Thierry Reding, Gregory Clement, Ezequiel Garcia, Olof Johansson,
	Tawfik Bayouk, Jason Gunthorpe, Mitch Bradley, Andrew Murray

The PCI specifications says that an I/O region must be aligned on a 4
KB boundary, and a memory region aligned on a 1 MB boundary.

However, the Marvell PCIe interfaces rely on address decoding windows
(which allow to associate a range of physical addresses with a given
device). For PCIe memory windows, those windows are defined with a 1
MB granularity (which matches the PCI specs), but PCIe I/O windows can
only be defined with a 64 KB granularity, so they have to be 64 KB
aligned. We therefore need to tell the PCI core about this special
alignement requirement.

The PCI core already calls pcibios_align_resource() in the ARM PCI
core, specifically for such purposes. So this patch extends the ARM
PCI core so that it calls a ->align_resource() hook registered by the
PCI driver, exactly like the existing ->map_irq() and ->swizzle()
hooks.

A particular PCI driver can register a align_resource() hook, and do
its own specific alignement, depending on the specific constraints of
the underlying hardware.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Cc: Russell King <linux@arm.linux.org.uk>
---
 arch/arm/include/asm/mach/pci.h |   11 +++++++++++
 arch/arm/kernel/bios32.c        |    6 ++++++
 2 files changed, 17 insertions(+)

diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h
index 5cf2e97..7d2c3c8 100644
--- a/arch/arm/include/asm/mach/pci.h
+++ b/arch/arm/include/asm/mach/pci.h
@@ -30,6 +30,11 @@ struct hw_pci {
 	void		(*postinit)(void);
 	u8		(*swizzle)(struct pci_dev *dev, u8 *pin);
 	int		(*map_irq)(const struct pci_dev *dev, u8 slot, u8 pin);
+	resource_size_t (*align_resource)(struct pci_dev *dev,
+					  const struct resource *res,
+					  resource_size_t start,
+					  resource_size_t size,
+					  resource_size_t align);
 };
 
 /*
@@ -51,6 +56,12 @@ struct pci_sys_data {
 	u8		(*swizzle)(struct pci_dev *, u8 *);
 					/* IRQ mapping				*/
 	int		(*map_irq)(const struct pci_dev *, u8, u8);
+					/* Resource alignement requirements	*/
+	resource_size_t (*align_resource)(struct pci_dev *dev,
+					  const struct resource *res,
+					  resource_size_t start,
+					  resource_size_t size,
+					  resource_size_t align);
 	void		*private_data;	/* platform controller private data	*/
 };
 
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index a1f73b5..b2ed73c 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -462,6 +462,7 @@ static void pcibios_init_hw(struct hw_pci *hw, struct list_head *head)
 		sys->busnr   = busnr;
 		sys->swizzle = hw->swizzle;
 		sys->map_irq = hw->map_irq;
+		sys->align_resource = hw->align_resource;
 		INIT_LIST_HEAD(&sys->resources);
 
 		if (hw->private_data)
@@ -574,6 +575,8 @@ char * __init pcibios_setup(char *str)
 resource_size_t pcibios_align_resource(void *data, const struct resource *res,
 				resource_size_t size, resource_size_t align)
 {
+	struct pci_dev *dev = data;
+	struct pci_sys_data *sys = dev->sysdata;
 	resource_size_t start = res->start;
 
 	if (res->flags & IORESOURCE_IO && start & 0x300)
@@ -581,6 +584,9 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
 
 	start = (start + align - 1) & ~(align - 1);
 
+	if (sys->align_resource)
+		return sys->align_resource(dev, res, start, size, align);
+
 	return start;
 }
 
-- 
1.7.9.5

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

* [PATCHv7 06/17] clk: mvebu: create parent-child relation for PCIe clocks on Armada 370
  2013-03-27 14:40 [PATCHv7 00/17] PCIe support for the Armada 370 and Armada XP SoCs Thomas Petazzoni
                   ` (4 preceding siblings ...)
  2013-03-27 14:40 ` [PATCHv7 05/17] arm: pci: add a align_resource hook Thomas Petazzoni
@ 2013-03-27 14:40 ` Thomas Petazzoni
  2013-04-05 13:58   ` Thomas Petazzoni
  2013-04-10  8:09   ` Mike Turquette
  2013-03-27 14:40 ` [PATCHv7 07/17] clk: mvebu: add more PCIe clocks for Armada XP Thomas Petazzoni
                   ` (13 subsequent siblings)
  19 siblings, 2 replies; 37+ messages in thread
From: Thomas Petazzoni @ 2013-03-27 14:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Grant Likely, Russell King
  Cc: linux-pci, linux-arm-kernel, devicetree-discuss, Lior Amsalem,
	Andrew Lunn, Jason Cooper, Arnd Bergmann, Maen Suleiman,
	Thierry Reding, Gregory Clement, Ezequiel Garcia, Olof Johansson,
	Tawfik Bayouk, Jason Gunthorpe, Mitch Bradley, Andrew Murray,
	Mike Turquette

The Armada 370 has two gatable clocks for each PCIe interface, and we
want both of them to be enabled. We therefore make one of the two
clocks a child of the other, as we did for the sataX and sataXlnk
clocks on Armada XP.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Cc: Mike Turquette <mturquette@linaro.org>
---
 drivers/clk/mvebu/clk-gating-ctrl.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/mvebu/clk-gating-ctrl.c b/drivers/clk/mvebu/clk-gating-ctrl.c
index ebf141d..b35785a 100644
--- a/drivers/clk/mvebu/clk-gating-ctrl.c
+++ b/drivers/clk/mvebu/clk-gating-ctrl.c
@@ -119,8 +119,8 @@ static const struct mvebu_soc_descr __initconst armada_370_gating_descr[] = {
 	{ "pex1_en", NULL,  2 },
 	{ "ge1", NULL, 3 },
 	{ "ge0", NULL, 4 },
-	{ "pex0", NULL, 5 },
-	{ "pex1", NULL, 9 },
+	{ "pex0", "pex0_en", 5 },
+	{ "pex1", "pex1_en", 9 },
 	{ "sata0", NULL, 15 },
 	{ "sdio", NULL, 17 },
 	{ "tdm", NULL, 25 },
-- 
1.7.9.5

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

* [PATCHv7 07/17] clk: mvebu: add more PCIe clocks for Armada XP
  2013-03-27 14:40 [PATCHv7 00/17] PCIe support for the Armada 370 and Armada XP SoCs Thomas Petazzoni
                   ` (5 preceding siblings ...)
  2013-03-27 14:40 ` [PATCHv7 06/17] clk: mvebu: create parent-child relation for PCIe clocks on Armada 370 Thomas Petazzoni
@ 2013-03-27 14:40 ` Thomas Petazzoni
  2013-04-05 14:59   ` Thomas Petazzoni
  2013-04-10  8:08   ` Mike Turquette
  2013-03-27 14:40 ` [PATCHv7 08/17] pci: PCIe driver for Marvell Armada 370/XP systems Thomas Petazzoni
                   ` (12 subsequent siblings)
  19 siblings, 2 replies; 37+ messages in thread
From: Thomas Petazzoni @ 2013-03-27 14:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Grant Likely, Russell King
  Cc: linux-pci, linux-arm-kernel, devicetree-discuss, Lior Amsalem,
	Andrew Lunn, Jason Cooper, Arnd Bergmann, Maen Suleiman,
	Thierry Reding, Gregory Clement, Ezequiel Garcia, Olof Johansson,
	Tawfik Bayouk, Jason Gunthorpe, Mitch Bradley, Andrew Murray

The current revision of the datasheet only mentions the gatable clocks
for the PCIe 0.0, 0.1, 0.2 and 0.3 interfaces, and forgot to mention
the ones for the PCIe 1.0, 1.1, 1.2, 1.3, 2.0 and 3.0
interfaces. After confirmation with Marvell engineers, this patch adds
the missing gatable clocks for those PCIe interfaces.

It also changes the name of the previously existing PCIe gatable
clocks, in order to match the naming using the datasheets.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
 drivers/clk/mvebu/clk-gating-ctrl.c |   14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/mvebu/clk-gating-ctrl.c b/drivers/clk/mvebu/clk-gating-ctrl.c
index b35785a..2f03723 100644
--- a/drivers/clk/mvebu/clk-gating-ctrl.c
+++ b/drivers/clk/mvebu/clk-gating-ctrl.c
@@ -137,10 +137,14 @@ static const struct mvebu_soc_descr __initconst armada_xp_gating_descr[] = {
 	{ "ge2", NULL,  2 },
 	{ "ge1", NULL, 3 },
 	{ "ge0", NULL, 4 },
-	{ "pex0", NULL, 5 },
-	{ "pex1", NULL, 6 },
-	{ "pex2", NULL, 7 },
-	{ "pex3", NULL, 8 },
+	{ "pex00", NULL, 5 },
+	{ "pex01", NULL, 6 },
+	{ "pex02", NULL, 7 },
+	{ "pex03", NULL, 8 },
+	{ "pex10", NULL, 9 },
+	{ "pex11", NULL, 10 },
+	{ "pex12", NULL, 11 },
+	{ "pex13", NULL, 12 },
 	{ "bp", NULL, 13 },
 	{ "sata0lnk", NULL, 14 },
 	{ "sata0", "sata0lnk", 15 },
@@ -152,6 +156,8 @@ static const struct mvebu_soc_descr __initconst armada_xp_gating_descr[] = {
 	{ "xor0", NULL, 22 },
 	{ "crypto", NULL, 23 },
 	{ "tdm", NULL, 25 },
+	{ "pex20", NULL, 26 },
+	{ "pex30", NULL, 27 },
 	{ "xor1", NULL, 28 },
 	{ "sata1lnk", NULL, 29 },
 	{ "sata1", "sata1lnk", 30 },
-- 
1.7.9.5

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

* [PATCHv7 08/17] pci: PCIe driver for Marvell Armada 370/XP systems
  2013-03-27 14:40 [PATCHv7 00/17] PCIe support for the Armada 370 and Armada XP SoCs Thomas Petazzoni
                   ` (6 preceding siblings ...)
  2013-03-27 14:40 ` [PATCHv7 07/17] clk: mvebu: add more PCIe clocks for Armada XP Thomas Petazzoni
@ 2013-03-27 14:40 ` Thomas Petazzoni
  2013-04-08 20:29   ` Bjorn Helgaas
  2013-03-27 14:40 ` [PATCHv7 09/17] arm: mvebu: PCIe support is now available on mvebu Thomas Petazzoni
                   ` (11 subsequent siblings)
  19 siblings, 1 reply; 37+ messages in thread
From: Thomas Petazzoni @ 2013-03-27 14:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Grant Likely, Russell King
  Cc: linux-pci, linux-arm-kernel, devicetree-discuss, Lior Amsalem,
	Andrew Lunn, Jason Cooper, Arnd Bergmann, Maen Suleiman,
	Thierry Reding, Gregory Clement, Ezequiel Garcia, Olof Johansson,
	Tawfik Bayouk, Jason Gunthorpe, Mitch Bradley, Andrew Murray

This driver implements the support for the PCIe interfaces on the
Marvell Armada 370/XP ARM SoCs. In the future, it might be extended to
cover earlier families of Marvell SoCs, such as Dove, Orion and
Kirkwood.

The driver implements the hw_pci operations needed by the core ARM PCI
code to setup PCI devices and get their corresponding IRQs, and the
pci_ops operations that are used by the PCI core to read/write the
configuration space of PCI devices.

Since the PCIe interfaces of Marvell SoCs are completely separate and
not linked together in a bus, this driver sets up an emulated PCI host
bridge, with one PCI-to-PCI bridge as child for each hardware PCIe
interface.

In addition, this driver enumerates the different PCIe slots, and for
those having a device plugged in, it sets up the necessary address
decoding windows, using the new armada_370_xp_alloc_pcie_window()
function from mach-mvebu/addr-map.c.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
 .../devicetree/bindings/pci/mvebu-pci.txt          |  220 +++++
 drivers/pci/host/Kconfig                           |    4 +
 drivers/pci/host/Makefile                          |    4 +
 drivers/pci/host/pci-mvebu.c                       |  927 ++++++++++++++++++++
 4 files changed, 1155 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/mvebu-pci.txt
 create mode 100644 drivers/pci/host/Makefile
 create mode 100644 drivers/pci/host/pci-mvebu.c

diff --git a/Documentation/devicetree/bindings/pci/mvebu-pci.txt b/Documentation/devicetree/bindings/pci/mvebu-pci.txt
new file mode 100644
index 0000000..eb69d92
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/mvebu-pci.txt
@@ -0,0 +1,220 @@
+* Marvell EBU PCIe interfaces
+
+Mandatory properties:
+- compatible: one of the following values:
+    marvell,armada-370-pcie
+    marvell,armada-xp-pcie
+- #address-cells, set to <3>
+- #size-cells, set to <2>
+- #interrupt-cells, set to <1>
+- bus-range: PCI bus numbers covered
+- device_type, set to "pci"
+- ranges: ranges for the PCI memory and I/O regions, as well as the
+  MMIO registers to control the PCIe interfaces.
+
+In addition, the Device Tree node must have sub-nodes describing each
+PCIe interface, having the following mandatory properties:
+- reg: used only for interrupt mapping, so only the first four bytes
+  are used to refer to the correct bus number and device number.
+- assigned-addresses: reference to the MMIO registers used to control
+  this PCIe interface.
+- clocks: the clock associated to this PCIe interface
+- marvell,pcie-port: the physical PCIe port number
+- status: either "disabled" or "okay"
+- device_type, set to "pci"
+- #address-cells, set to <3>
+- #size-cells, set to <2>
+- #interrupt-cells, set to <1>
+- ranges, empty property.
+- interrupt-map-mask and interrupt-map, standard PCI properties to
+  define the mapping of the PCIe interface to interrupt numbers.
+
+and the following optional properties:
+- marvell,pcie-lane: the physical PCIe lane number, for ports having
+  multiple lanes. If this property is not found, we assume that the
+  value is 0.
+
+Example:
+
+pcie-controller {
+	compatible = "marvell,armada-xp-pcie";
+	status = "disabled";
+	device_type = "pci";
+
+	#address-cells = <3>;
+	#size-cells = <2>;
+
+	bus-range = <0x00 0xff>;
+
+	ranges = <0x82000000 0 0xd0040000 0xd0040000 0 0x00002000   /* Port 0.0 registers */
+		  0x82000000 0 0xd0042000 0xd0042000 0 0x00002000   /* Port 2.0 registers */
+		  0x82000000 0 0xd0044000 0xd0044000 0 0x00002000   /* Port 0.1 registers */
+		  0x82000000 0 0xd0048000 0xd0048000 0 0x00002000   /* Port 0.2 registers */
+		  0x82000000 0 0xd004c000 0xd004c000 0 0x00002000   /* Port 0.3 registers */
+		  0x82000000 0 0xd0080000 0xd0080000 0 0x00002000   /* Port 1.0 registers */
+		  0x82000000 0 0xd0082000 0xd0082000 0 0x00002000   /* Port 3.0 registers */
+		  0x82000000 0 0xd0084000 0xd0084000 0 0x00002000   /* Port 1.1 registers */
+		  0x82000000 0 0xd0088000 0xd0088000 0 0x00002000   /* Port 1.2 registers */
+		  0x82000000 0 0xd008c000 0xd008c000 0 0x00002000   /* Port 1.3 registers */
+		  0x82000000 0 0xe0000000 0xe0000000 0 0x08000000   /* non-prefetchable memory */
+		  0x81000000 0 0	  0xe8000000 0 0x00100000>; /* downstream I/O */
+
+	pcie@1,0 {
+		device_type = "pci";
+		assigned-addresses = <0x82000800 0 0xd0040000 0 0x2000>;
+		reg = <0x0800 0 0 0 0>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		#interrupt-cells = <1>;
+		ranges;
+		interrupt-map-mask = <0 0 0 0>;
+		interrupt-map = <0 0 0 0 &mpic 58>;
+		marvell,pcie-port = <0>;
+		marvell,pcie-lane = <0>;
+		clocks = <&gateclk 5>;
+		status = "disabled";
+	};
+
+	pcie@2,0 {
+		device_type = "pci";
+		assigned-addresses = <0x82001000 0 0xd0044000 0 0x2000>;
+		reg = <0x1000 0 0 0 0>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		#interrupt-cells = <1>;
+		ranges;
+		interrupt-map-mask = <0 0 0 0>;
+		interrupt-map = <0 0 0 0 &mpic 59>;
+		marvell,pcie-port = <0>;
+		marvell,pcie-lane = <1>;
+		clocks = <&gateclk 6>;
+		status = "disabled";
+	};
+
+	pcie@3,0 {
+		device_type = "pci";
+		assigned-addresses = <0x82001800 0 0xd0048000 0 0x2000>;
+		reg = <0x1800 0 0 0 0>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		#interrupt-cells = <1>;
+		ranges;
+		interrupt-map-mask = <0 0 0 0>;
+		interrupt-map = <0 0 0 0 &mpic 60>;
+		marvell,pcie-port = <0>;
+		marvell,pcie-lane = <2>;
+		clocks = <&gateclk 7>;
+		status = "disabled";
+	};
+
+	pcie@4,0 {
+		device_type = "pci";
+		assigned-addresses = <0x82002000 0 0xd004c000 0 0x2000>;
+		reg = <0x2000 0 0 0 0>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		#interrupt-cells = <1>;
+		ranges;
+		interrupt-map-mask = <0 0 0 0>;
+		interrupt-map = <0 0 0 0 &mpic 61>;
+		marvell,pcie-port = <0>;
+		marvell,pcie-lane = <3>;
+		clocks = <&gateclk 8>;
+		status = "disabled";
+	};
+
+	pcie@5,0 {
+		device_type = "pci";
+		assigned-addresses = <0x82002800 0 0xd0080000 0 0x2000>;
+		reg = <0x2800 0 0 0 0>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		#interrupt-cells = <1>;
+		ranges;
+		interrupt-map-mask = <0 0 0 0>;
+		interrupt-map = <0 0 0 0 &mpic 62>;
+		marvell,pcie-port = <1>;
+		marvell,pcie-lane = <0>;
+		clocks = <&gateclk 9>;
+		status = "disabled";
+	};
+
+	pcie@6,0 {
+		device_type = "pci";
+		assigned-addresses = <0x82003000 0 0xd0084000 0 0x2000>;
+		reg = <0x3000 0 0 0 0>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		#interrupt-cells = <1>;
+		ranges;
+		interrupt-map-mask = <0 0 0 0>;
+		interrupt-map = <0 0 0 0 &mpic 63>;
+		marvell,pcie-port = <1>;
+		marvell,pcie-lane = <1>;
+		clocks = <&gateclk 10>;
+		status = "disabled";
+	};
+
+	pcie@7,0 {
+		device_type = "pci";
+		assigned-addresses = <0x82003800 0 0xd0088000 0 0x2000>;
+		reg = <0x3800 0 0 0 0>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		#interrupt-cells = <1>;
+		ranges;
+		interrupt-map-mask = <0 0 0 0>;
+		interrupt-map = <0 0 0 0 &mpic 64>;
+		marvell,pcie-port = <1>;
+		marvell,pcie-lane = <2>;
+		clocks = <&gateclk 11>;
+		status = "disabled";
+	};
+
+	pcie@8,0 {
+		device_type = "pci";
+		assigned-addresses = <0x82004000 0 0xd008c000 0 0x2000>;
+		reg = <0x4000 0 0 0 0>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		#interrupt-cells = <1>;
+		ranges;
+		interrupt-map-mask = <0 0 0 0>;
+		interrupt-map = <0 0 0 0 &mpic 65>;
+		marvell,pcie-port = <1>;
+		marvell,pcie-lane = <3>;
+		clocks = <&gateclk 12>;
+		status = "disabled";
+	};
+	pcie@9,0 {
+		device_type = "pci";
+		assigned-addresses = <0x82004800 0 0xd0042000 0 0x2000>;
+		reg = <0x4800 0 0 0 0>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		#interrupt-cells = <1>;
+		ranges;
+		interrupt-map-mask = <0 0 0 0>;
+		interrupt-map = <0 0 0 0 &mpic 99>;
+		marvell,pcie-port = <2>;
+		marvell,pcie-lane = <0>;
+		clocks = <&gateclk 26>;
+		status = "disabled";
+	};
+
+	pcie@10,0 {
+		device_type = "pci";
+		assigned-addresses = <0x82005000 0 0xd0082000 0 0x2000>;
+		reg = <0x5000 0 0 0 0>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		#interrupt-cells = <1>;
+		ranges;
+		interrupt-map-mask = <0 0 0 0>;
+		interrupt-map = <0 0 0 0 &mpic 103>;
+		marvell,pcie-port = <3>;
+		marvell,pcie-lane = <0>;
+		clocks = <&gateclk 27>;
+		status = "disabled";
+	};
+};
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index cc3a1af..6918fbc 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -1,4 +1,8 @@
 menu "PCI host controller drivers"
 	depends on PCI
 
+config PCI_MVEBU
+	bool "Marvell EBU PCIe controller"
+	depends on ARCH_MVEBU
+
 endmenu
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
new file mode 100644
index 0000000..3ad563f
--- /dev/null
+++ b/drivers/pci/host/Makefile
@@ -0,0 +1,4 @@
+obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
+CFLAGS_pci-mvebu.o += \
+	-I$(srctree)/arch/arm/plat-orion/include \
+	-I$(srctree)/arch/arm/mach-mvebu/include
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c
new file mode 100644
index 0000000..289babd
--- /dev/null
+++ b/drivers/pci/host/pci-mvebu.c
@@ -0,0 +1,927 @@
+/*
+ * PCIe driver for Marvell Armada 370 and Armada XP SoCs
+ *
+ * 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/kernel.h>
+#include <linux/pci.h>
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/mbus.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/of_address.h>
+#include <linux/of_pci.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+
+/*
+ * PCIe unit register offsets.
+ */
+#define PCIE_DEV_ID_OFF		0x0000
+#define PCIE_CMD_OFF		0x0004
+#define PCIE_DEV_REV_OFF	0x0008
+#define PCIE_BAR_LO_OFF(n)	(0x0010 + ((n) << 3))
+#define PCIE_BAR_HI_OFF(n)	(0x0014 + ((n) << 3))
+#define PCIE_HEADER_LOG_4_OFF	0x0128
+#define PCIE_BAR_CTRL_OFF(n)	(0x1804 + ((n - 1) * 4))
+#define PCIE_WIN04_CTRL_OFF(n)	(0x1820 + ((n) << 4))
+#define PCIE_WIN04_BASE_OFF(n)	(0x1824 + ((n) << 4))
+#define PCIE_WIN04_REMAP_OFF(n)	(0x182c + ((n) << 4))
+#define PCIE_WIN5_CTRL_OFF	0x1880
+#define PCIE_WIN5_BASE_OFF	0x1884
+#define PCIE_WIN5_REMAP_OFF	0x188c
+#define PCIE_CONF_ADDR_OFF	0x18f8
+#define  PCIE_CONF_ADDR_EN		0x80000000
+#define  PCIE_CONF_REG(r)		((((r) & 0xf00) << 16) | ((r) & 0xfc))
+#define  PCIE_CONF_BUS(b)		(((b) & 0xff) << 16)
+#define  PCIE_CONF_DEV(d)		(((d) & 0x1f) << 11)
+#define  PCIE_CONF_FUNC(f)		(((f) & 0x7) << 8)
+#define PCIE_CONF_DATA_OFF	0x18fc
+#define PCIE_MASK_OFF		0x1910
+#define PCIE_CTRL_OFF		0x1a00
+#define  PCIE_CTRL_X1_MODE		0x0001
+#define PCIE_STAT_OFF		0x1a04
+#define  PCIE_STAT_DEV_OFFS		20
+#define  PCIE_STAT_DEV_MASK		0x1f
+#define  PCIE_STAT_BUS_OFFS		8
+#define  PCIE_STAT_BUS_MASK		0xff
+#define  PCIE_STAT_LINK_DOWN		1
+#define PCIE_DEBUG_CTRL         0x1a60
+#define  PCIE_DEBUG_SOFT_RESET		(1<<20)
+
+/*
+ * This product ID is registered by Marvell, and used when the Marvell
+ * SoC is not the root complex, but an endpoint on the PCIe bus. It is
+ * therefore safe to re-use this PCI ID for our emulated PCI-to-PCI
+ * bridge.
+ */
+#define MARVELL_EMULATED_PCI_PCI_BRIDGE_ID 0x7846
+
+/* PCI configuration space of a PCI-to-PCI bridge */
+struct mvebu_sw_pci_bridge {
+	u16 vendor;
+	u16 device;
+	u16 command;
+	u16 status;
+	u16 class;
+	u8 interface;
+	u8 revision;
+	u8 bist;
+	u8 header_type;
+	u8 latency_timer;
+	u8 cache_line_size;
+	u32 bar[2];
+	u8 primary_bus;
+	u8 secondary_bus;
+	u8 subordinate_bus;
+	u8 secondary_latency_timer;
+	u8 iobase;
+	u8 iolimit;
+	u16 secondary_status;
+	u16 membase;
+	u16 memlimit;
+	u16 prefmembase;
+	u16 prefmemlimit;
+	u32 prefbaseupper;
+	u32 preflimitupper;
+	u16 iobaseupper;
+	u16 iolimitupper;
+	u8 cappointer;
+	u8 reserved1;
+	u16 reserved2;
+	u32 romaddr;
+	u8 intline;
+	u8 intpin;
+	u16 bridgectrl;
+};
+
+struct mvebu_pcie_port;
+
+/* Structure representing all PCIe interfaces */
+struct mvebu_pcie {
+	struct platform_device *pdev;
+	struct mvebu_pcie_port *ports;
+	struct resource io;
+	struct resource realio;
+	struct resource mem;
+	struct resource busn;
+	int nports;
+};
+
+/* Structure representing one PCIe interface */
+struct mvebu_pcie_port {
+	char *name;
+	void __iomem *base;
+	spinlock_t conf_lock;
+	int haslink;
+	u32 port;
+	u32 lane;
+	int devfn;
+	struct clk *clk;
+	struct mvebu_sw_pci_bridge bridge;
+	struct device_node *dn;
+	struct mvebu_pcie *pcie;
+	phys_addr_t memwin_base;
+	size_t memwin_size;
+	phys_addr_t iowin_base;
+	size_t iowin_size;
+};
+
+static int mvebu_pcie_link_up(void __iomem *base)
+{
+	return !(readl(base + PCIE_STAT_OFF) & PCIE_STAT_LINK_DOWN);
+}
+
+static void mvebu_pcie_set_local_bus_nr(void __iomem *base, int nr)
+{
+	u32 stat;
+
+	stat = readl(base + PCIE_STAT_OFF);
+	stat &= ~(PCIE_STAT_BUS_MASK << PCIE_STAT_BUS_OFFS);
+	stat |= nr << PCIE_STAT_BUS_OFFS;
+	writel(stat, base + PCIE_STAT_OFF);
+}
+
+/*
+ * Setup PCIE BARs and Address Decode Wins:
+ * BAR[0,2] -> disabled, BAR[1] -> covers all DRAM banks
+ * WIN[0-3] -> DRAM bank[0-3]
+ */
+static void __init mvebu_pcie_setup_wins(void __iomem *base)
+{
+	const struct mbus_dram_target_info *dram;
+	u32 size;
+	int i;
+
+	dram = mv_mbus_dram_info();
+
+	/*
+	 * First, disable and clear BARs and windows.
+	 */
+	for (i = 1; i <= 2; i++) {
+		writel(0, base + PCIE_BAR_CTRL_OFF(i));
+		writel(0, base + PCIE_BAR_LO_OFF(i));
+		writel(0, base + PCIE_BAR_HI_OFF(i));
+	}
+
+	for (i = 0; i < 5; i++) {
+		writel(0, base + PCIE_WIN04_CTRL_OFF(i));
+		writel(0, base + PCIE_WIN04_BASE_OFF(i));
+		writel(0, base + PCIE_WIN04_REMAP_OFF(i));
+	}
+
+	writel(0, base + PCIE_WIN5_CTRL_OFF);
+	writel(0, base + PCIE_WIN5_BASE_OFF);
+	writel(0, base + PCIE_WIN5_REMAP_OFF);
+
+	/*
+	 * Setup windows for DDR banks.  Count total DDR size on the fly.
+	 */
+	size = 0;
+	for (i = 0; i < dram->num_cs; i++) {
+		const struct mbus_dram_window *cs = dram->cs + i;
+
+		writel(cs->base & 0xffff0000, base + PCIE_WIN04_BASE_OFF(i));
+		writel(0, base + PCIE_WIN04_REMAP_OFF(i));
+		writel(((cs->size - 1) & 0xffff0000) |
+			(cs->mbus_attr << 8) |
+			(dram->mbus_dram_target_id << 4) | 1,
+				base + PCIE_WIN04_CTRL_OFF(i));
+
+		size += cs->size;
+	}
+
+	/*
+	 * Round up 'size' to the nearest power of two.
+	 */
+	if ((size & (size - 1)) != 0)
+		size = 1 << fls(size);
+
+	/*
+	 * Setup BAR[1] to all DRAM banks.
+	 */
+	writel(dram->cs[0].base, base + PCIE_BAR_LO_OFF(1));
+	writel(0, base + PCIE_BAR_HI_OFF(1));
+	writel(((size - 1) & 0xffff0000) | 1, base + PCIE_BAR_CTRL_OFF(1));
+}
+
+static void __init mvebu_pcie_setup_hw(void __iomem *base)
+{
+	u16 cmd;
+	u32 mask;
+
+	/*
+	 * Point PCIe unit MBUS decode windows to DRAM space.
+	 */
+	mvebu_pcie_setup_wins(base);
+
+	/*
+	 * Master + slave enable.
+	 */
+	cmd = readw(base + PCIE_CMD_OFF);
+	cmd |= PCI_COMMAND_IO;
+	cmd |= PCI_COMMAND_MEMORY;
+	cmd |= PCI_COMMAND_MASTER;
+	writew(cmd, base + PCIE_CMD_OFF);
+
+	/*
+	 * Enable interrupt lines A-D.
+	 */
+	mask = readl(base + PCIE_MASK_OFF);
+	mask |= 0x0f000000;
+	writel(mask, base + PCIE_MASK_OFF);
+}
+
+static int mvebu_pcie_hw_rd_conf(void __iomem *base, struct pci_bus *bus,
+				 u32 devfn, int where, int size, u32 *val)
+{
+	writel(PCIE_CONF_BUS(bus->number) |
+		PCIE_CONF_DEV(PCI_SLOT(devfn)) |
+		PCIE_CONF_FUNC(PCI_FUNC(devfn)) |
+		PCIE_CONF_REG(where) | PCIE_CONF_ADDR_EN,
+			base + PCIE_CONF_ADDR_OFF);
+
+	*val = readl(base + PCIE_CONF_DATA_OFF);
+
+	if (size == 1)
+		*val = (*val >> (8 * (where & 3))) & 0xff;
+	else if (size == 2)
+		*val = (*val >> (8 * (where & 3))) & 0xffff;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int mvebu_pcie_hw_wr_conf(void __iomem *base, struct pci_bus *bus,
+			      u32 devfn, int where, int size, u32 val)
+{
+	int ret = PCIBIOS_SUCCESSFUL;
+
+	writel(PCIE_CONF_BUS(bus->number) |
+		PCIE_CONF_DEV(PCI_SLOT(devfn)) |
+		PCIE_CONF_FUNC(PCI_FUNC(devfn)) |
+		PCIE_CONF_REG(where) | PCIE_CONF_ADDR_EN,
+			base + PCIE_CONF_ADDR_OFF);
+
+	if (size == 4)
+		writel(val, base + PCIE_CONF_DATA_OFF);
+	else if (size == 2)
+		writew(val, base + PCIE_CONF_DATA_OFF + (where & 3));
+	else if (size == 1)
+		writeb(val, base + PCIE_CONF_DATA_OFF + (where & 3));
+	else
+		ret = PCIBIOS_BAD_REGISTER_NUMBER;
+
+	return ret;
+}
+
+static void mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port *port)
+{
+	phys_addr_t iobase;
+
+	/* Are the current iobase/iolimit values invalid? */
+	if (port->bridge.iolimit < port->bridge.iobase ||
+	    port->bridge.iolimitupper < port->bridge.iobaseupper) {
+
+		/* If a window was configured, remove it */
+		if (port->iowin_base) {
+			mvebu_mbus_del_window(port->iowin_base,
+					      port->iowin_size);
+			port->iowin_base = 0;
+			port->iowin_size = 0;
+		}
+
+		return;
+	}
+
+	/*
+	 * We read the PCI-to-PCI bridge emulated registers, and
+	 * calculate the base address and size of the address decoding
+	 * window to setup, according to the PCI-to-PCI bridge
+	 * specifications. iobase is the bus address, port->iowin_base
+	 * is the CPU address.
+	 */
+	iobase = ((port->bridge.iobase & 0xF0) << 8) |
+		(port->bridge.iobaseupper << 16);
+	port->iowin_base = port->pcie->io.start + iobase;
+	port->iowin_size = ((0xFFF | ((port->bridge.iolimit & 0xF0) << 8) |
+			    (port->bridge.iolimitupper << 16)) -
+			    iobase);
+
+	mvebu_mbus_add_window_remap_flags(port->name, port->iowin_base,
+					  port->iowin_size,
+					  iobase,
+					  MVEBU_MBUS_PCI_IO);
+
+	pci_ioremap_io(iobase, port->iowin_base);
+}
+
+static void mvebu_pcie_handle_membase_change(struct mvebu_pcie_port *port)
+{
+	/* Are the current membase/memlimit values invalid? */
+	if (port->bridge.memlimit < port->bridge.membase) {
+
+		/* If a window was configured, remove it */
+		if (port->memwin_base) {
+			mvebu_mbus_del_window(port->memwin_base,
+					      port->memwin_size);
+			port->memwin_base = 0;
+			port->memwin_size = 0;
+		}
+
+		return;
+	}
+
+	/*
+	 * We read the PCI-to-PCI bridge emulated registers, and
+	 * calculate the base address and size of the address decoding
+	 * window to setup, according to the PCI-to-PCI bridge
+	 * specifications.
+	 */
+	port->memwin_base  = ((port->bridge.membase & 0xFFF0) << 16);
+	port->memwin_size  =
+		(((port->bridge.memlimit & 0xFFF0) << 16) | 0xFFFFF) -
+		port->memwin_base;
+
+	mvebu_mbus_add_window_remap_flags(port->name, port->memwin_base,
+					  port->memwin_size,
+					  MVEBU_MBUS_NO_REMAP,
+					  MVEBU_MBUS_PCI_MEM);
+}
+
+/*
+ * Initialize the configuration space of the PCI-to-PCI bridge
+ * associated with the given PCIe interface.
+ */
+static void mvebu_sw_pci_bridge_init(struct mvebu_pcie_port *port)
+{
+	struct mvebu_sw_pci_bridge *bridge = &port->bridge;
+
+	memset(bridge, 0, sizeof(struct mvebu_sw_pci_bridge));
+
+	bridge->status = PCI_STATUS_CAP_LIST;
+	bridge->class = PCI_CLASS_BRIDGE_PCI;
+	bridge->vendor = PCI_VENDOR_ID_MARVELL;
+	bridge->device = MARVELL_EMULATED_PCI_PCI_BRIDGE_ID;
+	bridge->header_type = PCI_HEADER_TYPE_BRIDGE;
+	bridge->cache_line_size = 0x10;
+
+	/* We support 32 bits I/O addressing */
+	bridge->iobase = PCI_IO_RANGE_TYPE_32;
+	bridge->iolimit = PCI_IO_RANGE_TYPE_32;
+}
+
+/*
+ * Read the configuration space of the PCI-to-PCI bridge associated to
+ * the given PCIe interface.
+ */
+static int mvebu_sw_pci_bridge_read(struct mvebu_pcie_port *port,
+				  unsigned int where, int size, u32 *value)
+{
+	struct mvebu_sw_pci_bridge *bridge = &port->bridge;
+
+	switch (where & ~3) {
+	case PCI_VENDOR_ID:
+		*value = bridge->device << 16 | bridge->vendor;
+		break;
+
+	case PCI_COMMAND:
+		*value = bridge->status << 16 | bridge->command;
+		break;
+
+	case PCI_CLASS_REVISION:
+		*value = bridge->class << 16 | bridge->interface << 8 |
+			 bridge->revision;
+		break;
+
+	case PCI_CACHE_LINE_SIZE:
+		*value = bridge->bist << 24 | bridge->header_type << 16 |
+			 bridge->latency_timer << 8 | bridge->cache_line_size;
+		break;
+
+	case PCI_BASE_ADDRESS_0 ... PCI_BASE_ADDRESS_1:
+		*value = bridge->bar[((where & ~3) - PCI_BASE_ADDRESS_0) / 4];
+		break;
+
+	case PCI_PRIMARY_BUS:
+		*value = (bridge->secondary_latency_timer << 24 |
+			  bridge->subordinate_bus         << 16 |
+			  bridge->secondary_bus           <<  8 |
+			  bridge->primary_bus);
+		break;
+
+	case PCI_IO_BASE:
+		*value = (bridge->secondary_status << 16 |
+			  bridge->iolimit          <<  8 |
+			  bridge->iobase);
+		break;
+
+	case PCI_MEMORY_BASE:
+		*value = (bridge->memlimit << 16 | bridge->membase);
+		break;
+
+	case PCI_PREF_MEMORY_BASE:
+		*value = (bridge->prefmemlimit << 16 | bridge->prefmembase);
+		break;
+
+	case PCI_PREF_BASE_UPPER32:
+		*value = bridge->prefbaseupper;
+		break;
+
+	case PCI_PREF_LIMIT_UPPER32:
+		*value = bridge->preflimitupper;
+		break;
+
+	case PCI_IO_BASE_UPPER16:
+		*value = (bridge->iolimitupper << 16 | bridge->iobaseupper);
+		break;
+
+	case PCI_ROM_ADDRESS1:
+		*value = 0;
+		break;
+
+	default:
+		*value = 0xffffffff;
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	}
+
+	if (size == 2)
+		*value = (*value >> (8 * (where & 3))) & 0xffff;
+	else if (size == 1)
+		*value = (*value >> (8 * (where & 3))) & 0xff;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/* Write to the PCI-to-PCI bridge configuration space */
+static int mvebu_sw_pci_bridge_write(struct mvebu_pcie_port *port,
+				     unsigned int where, int size, u32 value)
+{
+	struct mvebu_sw_pci_bridge *bridge = &port->bridge;
+	u32 mask, reg;
+	int err;
+
+	if (size == 4)
+		mask = 0x0;
+	else if (size == 2)
+		mask = ~(0xffff << ((where & 3) * 8));
+	else if (size == 1)
+		mask = ~(0xff << ((where & 3) * 8));
+	else
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	err = mvebu_sw_pci_bridge_read(port, where & ~3, 4, &reg);
+	if (err)
+		return err;
+
+	value = (reg & mask) | value << ((where & 3) * 8);
+
+	switch (where & ~3) {
+	case PCI_COMMAND:
+		bridge->command = value & 0xffff;
+		bridge->status = value >> 16;
+		break;
+
+	case PCI_BASE_ADDRESS_0 ... PCI_BASE_ADDRESS_1:
+		bridge->bar[((where & ~3) - PCI_BASE_ADDRESS_0) / 4] = value;
+		break;
+
+	case PCI_IO_BASE:
+		/*
+		 * We also keep bit 1 set, it is a read-only bit that
+		 * indicates we support 32 bits addressing for the
+		 * I/O
+		 */
+		bridge->iobase = (value & 0xff) | PCI_IO_RANGE_TYPE_32;
+		bridge->iolimit = ((value >> 8) & 0xff) | PCI_IO_RANGE_TYPE_32;
+		bridge->secondary_status = value >> 16;
+		mvebu_pcie_handle_iobase_change(port);
+		break;
+
+	case PCI_MEMORY_BASE:
+		bridge->membase = value & 0xffff;
+		bridge->memlimit = value >> 16;
+		mvebu_pcie_handle_membase_change(port);
+		break;
+
+	case PCI_PREF_MEMORY_BASE:
+		bridge->prefmembase = value & 0xffff;
+		bridge->prefmemlimit = value >> 16;
+		break;
+
+	case PCI_PREF_BASE_UPPER32:
+		bridge->prefbaseupper = value;
+		break;
+
+	case PCI_PREF_LIMIT_UPPER32:
+		bridge->preflimitupper = value;
+		break;
+
+	case PCI_IO_BASE_UPPER16:
+		bridge->iobaseupper = value & 0xffff;
+		bridge->iolimitupper = value >> 16;
+		mvebu_pcie_handle_iobase_change(port);
+		break;
+
+	case PCI_PRIMARY_BUS:
+		bridge->primary_bus             = value & 0xff;
+		bridge->secondary_bus           = (value >> 8) & 0xff;
+		bridge->subordinate_bus         = (value >> 16) & 0xff;
+		bridge->secondary_latency_timer = (value >> 24) & 0xff;
+		mvebu_pcie_set_local_bus_nr(port->base, bridge->secondary_bus);
+		break;
+
+	default:
+		break;
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static inline struct mvebu_pcie *sys_to_pcie(struct pci_sys_data *sys)
+{
+	return sys->private_data;
+}
+
+/* Find the PCIe interface that corresponds to the given bus */
+static struct mvebu_pcie_port *mvebu_find_port_from_bus(struct mvebu_pcie *pcie,
+							int bus)
+{
+	int porti;
+
+	for (porti = 0; porti < pcie->nports; porti++)
+		if (pcie->ports[porti].bridge.secondary_bus == bus)
+			return &pcie->ports[porti];
+
+	return NULL;
+}
+
+/* Find the PCIe interface that corresponds to the given devfn */
+static struct mvebu_pcie_port *
+mvebu_find_port_from_devfn(struct mvebu_pcie *pcie, int devfn)
+{
+	int porti;
+
+	for (porti = 0; porti < pcie->nports; porti++)
+		if (pcie->ports[porti].devfn == devfn)
+			return &pcie->ports[porti];
+
+	return NULL;
+}
+
+/* PCI configuration space write function */
+static int mvebu_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
+			      int where, int size, u32 val)
+{
+	struct mvebu_pcie *pcie = sys_to_pcie(bus->sysdata);
+
+	if (bus->number != 0) {
+		/*
+		 * Accessing a real PCIe interface.
+		 */
+		struct mvebu_pcie_port *port;
+		unsigned long flags;
+		int ret;
+
+		port = mvebu_find_port_from_bus(pcie, bus->number);
+		if (!port)
+			return PCIBIOS_DEVICE_NOT_FOUND;
+
+		if (!port->haslink)
+			return PCIBIOS_DEVICE_NOT_FOUND;
+
+		if (PCI_SLOT(devfn) != 0)
+			return PCIBIOS_DEVICE_NOT_FOUND;
+
+		spin_lock_irqsave(&port->conf_lock, flags);
+		ret = mvebu_pcie_hw_wr_conf(port->base, bus,
+					    PCI_DEVFN(1, PCI_FUNC(devfn)),
+					    where, size, val);
+		spin_unlock_irqrestore(&port->conf_lock, flags);
+
+		return ret;
+	} else {
+		/*
+		 * Access the emulated PCI-to-PCI bridges.
+		 */
+		struct mvebu_pcie_port *port;
+		port = mvebu_find_port_from_devfn(pcie, devfn);
+		if (!port)
+			return PCIBIOS_DEVICE_NOT_FOUND;
+
+		return mvebu_sw_pci_bridge_write(port, where, size, val);
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/* PCI configuration space read function */
+static int mvebu_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
+			      int size, u32 *val)
+{
+	struct mvebu_pcie *pcie = sys_to_pcie(bus->sysdata);
+
+	if (bus->number != 0) {
+		/*
+		 * Accessing a real PCIe interface.
+		 */
+		struct mvebu_pcie_port *port;
+		unsigned long flags;
+		int ret;
+
+		port = mvebu_find_port_from_bus(pcie, bus->number);
+		if (!port) {
+			*val = 0xffffffff;
+			return PCIBIOS_DEVICE_NOT_FOUND;
+		}
+
+		if (!port->haslink || PCI_SLOT(devfn) != 0) {
+			*val = 0xffffffff;
+			return PCIBIOS_DEVICE_NOT_FOUND;
+		}
+
+		spin_lock_irqsave(&port->conf_lock, flags);
+		ret = mvebu_pcie_hw_rd_conf(port->base, bus,
+					    PCI_DEVFN(1, PCI_FUNC(devfn)),
+					    where, size, val);
+		spin_unlock_irqrestore(&port->conf_lock, flags);
+
+		return ret;
+	} else {
+		/*
+		 * Access the emulated PCI-to-PCI bridges.
+		 */
+		struct mvebu_pcie_port *port;
+		port = mvebu_find_port_from_devfn(pcie, devfn);
+		if (!port) {
+			*val = 0xffffffff;
+			return PCIBIOS_DEVICE_NOT_FOUND;
+		}
+
+		return mvebu_sw_pci_bridge_read(port, where, size, val);
+	}
+}
+
+static struct pci_ops mvebu_pcie_ops = {
+	.read = mvebu_pcie_rd_conf,
+	.write = mvebu_pcie_wr_conf,
+};
+
+static int __init mvebu_pcie_setup(int nr, struct pci_sys_data *sys)
+{
+	struct mvebu_pcie *pcie = sys_to_pcie(sys);
+	int i;
+
+	pci_add_resource_offset(&sys->resources, &pcie->realio, sys->io_offset);
+	pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset);
+	pci_add_resource(&sys->resources, &pcie->busn);
+
+	for (i = 0; i < pcie->nports; i++) {
+		struct mvebu_pcie_port *port = &pcie->ports[i];
+		mvebu_pcie_setup_hw(port->base);
+	}
+
+	return 1;
+}
+
+static int __init mvebu_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+	struct of_irq oirq;
+	int ret;
+
+	ret = of_irq_map_pci(dev, &oirq);
+	if (ret)
+		return ret;
+
+	return irq_create_of_mapping(oirq.controller, oirq.specifier,
+				     oirq.size);
+}
+
+static struct pci_bus *mvebu_pcie_scan_bus(int nr, struct pci_sys_data *sys)
+{
+	struct mvebu_pcie *pcie = sys_to_pcie(sys);
+	struct pci_bus *bus;
+
+	bus = pci_create_root_bus(&pcie->pdev->dev, sys->busnr,
+				  &mvebu_pcie_ops, sys, &sys->resources);
+	if (!bus)
+		return NULL;
+
+	pci_scan_child_bus(bus);
+
+	return bus;
+}
+
+resource_size_t mvebu_pcie_align_resource(struct pci_dev *dev,
+					  const struct resource *res,
+					  resource_size_t start,
+					  resource_size_t size,
+					  resource_size_t align)
+{
+	if (dev->bus->number != 0)
+		return start;
+
+	/*
+	 * On the PCI-to-PCI bridge side, the I/O windows must have at
+	 * least a 64 KB size and be aligned on their size, and the
+	 * memory windows must have at least a 1 MB size and be
+	 * aligned on their size
+	 */
+	if (res->flags & IORESOURCE_IO)
+		return round_up(start, max((resource_size_t)SZ_64K, size));
+	else if (res->flags & IORESOURCE_MEM)
+		return round_up(start, max((resource_size_t)SZ_1M, size));
+	else
+		return start;
+}
+
+static void mvebu_pcie_enable(struct mvebu_pcie *pcie)
+{
+	struct hw_pci hw;
+
+	memset(&hw, 0, sizeof(hw));
+
+	hw.nr_controllers = 1;
+	hw.private_data   = (void **)&pcie;
+	hw.setup          = mvebu_pcie_setup;
+	hw.scan           = mvebu_pcie_scan_bus;
+	hw.map_irq        = mvebu_pcie_map_irq;
+	hw.ops            = &mvebu_pcie_ops;
+	hw.align_resource = mvebu_pcie_align_resource;
+
+	pci_common_init(&hw);
+}
+
+/*
+ * Looks up the list of register addresses encoded into the reg =
+ * <...> property for one that matches the given port/lane. Once
+ * found, maps it.
+ */
+static void __iomem *mvebu_pcie_map_registers(struct platform_device *pdev,
+					      struct device_node *np,
+					      struct mvebu_pcie_port *port)
+{
+	struct resource regs;
+	int ret = 0;
+
+	ret = of_address_to_resource(np, 0, &regs);
+	if (ret)
+		return NULL;
+
+	return devm_request_and_ioremap(&pdev->dev, &regs);
+}
+
+static int __init mvebu_pcie_probe(struct platform_device *pdev)
+{
+	struct mvebu_pcie *pcie;
+	struct device_node *np = pdev->dev.of_node;
+	struct of_pci_range range;
+	struct of_pci_range_parser parser;
+	struct device_node *child;
+	int i, ret;
+
+	pcie = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_pcie),
+			    GFP_KERNEL);
+	if (!pcie)
+		return -ENOMEM;
+
+	pcie->pdev = pdev;
+
+	if (of_pci_range_parser(&parser, np))
+		return -EINVAL;
+
+	/* Get the I/O and memory ranges from DT */
+	for_each_of_pci_range(&parser, &range) {
+		unsigned long restype = range.flags & IORESOURCE_TYPE_BITS;
+		if (restype == IORESOURCE_IO) {
+			of_pci_range_to_resource(&range, np, &pcie->io);
+			of_pci_range_to_resource(&range, np, &pcie->realio);
+			pcie->io.name = "I/O";
+			pcie->realio.start = PCIBIOS_MIN_IO;
+			pcie->realio.end = min(resource_size(&pcie->io),
+					       IO_SPACE_LIMIT);
+		}
+		if (restype == IORESOURCE_MEM) {
+			of_pci_range_to_resource(&range, np, &pcie->mem);
+			pcie->mem.name = "MEM";
+		}
+	}
+
+	/* Get the bus range */
+	ret = of_pci_parse_bus_range(np, &pcie->busn);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to parse bus-range property: %d\n",
+			ret);
+		return ret;
+	}
+
+	for_each_child_of_node(pdev->dev.of_node, child) {
+		if (!of_device_is_available(child))
+			continue;
+		pcie->nports++;
+	}
+
+	pcie->ports = devm_kzalloc(&pdev->dev, pcie->nports *
+				   sizeof(struct mvebu_pcie_port),
+				   GFP_KERNEL);
+	if (!pcie->ports)
+		return -ENOMEM;
+
+	i = 0;
+	for_each_child_of_node(pdev->dev.of_node, child) {
+		struct mvebu_pcie_port *port = &pcie->ports[i];
+
+		if (!of_device_is_available(child))
+			continue;
+
+		port->pcie = pcie;
+
+		if (of_property_read_u32(child, "marvell,pcie-port",
+					 &port->port)) {
+			dev_warn(&pdev->dev,
+				 "ignoring PCIe DT node, missing pcie-port property\n");
+			continue;
+		}
+
+		if (of_property_read_u32(child, "marvell,pcie-lane",
+					 &port->lane))
+			port->lane = 0;
+
+		port->name = kasprintf(GFP_KERNEL, "pcie%d.%d",
+				       port->port, port->lane);
+
+		port->devfn = of_pci_get_devfn(child);
+		if (port->devfn < 0)
+			continue;
+
+		port->base = mvebu_pcie_map_registers(pdev, child, port);
+		if (!port->base) {
+			dev_err(&pdev->dev, "PCIe%d.%d: cannot map registers\n",
+				port->port, port->lane);
+			continue;
+		}
+
+		if (mvebu_pcie_link_up(port->base)) {
+			port->haslink = 1;
+			dev_info(&pdev->dev, "PCIe%d.%d: link up\n",
+				 port->port, port->lane);
+		} else {
+			port->haslink = 0;
+			dev_info(&pdev->dev, "PCIe%d.%d: link down\n",
+				 port->port, port->lane);
+		}
+
+		port->clk = of_clk_get_by_name(child, NULL);
+		if (!port->clk) {
+			dev_err(&pdev->dev, "PCIe%d.%d: cannot get clock\n",
+			       port->port, port->lane);
+			iounmap(port->base);
+			port->haslink = 0;
+			continue;
+		}
+
+		port->dn = child;
+
+		clk_prepare_enable(port->clk);
+		spin_lock_init(&port->conf_lock);
+
+		mvebu_sw_pci_bridge_init(port);
+
+		i++;
+	}
+
+	mvebu_pcie_enable(pcie);
+
+	return 0;
+}
+
+static const struct of_device_id mvebu_pcie_of_match_table[] = {
+	{ .compatible = "marvell,armada-xp-pcie", },
+	{ .compatible = "marvell,armada-370-pcie", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, mvebu_pcie_of_match_table);
+
+static struct platform_driver mvebu_pcie_driver = {
+	.driver = {
+		.owner = THIS_MODULE,
+		.name = "mvebu-pcie",
+		.of_match_table =
+		   of_match_ptr(mvebu_pcie_of_match_table),
+	},
+};
+
+static int mvebu_pcie_init(void)
+{
+	return platform_driver_probe(&mvebu_pcie_driver,
+				     mvebu_pcie_probe);
+}
+
+subsys_initcall(mvebu_pcie_init);
+
+MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@free-electrons.com>");
+MODULE_DESCRIPTION("Marvell EBU PCIe driver");
+MODULE_LICENSE("GPLv2");
-- 
1.7.9.5

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

* [PATCHv7 09/17] arm: mvebu: PCIe support is now available on mvebu
  2013-03-27 14:40 [PATCHv7 00/17] PCIe support for the Armada 370 and Armada XP SoCs Thomas Petazzoni
                   ` (7 preceding siblings ...)
  2013-03-27 14:40 ` [PATCHv7 08/17] pci: PCIe driver for Marvell Armada 370/XP systems Thomas Petazzoni
@ 2013-03-27 14:40 ` Thomas Petazzoni
  2013-03-27 14:40 ` [PATCHv7 10/17] arm: mvebu: add PCIe Device Tree informations for Armada 370 Thomas Petazzoni
                   ` (10 subsequent siblings)
  19 siblings, 0 replies; 37+ messages in thread
From: Thomas Petazzoni @ 2013-03-27 14:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Grant Likely, Russell King
  Cc: linux-pci, linux-arm-kernel, devicetree-discuss, Lior Amsalem,
	Andrew Lunn, Jason Cooper, Arnd Bergmann, Maen Suleiman,
	Thierry Reding, Gregory Clement, Ezequiel Garcia, Olof Johansson,
	Tawfik Bayouk, Jason Gunthorpe, Mitch Bradley, Andrew Murray

Now that the PCIe driver for mvebu has been integrated and all its
relevant dependencies, we can mark the ARCH_MVEBU platform has
MIGHT_HAVE_PCI, which allows to select the PCI bus support if needed.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
 arch/arm/mach-mvebu/Kconfig |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index c3715a5..d353249 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -14,6 +14,8 @@ config ARCH_MVEBU
 	select MVEBU_CLK_CPU
 	select MVEBU_CLK_GATING
 	select MVEBU_MBUS
+	select MIGHT_HAVE_PCI
+	select PCI_QUIRKS if PCI
 
 if ARCH_MVEBU
 
-- 
1.7.9.5

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

* [PATCHv7 10/17] arm: mvebu: add PCIe Device Tree informations for Armada 370
  2013-03-27 14:40 [PATCHv7 00/17] PCIe support for the Armada 370 and Armada XP SoCs Thomas Petazzoni
                   ` (8 preceding siblings ...)
  2013-03-27 14:40 ` [PATCHv7 09/17] arm: mvebu: PCIe support is now available on mvebu Thomas Petazzoni
@ 2013-03-27 14:40 ` Thomas Petazzoni
  2013-03-27 14:40 ` [PATCHv7 11/17] arm: mvebu: add PCIe Device Tree informations for Armada XP Thomas Petazzoni
                   ` (9 subsequent siblings)
  19 siblings, 0 replies; 37+ messages in thread
From: Thomas Petazzoni @ 2013-03-27 14:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Grant Likely, Russell King
  Cc: linux-pci, linux-arm-kernel, devicetree-discuss, Lior Amsalem,
	Andrew Lunn, Jason Cooper, Arnd Bergmann, Maen Suleiman,
	Thierry Reding, Gregory Clement, Ezequiel Garcia, Olof Johansson,
	Tawfik Bayouk, Jason Gunthorpe, Mitch Bradley, Andrew Murray

The Armada 370 SoC has two 1x PCIe 2.0 interfaces, so we add the
necessary Device Tree informations to make these interfaces availabel.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
 arch/arm/boot/dts/armada-370.dtsi |   51 +++++++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/arch/arm/boot/dts/armada-370.dtsi b/arch/arm/boot/dts/armada-370.dtsi
index 8188d13..2d9f8d6 100644
--- a/arch/arm/boot/dts/armada-370.dtsi
+++ b/arch/arm/boot/dts/armada-370.dtsi
@@ -153,5 +153,56 @@
 			clocks = <&coreclk 0>;
 		};
 
+		pcie-controller {
+			compatible = "marvell,armada-370-pcie";
+			status = "disabled";
+			device_type = "pci";
+
+			#address-cells = <3>;
+			#size-cells = <2>;
+
+			bus-range = <0x00 0xff>;
+
+			reg = <0xd0040000 0x2000>, <0xd0080000 0x2000>;
+
+			reg-names = "pcie0.0", "pcie1.0";
+
+			ranges = <0x82000000 0 0xd0040000 0xd0040000 0 0x00002000   /* Port 0.0 registers */
+				  0x82000000 0 0xd0080000 0xd0080000 0 0x00002000   /* Port 1.0 registers */
+				  0x82000000 0 0xe0000000 0xe0000000 0 0x08000000   /* non-prefetchable memory */
+			          0x81000000 0 0          0xe8000000 0 0x00100000>; /* downstream I/O */
+
+			pcie@1,0 {
+				device_type = "pci";
+				assigned-addresses = <0x82000800 0 0xd0040000 0 0x2000>;
+				reg = <0x0800 0 0 0 0>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				#interrupt-cells = <1>;
+				ranges;
+				interrupt-map-mask = <0 0 0 0>;
+				interrupt-map = <0 0 0 0 &mpic 58>;
+				marvell,pcie-port = <0>;
+				marvell,pcie-lane = <0>;
+				clocks = <&gateclk 5>;
+				status = "disabled";
+			};
+
+			pcie@2,0 {
+				device_type = "pci";
+				assigned-addresses = <0x82002800 0 0xd0080000 0 0x2000>;
+				reg = <0x1000 0 0 0 0>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				#interrupt-cells = <1>;
+				ranges;
+				interrupt-map-mask = <0 0 0 0>;
+				interrupt-map = <0 0 0 0 &mpic 62>;
+				marvell,pcie-port = <1>;
+				marvell,pcie-lane = <0>;
+				clocks = <&gateclk 9>;
+				status = "disabled";
+			};
+		};
 	};
 };
-- 
1.7.9.5

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

* [PATCHv7 11/17] arm: mvebu: add PCIe Device Tree informations for Armada XP
  2013-03-27 14:40 [PATCHv7 00/17] PCIe support for the Armada 370 and Armada XP SoCs Thomas Petazzoni
                   ` (9 preceding siblings ...)
  2013-03-27 14:40 ` [PATCHv7 10/17] arm: mvebu: add PCIe Device Tree informations for Armada 370 Thomas Petazzoni
@ 2013-03-27 14:40 ` Thomas Petazzoni
  2013-03-27 14:40 ` [PATCHv7 12/17] arm: mvebu: PCIe Device Tree informations for OpenBlocks AX3-4 Thomas Petazzoni
                   ` (8 subsequent siblings)
  19 siblings, 0 replies; 37+ messages in thread
From: Thomas Petazzoni @ 2013-03-27 14:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Grant Likely, Russell King
  Cc: linux-pci, linux-arm-kernel, devicetree-discuss, Lior Amsalem,
	Andrew Lunn, Jason Cooper, Arnd Bergmann, Maen Suleiman,
	Thierry Reding, Gregory Clement, Ezequiel Garcia, Olof Johansson,
	Tawfik Bayouk, Jason Gunthorpe, Mitch Bradley, Andrew Murray

The Armada XP SoCs have multiple PCIe interfaces. The MV78230 has 2
PCIe units (one 4x or quad 1x, the other 1x only), the MV78260 has 3
PCIe units (two 4x or quad 1x and one 4x/1x), the MV78460 has 4 PCIe
units (two 4x or quad 1x and two 4x/1x). We therefore add the
necessary Device Tree informations to make those PCIe interfaces
usable.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
 arch/arm/boot/dts/armada-xp-mv78230.dtsi |  104 +++++++++++++++++
 arch/arm/boot/dts/armada-xp-mv78260.dtsi |  122 +++++++++++++++++++
 arch/arm/boot/dts/armada-xp-mv78460.dtsi |  188 ++++++++++++++++++++++++++++++
 3 files changed, 414 insertions(+)

diff --git a/arch/arm/boot/dts/armada-xp-mv78230.dtsi b/arch/arm/boot/dts/armada-xp-mv78230.dtsi
index f56c405..c2c7845 100644
--- a/arch/arm/boot/dts/armada-xp-mv78230.dtsi
+++ b/arch/arm/boot/dts/armada-xp-mv78230.dtsi
@@ -76,5 +76,109 @@
 			#interrupts-cells = <2>;
 			interrupts = <87>, <88>, <89>;
 		};
+
+		/*
+		 * MV78230 has 2 PCIe units Gen2.0: One unit can be
+		 * configured as x4 or quad x1 lanes. One unit is
+		 * x4/x1.
+		 */
+		pcie-controller {
+			compatible = "marvell,armada-xp-pcie";
+			status = "disabled";
+			device_type = "pci";
+
+			#address-cells = <3>;
+			#size-cells = <2>;
+
+			bus-range = <0x00 0xff>;
+
+			ranges = <0x82000000 0 0xd0040000 0xd0040000 0 0x00002000   /* Port 0.0 registers */
+				  0x82000000 0 0xd0042000 0xd0042000 0 0x00002000   /* Port 2.0 registers */
+				  0x82000000 0 0xd0044000 0xd0044000 0 0x00002000   /* Port 0.1 registers */
+				  0x82000000 0 0xd0048000 0xd0048000 0 0x00002000   /* Port 0.2 registers */
+				  0x82000000 0 0xd004c000 0xd004c000 0 0x00002000   /* Port 0.3 registers */
+				  0x82000000 0 0xe0000000 0xe0000000 0 0x08000000   /* non-prefetchable memory */
+				  0x81000000 0 0	  0xe8000000 0 0x00100000>; /* downstream I/O */
+
+			pcie@1,0 {
+				device_type = "pci";
+				assigned-addresses = <0x82000800 0 0xd0040000 0 0x2000>;
+				reg = <0x0800 0 0 0 0>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				#interrupt-cells = <1>;
+				ranges;
+				interrupt-map-mask = <0 0 0 0>;
+				interrupt-map = <0 0 0 0 &mpic 58>;
+				marvell,pcie-port = <0>;
+				marvell,pcie-lane = <0>;
+				clocks = <&gateclk 5>;
+				status = "disabled";
+			};
+
+			pcie@2,0 {
+				device_type = "pci";
+				assigned-addresses = <0x82000800 0 0xd0044000 0 0x2000>;
+				reg = <0x1000 0 0 0 0>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				#interrupt-cells = <1>;
+				ranges;
+				interrupt-map-mask = <0 0 0 0>;
+				interrupt-map = <0 0 0 0 &mpic 59>;
+				marvell,pcie-port = <0>;
+				marvell,pcie-lane = <1>;
+				clocks = <&gateclk 6>;
+				status = "disabled";
+			};
+
+			pcie@3,0 {
+				device_type = "pci";
+				assigned-addresses = <0x82000800 0 0xd0048000 0 0x2000>;
+				reg = <0x1800 0 0 0 0>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				#interrupt-cells = <1>;
+				ranges;
+				interrupt-map-mask = <0 0 0 0>;
+				interrupt-map = <0 0 0 0 &mpic 60>;
+				marvell,pcie-port = <0>;
+				marvell,pcie-lane = <2>;
+				clocks = <&gateclk 7>;
+				status = "disabled";
+			};
+
+			pcie@4,0 {
+				device_type = "pci";
+				assigned-addresses = <0x82000800 0 0xd004c000 0 0x2000>;
+				reg = <0x2000 0 0 0 0>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				#interrupt-cells = <1>;
+				ranges;
+				interrupt-map-mask = <0 0 0 0>;
+				interrupt-map = <0 0 0 0 &mpic 61>;
+				marvell,pcie-port = <0>;
+				marvell,pcie-lane = <3>;
+				clocks = <&gateclk 8>;
+				status = "disabled";
+			};
+
+			pcie@9,0 {
+				device_type = "pci";
+				assigned-addresses = <0x82000800 0 0xd0042000 0 0x2000>;
+				reg = <0x4800 0 0 0 0>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				#interrupt-cells = <1>;
+				ranges;
+				interrupt-map-mask = <0 0 0 0>;
+				interrupt-map = <0 0 0 0 &mpic 99>;
+				marvell,pcie-port = <2>;
+				marvell,pcie-lane = <0>;
+				clocks = <&gateclk 26>;
+				status = "disabled";
+			};
+		};
 	};
 };
diff --git a/arch/arm/boot/dts/armada-xp-mv78260.dtsi b/arch/arm/boot/dts/armada-xp-mv78260.dtsi
index f8f2b78..885bf22 100644
--- a/arch/arm/boot/dts/armada-xp-mv78260.dtsi
+++ b/arch/arm/boot/dts/armada-xp-mv78260.dtsi
@@ -96,5 +96,127 @@
 				clocks = <&gateclk 1>;
 				status = "disabled";
 		};
+
+		/*
+		 * MV78260 has 3 PCIe units Gen2.0: Two units can be
+		 * configured as x4 or quad x1 lanes. One unit is
+		 * x4/x1.
+		 */
+		pcie-controller {
+			compatible = "marvell,armada-xp-pcie";
+			status = "disabled";
+			device_type = "pci";
+
+			#address-cells = <3>;
+			#size-cells = <2>;
+
+			bus-range = <0x00 0xff>;
+
+			ranges = <0x82000000 0 0xd0040000 0xd0040000 0 0x00002000   /* Port 0.0 registers */
+				  0x82000000 0 0xd0042000 0xd0042000 0 0x00002000   /* Port 2.0 registers */
+				  0x82000000 0 0xd0044000 0xd0044000 0 0x00002000   /* Port 0.1 registers */
+				  0x82000000 0 0xd0048000 0xd0048000 0 0x00002000   /* Port 0.2 registers */
+				  0x82000000 0 0xd004c000 0xd004c000 0 0x00002000   /* Port 0.3 registers */
+				  0x82000000 0 0xd0080000 0xd0080000 0 0x00002000   /* Port 1.0 registers */
+				  0x82000000 0 0xd0082000 0xd0082000 0 0x00002000   /* Port 3.0 registers */
+				  0x82000000 0 0xe0000000 0xe0000000 0 0x08000000   /* non-prefetchable memory */
+				  0x81000000 0 0	  0xe8000000 0 0x00100000>; /* downstream I/O */
+
+			pcie@1,0 {
+				device_type = "pci";
+				assigned-addresses = <0x82000800 0 0xd0040000 0 0x2000>;
+				reg = <0x0800 0 0 0 0>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				#interrupt-cells = <1>;
+				ranges;
+				interrupt-map-mask = <0 0 0 0>;
+				interrupt-map = <0 0 0 0 &mpic 58>;
+				marvell,pcie-port = <0>;
+				marvell,pcie-lane = <0>;
+				clocks = <&gateclk 5>;
+				status = "disabled";
+			};
+
+			pcie@2,0 {
+				device_type = "pci";
+				assigned-addresses = <0x82000800 0 0xd0044000 0 0x2000>;
+				reg = <0x1000 0 0 0 0>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				#interrupt-cells = <1>;
+				ranges;
+				interrupt-map-mask = <0 0 0 0>;
+				interrupt-map = <0 0 0 0 &mpic 59>;
+				marvell,pcie-port = <0>;
+				marvell,pcie-lane = <1>;
+				clocks = <&gateclk 6>;
+				status = "disabled";
+			};
+
+			pcie@3,0 {
+				device_type = "pci";
+				assigned-addresses = <0x82000800 0 0xd0048000 0 0x2000>;
+				reg = <0x1800 0 0 0 0>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				#interrupt-cells = <1>;
+				ranges;
+				interrupt-map-mask = <0 0 0 0>;
+				interrupt-map = <0 0 0 0 &mpic 60>;
+				marvell,pcie-port = <0>;
+				marvell,pcie-lane = <2>;
+				clocks = <&gateclk 7>;
+				status = "disabled";
+			};
+
+			pcie@4,0 {
+				device_type = "pci";
+				assigned-addresses = <0x82000800 0 0xd004c000 0 0x2000>;
+				reg = <0x2000 0 0 0 0>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				#interrupt-cells = <1>;
+				ranges;
+				interrupt-map-mask = <0 0 0 0>;
+				interrupt-map = <0 0 0 0 &mpic 61>;
+				marvell,pcie-port = <0>;
+				marvell,pcie-lane = <3>;
+				clocks = <&gateclk 8>;
+				status = "disabled";
+			};
+
+			pcie@9,0 {
+				device_type = "pci";
+				assigned-addresses = <0x82000800 0 0xd0042000 0 0x2000>;
+				reg = <0x4800 0 0 0 0>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				#interrupt-cells = <1>;
+				ranges;
+				interrupt-map-mask = <0 0 0 0>;
+				interrupt-map = <0 0 0 0 &mpic 99>;
+				marvell,pcie-port = <2>;
+				marvell,pcie-lane = <0>;
+				clocks = <&gateclk 26>;
+				status = "disabled";
+			};
+
+			pcie@10,0 {
+				device_type = "pci";
+				assigned-addresses = <0x82000800 0 0xd0082000 0 0x2000>;
+				reg = <0x5000 0 0 0 0>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				#interrupt-cells = <1>;
+				ranges;
+				interrupt-map-mask = <0 0 0 0>;
+				interrupt-map = <0 0 0 0 &mpic 103>;
+				marvell,pcie-port = <3>;
+				marvell,pcie-lane = <0>;
+				clocks = <&gateclk 27>;
+				status = "disabled";
+			};
+		};
 	};
 };
diff --git a/arch/arm/boot/dts/armada-xp-mv78460.dtsi b/arch/arm/boot/dts/armada-xp-mv78460.dtsi
index 936c25d..23a5ac4 100644
--- a/arch/arm/boot/dts/armada-xp-mv78460.dtsi
+++ b/arch/arm/boot/dts/armada-xp-mv78460.dtsi
@@ -111,5 +111,193 @@
 				clocks = <&gateclk 1>;
 				status = "disabled";
 		};
+
+		/*
+		 * MV78460 has 4 PCIe units Gen2.0: Two units can be
+		 * configured as x4 or quad x1 lanes. Two units are
+		 * x4/x1.
+		 */
+		pcie-controller {
+			compatible = "marvell,armada-xp-pcie";
+			status = "disabled";
+			device_type = "pci";
+
+			#address-cells = <3>;
+			#size-cells = <2>;
+
+			bus-range = <0x00 0xff>;
+
+			ranges = <0x82000000 0 0xd0040000 0xd0040000 0 0x00002000   /* Port 0.0 registers */
+				  0x82000000 0 0xd0042000 0xd0042000 0 0x00002000   /* Port 2.0 registers */
+				  0x82000000 0 0xd0044000 0xd0044000 0 0x00002000   /* Port 0.1 registers */
+				  0x82000000 0 0xd0048000 0xd0048000 0 0x00002000   /* Port 0.2 registers */
+				  0x82000000 0 0xd004c000 0xd004c000 0 0x00002000   /* Port 0.3 registers */
+				  0x82000000 0 0xd0080000 0xd0080000 0 0x00002000   /* Port 1.0 registers */
+				  0x82000000 0 0xd0082000 0xd0082000 0 0x00002000   /* Port 3.0 registers */
+				  0x82000000 0 0xd0084000 0xd0084000 0 0x00002000   /* Port 1.1 registers */
+				  0x82000000 0 0xd0088000 0xd0088000 0 0x00002000   /* Port 1.2 registers */
+				  0x82000000 0 0xd008c000 0xd008c000 0 0x00002000   /* Port 1.3 registers */
+				  0x82000000 0 0xe0000000 0xe0000000 0 0x08000000   /* non-prefetchable memory */
+				  0x81000000 0 0	  0xe8000000 0 0x00100000>; /* downstream I/O */
+
+			pcie@1,0 {
+				device_type = "pci";
+				assigned-addresses = <0x82000800 0 0xd0040000 0 0x2000>;
+				reg = <0x0800 0 0 0 0>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				#interrupt-cells = <1>;
+				ranges;
+				interrupt-map-mask = <0 0 0 0>;
+				interrupt-map = <0 0 0 0 &mpic 58>;
+				marvell,pcie-port = <0>;
+				marvell,pcie-lane = <0>;
+				clocks = <&gateclk 5>;
+				status = "disabled";
+			};
+
+			pcie@2,0 {
+				device_type = "pci";
+				assigned-addresses = <0x82001000 0 0xd0044000 0 0x2000>;
+				reg = <0x1000 0 0 0 0>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				#interrupt-cells = <1>;
+				ranges;
+				interrupt-map-mask = <0 0 0 0>;
+				interrupt-map = <0 0 0 0 &mpic 59>;
+				marvell,pcie-port = <0>;
+				marvell,pcie-lane = <1>;
+				clocks = <&gateclk 6>;
+				status = "disabled";
+			};
+
+			pcie@3,0 {
+				device_type = "pci";
+				assigned-addresses = <0x82001800 0 0xd0048000 0 0x2000>;
+				reg = <0x1800 0 0 0 0>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				#interrupt-cells = <1>;
+				ranges;
+				interrupt-map-mask = <0 0 0 0>;
+				interrupt-map = <0 0 0 0 &mpic 60>;
+				marvell,pcie-port = <0>;
+				marvell,pcie-lane = <2>;
+				clocks = <&gateclk 7>;
+				status = "disabled";
+			};
+
+			pcie@4,0 {
+				device_type = "pci";
+				assigned-addresses = <0x82002000 0 0xd004c000 0 0x2000>;
+				reg = <0x2000 0 0 0 0>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				#interrupt-cells = <1>;
+				ranges;
+				interrupt-map-mask = <0 0 0 0>;
+				interrupt-map = <0 0 0 0 &mpic 61>;
+				marvell,pcie-port = <0>;
+				marvell,pcie-lane = <3>;
+				clocks = <&gateclk 8>;
+				status = "disabled";
+			};
+
+			pcie@5,0 {
+				device_type = "pci";
+				assigned-addresses = <0x82002800 0 0xd0080000 0 0x2000>;
+				reg = <0x2800 0 0 0 0>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				#interrupt-cells = <1>;
+				ranges;
+				interrupt-map-mask = <0 0 0 0>;
+				interrupt-map = <0 0 0 0 &mpic 62>;
+				marvell,pcie-port = <1>;
+				marvell,pcie-lane = <0>;
+				clocks = <&gateclk 9>;
+				status = "disabled";
+			};
+
+			pcie@6,0 {
+				device_type = "pci";
+				assigned-addresses = <0x82003000 0 0xd0084000 0 0x2000>;
+				reg = <0x3000 0 0 0 0>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				#interrupt-cells = <1>;
+				ranges;
+				interrupt-map-mask = <0 0 0 0>;
+				interrupt-map = <0 0 0 0 &mpic 63>;
+				marvell,pcie-port = <1>;
+				marvell,pcie-lane = <1>;
+				clocks = <&gateclk 10>;
+				status = "disabled";
+			};
+
+			pcie@7,0 {
+				device_type = "pci";
+				assigned-addresses = <0x82003800 0 0xd0088000 0 0x2000>;
+				reg = <0x3800 0 0 0 0>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				#interrupt-cells = <1>;
+				ranges;
+				interrupt-map-mask = <0 0 0 0>;
+				interrupt-map = <0 0 0 0 &mpic 64>;
+				marvell,pcie-port = <1>;
+				marvell,pcie-lane = <2>;
+				clocks = <&gateclk 11>;
+				status = "disabled";
+			};
+
+			pcie@8,0 {
+				device_type = "pci";
+				assigned-addresses = <0x82004000 0 0xd008c000 0 0x2000>;
+				reg = <0x4000 0 0 0 0>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				#interrupt-cells = <1>;
+				ranges;
+				interrupt-map-mask = <0 0 0 0>;
+				interrupt-map = <0 0 0 0 &mpic 65>;
+				marvell,pcie-port = <1>;
+				marvell,pcie-lane = <3>;
+				clocks = <&gateclk 12>;
+				status = "disabled";
+			};
+			pcie@9,0 {
+				device_type = "pci";
+				assigned-addresses = <0x82004800 0 0xd0042000 0 0x2000>;
+				reg = <0x4800 0 0 0 0>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				#interrupt-cells = <1>;
+				ranges;
+				interrupt-map-mask = <0 0 0 0>;
+				interrupt-map = <0 0 0 0 &mpic 99>;
+				marvell,pcie-port = <2>;
+				marvell,pcie-lane = <0>;
+				clocks = <&gateclk 26>;
+				status = "disabled";
+			};
+
+			pcie@10,0 {
+				device_type = "pci";
+				assigned-addresses = <0x82005000 0 0xd0082000 0 0x2000>;
+				reg = <0x5000 0 0 0 0>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				#interrupt-cells = <1>;
+				ranges;
+				interrupt-map-mask = <0 0 0 0>;
+				interrupt-map = <0 0 0 0 &mpic 103>;
+				marvell,pcie-port = <3>;
+				marvell,pcie-lane = <0>;
+				clocks = <&gateclk 27>;
+				status = "disabled";
+			};
+		};
 	};
  };
-- 
1.7.9.5

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

* [PATCHv7 12/17] arm: mvebu: PCIe Device Tree informations for OpenBlocks AX3-4
  2013-03-27 14:40 [PATCHv7 00/17] PCIe support for the Armada 370 and Armada XP SoCs Thomas Petazzoni
                   ` (10 preceding siblings ...)
  2013-03-27 14:40 ` [PATCHv7 11/17] arm: mvebu: add PCIe Device Tree informations for Armada XP Thomas Petazzoni
@ 2013-03-27 14:40 ` Thomas Petazzoni
  2013-03-27 14:40 ` [PATCHv7 13/17] arm: mvebu: PCIe Device Tree informations for Armada XP DB Thomas Petazzoni
                   ` (7 subsequent siblings)
  19 siblings, 0 replies; 37+ messages in thread
From: Thomas Petazzoni @ 2013-03-27 14:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Grant Likely, Russell King
  Cc: linux-pci, linux-arm-kernel, devicetree-discuss, Lior Amsalem,
	Andrew Lunn, Jason Cooper, Arnd Bergmann, Maen Suleiman,
	Thierry Reding, Gregory Clement, Ezequiel Garcia, Olof Johansson,
	Tawfik Bayouk, Jason Gunthorpe, Mitch Bradley, Andrew Murray

The PlatHome OpenBlocks AX3-4 has an internal mini-PCIe slot that can
be used to plug mini-PCIe devices. We therefore enable the PCIe
interface that corresponds to this slot.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
 arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts |    9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
index 3818a82..5a748bd 100644
--- a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
+++ b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
@@ -139,5 +139,14 @@
 		usb@d0051000 {
 			status = "okay";
 		};
+
+		pcie-controller {
+			status = "okay";
+			/* Internal mini-PCIe connector */
+			pcie@1,0 {
+				/* Port 0, Lane 0 */
+				status = "okay";
+			};
+		};
 	};
 };
-- 
1.7.9.5

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

* [PATCHv7 13/17] arm: mvebu: PCIe Device Tree informations for Armada XP DB
  2013-03-27 14:40 [PATCHv7 00/17] PCIe support for the Armada 370 and Armada XP SoCs Thomas Petazzoni
                   ` (11 preceding siblings ...)
  2013-03-27 14:40 ` [PATCHv7 12/17] arm: mvebu: PCIe Device Tree informations for OpenBlocks AX3-4 Thomas Petazzoni
@ 2013-03-27 14:40 ` Thomas Petazzoni
  2013-03-27 14:40 ` [PATCHv7 14/17] arm: mvebu: PCIe Device Tree informations for Armada 370 Mirabox Thomas Petazzoni
                   ` (6 subsequent siblings)
  19 siblings, 0 replies; 37+ messages in thread
From: Thomas Petazzoni @ 2013-03-27 14:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Grant Likely, Russell King
  Cc: linux-pci, linux-arm-kernel, devicetree-discuss, Lior Amsalem,
	Andrew Lunn, Jason Cooper, Arnd Bergmann, Maen Suleiman,
	Thierry Reding, Gregory Clement, Ezequiel Garcia, Olof Johansson,
	Tawfik Bayouk, Jason Gunthorpe, Mitch Bradley, Andrew Murray

The Marvell evaluation board (DB) for the Armada XP SoC has 6
physicals full-size PCIe slots, so we enable the corresponding PCIe
interfaces in the Device Tree.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
 arch/arm/boot/dts/armada-xp-db.dts |   33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/arch/arm/boot/dts/armada-xp-db.dts b/arch/arm/boot/dts/armada-xp-db.dts
index e83505e..54cc5bb 100644
--- a/arch/arm/boot/dts/armada-xp-db.dts
+++ b/arch/arm/boot/dts/armada-xp-db.dts
@@ -121,5 +121,38 @@
 				spi-max-frequency = <20000000>;
 			};
 		};
+
+		pcie-controller {
+			status = "okay";
+
+			/*
+			 * All 6 slots are physically present as
+			 * standard PCIe slots on the board.
+			 */
+			pcie@1,0 {
+				/* Port 0, Lane 0 */
+				status = "okay";
+			};
+			pcie@2,0 {
+				/* Port 0, Lane 1 */
+				status = "okay";
+			};
+			pcie@3,0 {
+				/* Port 0, Lane 2 */
+				status = "okay";
+			};
+			pcie@4,0 {
+				/* Port 0, Lane 3 */
+				status = "okay";
+			};
+			pcie@9,0 {
+				/* Port 2, Lane 0 */
+				status = "okay";
+			};
+			pcie@10,0 {
+				/* Port 3, Lane 0 */
+				status = "okay";
+			};
+		};
 	};
 };
-- 
1.7.9.5

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

* [PATCHv7 14/17] arm: mvebu: PCIe Device Tree informations for Armada 370 Mirabox
  2013-03-27 14:40 [PATCHv7 00/17] PCIe support for the Armada 370 and Armada XP SoCs Thomas Petazzoni
                   ` (12 preceding siblings ...)
  2013-03-27 14:40 ` [PATCHv7 13/17] arm: mvebu: PCIe Device Tree informations for Armada XP DB Thomas Petazzoni
@ 2013-03-27 14:40 ` Thomas Petazzoni
  2013-03-27 14:40 ` [PATCHv7 15/17] arm: mvebu: PCIe Device Tree informations for Armada 370 DB Thomas Petazzoni
                   ` (5 subsequent siblings)
  19 siblings, 0 replies; 37+ messages in thread
From: Thomas Petazzoni @ 2013-03-27 14:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Grant Likely, Russell King
  Cc: linux-pci, linux-arm-kernel, devicetree-discuss, Lior Amsalem,
	Andrew Lunn, Jason Cooper, Arnd Bergmann, Maen Suleiman,
	Thierry Reding, Gregory Clement, Ezequiel Garcia, Olof Johansson,
	Tawfik Bayouk, Jason Gunthorpe, Mitch Bradley, Andrew Murray

The Globalscale Mirabox platform uses one PCIe interface for an
available mini-PCIe slot, and the other PCIe interface for an internal
USB 3.0 controller. We add the necessary Device Tree informations to
enable those two interfaces.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
 arch/arm/boot/dts/armada-370-mirabox.dts |   16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm/boot/dts/armada-370-mirabox.dts b/arch/arm/boot/dts/armada-370-mirabox.dts
index dd0c57d..5549de6 100644
--- a/arch/arm/boot/dts/armada-370-mirabox.dts
+++ b/arch/arm/boot/dts/armada-370-mirabox.dts
@@ -70,5 +70,21 @@
 		usb@d0051000 {
 			status = "okay";
 		};
+
+		pcie-controller {
+			status = "okay";
+
+			/* Internal mini-PCIe connector */
+			pcie@1,0 {
+				/* Port 0, Lane 0 */
+				status = "okay";
+			};
+
+			/* Connected on the PCB to a USB 3.0 XHCI controller */
+			pcie@2,0 {
+				/* Port 1, Lane 0 */
+				status = "okay";
+			};
+		};
 	};
 };
-- 
1.7.9.5

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

* [PATCHv7 15/17] arm: mvebu: PCIe Device Tree informations for Armada 370 DB
  2013-03-27 14:40 [PATCHv7 00/17] PCIe support for the Armada 370 and Armada XP SoCs Thomas Petazzoni
                   ` (13 preceding siblings ...)
  2013-03-27 14:40 ` [PATCHv7 14/17] arm: mvebu: PCIe Device Tree informations for Armada 370 Mirabox Thomas Petazzoni
@ 2013-03-27 14:40 ` Thomas Petazzoni
  2013-03-27 14:40 ` [PATCHv7 16/17] arm: mvebu: PCIe Device Tree informations for Armada XP GP Thomas Petazzoni
                   ` (4 subsequent siblings)
  19 siblings, 0 replies; 37+ messages in thread
From: Thomas Petazzoni @ 2013-03-27 14:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Grant Likely, Russell King
  Cc: linux-pci, linux-arm-kernel, devicetree-discuss, Lior Amsalem,
	Andrew Lunn, Jason Cooper, Arnd Bergmann, Maen Suleiman,
	Thierry Reding, Gregory Clement, Ezequiel Garcia, Olof Johansson,
	Tawfik Bayouk, Jason Gunthorpe, Mitch Bradley, Andrew Murray

The Marvell evaluation board (DB) for the Armada 370 SoC has 2
physical full-size PCIe slots, so we enable the corresponding PCIe
interfaces in the Device Tree.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
 arch/arm/boot/dts/armada-370-db.dts |   17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/arch/arm/boot/dts/armada-370-db.dts b/arch/arm/boot/dts/armada-370-db.dts
index e34b280..6403acd 100644
--- a/arch/arm/boot/dts/armada-370-db.dts
+++ b/arch/arm/boot/dts/armada-370-db.dts
@@ -94,5 +94,22 @@
 				spi-max-frequency = <50000000>;
 			};
 		};
+
+		pcie-controller {
+			status = "okay";
+			/*
+			 * The two PCIe units are accessible through
+			 * both standard PCIe slots and mini-PCIe
+			 * slots on the board.
+			 */
+			pcie@1,0 {
+				/* Port 0, Lane 0 */
+				status = "okay";
+			};
+			pcie@2,0 {
+				/* Port 1, Lane 0 */
+				status = "okay";
+			};
+		};
 	};
 };
-- 
1.7.9.5

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

* [PATCHv7 16/17] arm: mvebu: PCIe Device Tree informations for Armada XP GP
  2013-03-27 14:40 [PATCHv7 00/17] PCIe support for the Armada 370 and Armada XP SoCs Thomas Petazzoni
                   ` (14 preceding siblings ...)
  2013-03-27 14:40 ` [PATCHv7 15/17] arm: mvebu: PCIe Device Tree informations for Armada 370 DB Thomas Petazzoni
@ 2013-03-27 14:40 ` Thomas Petazzoni
  2013-03-27 14:40 ` [PATCHv7 17/17] arm: mvebu: update defconfig with PCI and USB support Thomas Petazzoni
                   ` (3 subsequent siblings)
  19 siblings, 0 replies; 37+ messages in thread
From: Thomas Petazzoni @ 2013-03-27 14:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Grant Likely, Russell King
  Cc: linux-pci, linux-arm-kernel, devicetree-discuss, Lior Amsalem,
	Andrew Lunn, Jason Cooper, Arnd Bergmann, Maen Suleiman,
	Thierry Reding, Gregory Clement, Ezequiel Garcia, Olof Johansson,
	Tawfik Bayouk, Jason Gunthorpe, Mitch Bradley, Andrew Murray

The Marvell Armada XP GP board has 3 physical full-size PCIe slots, so
we enable the corresponding PCIe interfaces in the Device Tree.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
 arch/arm/boot/dts/armada-xp-gp.dts |   21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/arch/arm/boot/dts/armada-xp-gp.dts b/arch/arm/boot/dts/armada-xp-gp.dts
index 1c8afe2..e2bf6b4 100644
--- a/arch/arm/boot/dts/armada-xp-gp.dts
+++ b/arch/arm/boot/dts/armada-xp-gp.dts
@@ -109,5 +109,26 @@
 				spi-max-frequency = <108000000>;
 			};
 		};
+
+		pcie-controller {
+			status = "okay";
+
+			/*
+			 * The 3 slots are physically present as
+			 * standard PCIe slots on the board.
+			 */
+			pcie@1,0 {
+				/* Port 0, Lane 0 */
+				status = "okay";
+			};
+			pcie@9,0 {
+				/* Port 2, Lane 0 */
+				status = "okay";
+			};
+			pcie@10,0 {
+				/* Port 3, Lane 0 */
+				status = "okay";
+			};
+		};
 	};
 };
-- 
1.7.9.5

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

* [PATCHv7 17/17] arm: mvebu: update defconfig with PCI and USB support
  2013-03-27 14:40 [PATCHv7 00/17] PCIe support for the Armada 370 and Armada XP SoCs Thomas Petazzoni
                   ` (15 preceding siblings ...)
  2013-03-27 14:40 ` [PATCHv7 16/17] arm: mvebu: PCIe Device Tree informations for Armada XP GP Thomas Petazzoni
@ 2013-03-27 14:40 ` Thomas Petazzoni
  2013-03-31  1:05 ` [PATCHv7 00/17] PCIe support for the Armada 370 and Armada XP SoCs Jason Cooper
                   ` (2 subsequent siblings)
  19 siblings, 0 replies; 37+ messages in thread
From: Thomas Petazzoni @ 2013-03-27 14:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Grant Likely, Russell King
  Cc: linux-pci, linux-arm-kernel, devicetree-discuss, Lior Amsalem,
	Andrew Lunn, Jason Cooper, Arnd Bergmann, Maen Suleiman,
	Thierry Reding, Gregory Clement, Ezequiel Garcia, Olof Johansson,
	Tawfik Bayouk, Jason Gunthorpe, Mitch Bradley, Andrew Murray

Now that we have the necessary drivers and Device Tree informations to
support PCIe on Armada 370 and Armada XP, enable the CONFIG_PCI
option.

Also, since the Armada 370 Mirabox has a built-in USB XHCI controller
connected on the PCIe bus, enable the corresponding options as well.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
 arch/arm/configs/mvebu_defconfig |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/configs/mvebu_defconfig b/arch/arm/configs/mvebu_defconfig
index 2ec8119..071a5b1 100644
--- a/arch/arm/configs/mvebu_defconfig
+++ b/arch/arm/configs/mvebu_defconfig
@@ -13,6 +13,8 @@ CONFIG_MACH_ARMADA_370=y
 CONFIG_MACH_ARMADA_XP=y
 # CONFIG_CACHE_L2X0 is not set
 # CONFIG_SWP_EMULATE is not set
+CONFIG_PCI=y
+CONFIG_PCI_MVEBU=y
 CONFIG_SMP=y
 CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
@@ -53,6 +55,7 @@ CONFIG_USB_SUPPORT=y
 CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_XHCI_HCD=y
 CONFIG_MMC=y
 CONFIG_MMC_MVSDIO=y
 CONFIG_NEW_LEDS=y
-- 
1.7.9.5

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

* Re: [PATCHv7 04/17] pci: infrastructure to add drivers in drivers/pci/host
       [not found]     ` <CAAfodu2t4j4ZASzdaKV0QarffXRwMgkMESGy=dDq1oMfTANEeg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2013-03-28  7:24       ` Thomas Petazzoni
  2013-04-08 20:32         ` Bjorn Helgaas
  0 siblings, 1 reply; 37+ messages in thread
From: Thomas Petazzoni @ 2013-03-28  7:24 UTC (permalink / raw)
  To: Neil Greatorex
  Cc: Lior Amsalem, Andrew Lunn, Russell King, Jason Cooper,
	Maen Suleiman, linux-pci-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Andrew Murray,
	Bjorn Helgaas, Tawfik Bayouk, Mitch Bradley,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Jason Gunthorpe

Dear Neil Greatorex,

On Thu, 28 Mar 2013 00:28:02 +0000, Neil Greatorex wrote:

> Surely this patch should include the drivers/pci/host/Makefile or it will
> not build?

Ah, correct. I'll fix that up in the v8. Thank you for noticing!

Best regards,

Thomas
-- 
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* Re: [PATCHv7 00/17] PCIe support for the Armada 370 and Armada XP SoCs
  2013-03-27 14:40 [PATCHv7 00/17] PCIe support for the Armada 370 and Armada XP SoCs Thomas Petazzoni
                   ` (16 preceding siblings ...)
  2013-03-27 14:40 ` [PATCHv7 17/17] arm: mvebu: update defconfig with PCI and USB support Thomas Petazzoni
@ 2013-03-31  1:05 ` Jason Cooper
  2013-04-02 11:36 ` Linus Walleij
  2013-04-03 12:27 ` Thomas Petazzoni
  19 siblings, 0 replies; 37+ messages in thread
From: Jason Cooper @ 2013-03-31  1:05 UTC (permalink / raw)
  To: Thomas Petazzoni, Arnd Bergmann, Olof Johansson, Bjorn Helgaas,
	Grant Likely, Russell King
  Cc: Lior Amsalem, Andrew Lunn, linux-pci, devicetree-discuss,
	Thierry Reding, Jason Gunthorpe, Maen Suleiman, Ezequiel Garcia,
	Gregory Clement, Andrew Murray, Tawfik Bayouk, linux-arm-kernel,
	Mitch Bradley

Thomas, Arnd, Olof, Russell, Grant, Bjorn,

On Wed, Mar 27, 2013 at 03:40:17PM +0100, Thomas Petazzoni wrote:
> Hello,
> 
> This series of patches introduces PCIe support for the Marvell Armada
> 370 and Armada XP. In the future, we plan to extend the driver to
> cover Kirkwood platforms, and possibly other Marvell EBU platforms as
> well.
> 
> As we are approaching 3.10, I would now like to get formal Acked-by,
> or disagreements from the following maintainers/developers :
> 
>  * Grant Likely, as the OF maintainer, for patches 1, 2 and 3
> 
>    [PATCH v5 01/17] of/pci: Provide support for parsing PCI DT ranges
>    [PATCH v5 02/17] of/pci: Add of_pci_get_devfn() function
>    [PATCH v5 03/17] of/pci: Add of_pci_parse_bus_range() function
> 
>  * Bjorn Helgaas, as the PCI maintainer, for patches 4 and 8
> 
>    [PATCH v5 04/17] pci: infrastructure to add drivers in drivers/pci/host
>    [PATCH v5 08/17] pci: PCIe driver for Marvell Armada 370/XP systems
> 
>  * Russell King, as the ARM maintainer, for patch 5
> 
>    [PATCH v5 05/17] arm: pci: add a align_resource hook
> 
>  * Arnd Bergmann, Mitch Bradley and Jason Gunthorpe, for patch 8 (the
>    PCIe driver itself), and specifically the Device Tree binding.
> 
>    [PATCH v5 08/17] pci: PCIe driver for Marvell Armada 370/XP systems

How would you best like to handle this series?  I can take just 9-17
without adding any external dependencies to the arm-soc tree.  Can each
maintainer do the same for each each of the groups above?  I have a
feeling the answer is no, especially with the dependency on
mvebu/cleanup and the mvebu mbus driver currently in my tree.  It's
probably best to keep this series together.  I'd really like to see this
in for v3.10 if at all possible.

Thoughts?

thx,

Jason.

> This patch set depends on:
> 
>  * The arm-soc/mvebu/cleanup branch in Arnd and Olof arm-soc tree
> 
>  * [PATCH v3 for 3.10] Introduce a Marvell EBU MBus driver
>    http://lists.infradead.org/pipermail/linux-arm-kernel/2013-March/156883.html
> 
> For easier testing, the code has been pushed to:
> 
>   git://github.com/MISL-EBU-System-SW/mainline-public.git marvell-pcie-v7
> 
> This PATCHv7 follows:
>  * PATCHv6, sent on March, 26st 2013
>  * PATCHv5, sent on March, 21st 2013
>  * PATCHv4, sent on March, 8th 2013
>  * PATCHv3, sent on February, 12th 2013
>  * PATCHv2, sent on January, 28th 2013
>  * RFCv1, sent on December, 7th 2012
> 
> Changes between v6 and v7:
> 
>  * Use assigned-addresses in the DT subnodes for the MMIO PCIe
>    registers, in order to align with what Thierry is doing on the
>    Tegra PCIe driver.
> 
>  * Added empty 'ranges;' properties in the subnodes, as requested by
>    Arnd. Note that due to this, it is not possible to remove the
>    #address-cells and #size-cells properties from the subnodes, as
>    Jason Gunthorpe requested, otherwise the DT compiler complains with:
> 
>      Warning (ranges_format): /soc/pcie-controller/pcie@1,0 has empty
>      "ranges" property but its #address-cells (2) differs from
>      /soc/pcie-controller (3)
> 
>      Warning (ranges_format): /soc/pcie-controller/pcie@1,0 has empty
>      "ranges" property but its #size-cells (1) differs from
>      /soc/pcie-controller (2)
> 
>  * Use the new RFCv3 patch from Andrew Murray for 'of/pci: Provide
>    support for parsing PCI DT ranges property'.
> 
>  * Updated the DT binding documentation accordingly.
> 
> Changes between v5 and v6:
> 
>  * Use pci_create_root_bus() + pci_scan_child_bus() instead of
>    pci_scan_root_bus(). This is needed to be able to add MSI support
>    later on. Moreover Thierry Reding suggested that
>    pci_scan_root_bus() "does a pci_bus_add_devices(), which is called
>    again in pci_common_init() in the ARM code". Thanks Thierry for
>    pointing out this issue.
> 
> Changes between v4 and v5:
> 
>  * Rebased on top of 3.9-rc2 + the new mvebu-mbus driver (v3).
> 
>  * Changed the names of the PCI DT sub-nodes to match the OF
>    specifications: they should be named pcie@DD,FF where DD is the
>    device number and FF the function number. Requested by Mitch
>    Bradley.
> 
>  * Add the device_type = "pci" property at the pcie-controller
>    level. Requested by Mitch Bradley.
> 
>  * Drop patch 'of/pci: Add of_pci_get_bus() function' because it
>    wasn't actually used in the rest of the patch series.
> 
>  * Updated the patch 'of/pci: Provide support for parsing PCI DT
>    ranges property' to use the latest version proposed by Andrew
>    Murray on the devicetree-discuss@ mailing list.
> 
> Changes between v3 and v4:
> 
>  * Rebased on top of 3.9-rc1.
> 
>  * Drop patch "ARM: pci: Allow passing per-controller private data"
>    because it was merged in 3.9.
> 
>  * Drop patch "lib: devres: don't enclose pcim_*() functions in
>    CONFIG_HAS_IOPORT", because it was merged in 3.9.
> 
>  * Added CONFIG_PCI_MVEBU=y in mvebu_defconfig, so that the right PCI
>    host controller driver is automatically enabled.
> 
>  * Instead of using the DT 'ranges' property to encode the PCIe
>    register ranges, use a 'reg' property on the main PCIe controller
>    DT node together with a 'reg-names' property. Suggested by Jason
>    Gunthorpe.
> 
>  * Don't select PCI_SW_HOST_BRIDGE and PCI_SW_PCI_PCI_BRIDGE, they
>    don't exist anymore. Reported by Bjorn Helgaas.
> 
>  * Added support for the Armada XP GP board.
> 
>  * Fix the 'ranges' property so that the memory range is an identity
>    map between CPU addresses and bus addresses. Suggested by Arnd
>    Bergmann.
> 
>  * Changed the 'ranges' property to have the I/O region after the
>    memory region.
> 
>  * Use the new mvebu-mbus driver API to create/remove address decoding
>    windows when needed. This remove the need to include
>    <mach/addr-map.h>. Requested by Arnd Bergmann.
> 
>  * Include directly into the driver the few common PCIe functions we
>    were using from arch/arm/plat-orion/pcie.c. This allows to remove
>    the inclusion of <plat/pcie.h>. Requested by Arnd Bergmann.
> 
>  * Directly set up the address decoding windows when the memory
>    base/limit and I/O base/limit are configured in the PCI-to-PCI
>    bridge instead of relying on the memory and I/O accesses being
>    enabled in the PCI_COMMAND register. Suggested by Bjorn Helgaas.
> 
>  * Added some comments on top of the calculations of the I/O
>    base/limit and memory base/limit. Suggested by Arnd Bergmann.
> 
>  * Changed a bit the way the "realio" resource is created, from
>    suggestions given by Arnd Bergmann.
> 
>  * Updated the Device Tree binding documentation. Reported by Jason
>    Gunthorpe.
> 
>  * Instead of using "marvell,armada-370-xp-pcie" as the DT compatible
>    string, use two separate compatible strings:
>    "marvell,armada-370-pcie" and "marvell,armada-xp-pcie". For now,
>    the driver does the same thing for both.
> 
> Changes between v2 and v3:
> 
>  * Use of_irq_map_pci() instead of of_irq_map_raw(), as suggested by
>    Andrew Murray. In order to do this, we moved the interrupt-map and
>    interrupt-map-mask DT properties from the main PCIe controller node
>    to the DT subnodes representing each PCIe interface.
> 
>  * Remove the usage of the emulated host bridge.
> 
>  * Move the emulated PCI-to-PCI bridge code into the Marvell PCI
>    driver itself, in order to allow a tighter integration. Suggested
>    by Bjorn Helgaas and Jason Gunthorpe.
> 
>  * Make the allocation of address decoding windows dynamic: it's when
>    memory accesses or I/O accesses are enabled at the PCI-to-PCI
>    bridge level that we allocate and setup the corresponding address
>    decoding window. Requested by Bjorn Helgaas.
> 
>  * Fixed the implementation of I/O accesses to use I/O addresses that
>    fall within the normal IO_SPACE_LIMIT. This required using the
>    "remap" functionality of address decoding windows, and therefore
>    some changes in the address decoding window allocator. Follows a
>    long discussion about I/O accesses.
> 
>  * Set up a correct bus number in the configuration of the PCIe
>    interfaces so that we don't have to fake bus numbers
>    anymore. Requested by Jason Gunthorpe.
> 
>  * Fix the of_pci_get_devfn() implementation according to Stephen
>    Warren's comment.
> 
>  * Use CFLAGS_ instead of ccflags to add the mach-mvebu and plat-orion
>    include paths when building the pci-mvebu driver. This ensures that
>    the include paths are only added when building this specific
>    driver. Requested by Stephen Warren.
> 
>  * Fix the ->resource_align() to only apply on bus 0 (the one on which
>    the emulated PCI-to-PCI bridges sit), and to request an alignment
>    on the size of the window (and not only 64 KB for I/O windows and 1
>    MB for memory windows).
> 
>  * Clarified the commit log of "clk: mvebu: create parent-child
>    relation for PCIe clocks on Armada 370"
> 
> Thanks,
> 
> Thomas
> 
> Andrew Murray (1):
>   of/pci: Provide support for parsing PCI DT ranges property
> 
> Thierry Reding (2):
>   of/pci: Add of_pci_get_devfn() function
>   of/pci: Add of_pci_parse_bus_range() function
> 
> Thomas Petazzoni (14):
>   pci: infrastructure to add drivers in drivers/pci/host
>   arm: pci: add a align_resource hook
>   clk: mvebu: create parent-child relation for PCIe clocks on Armada
>     370
>   clk: mvebu: add more PCIe clocks for Armada XP
>   pci: PCIe driver for Marvell Armada 370/XP systems
>   arm: mvebu: PCIe support is now available on mvebu
>   arm: mvebu: add PCIe Device Tree informations for Armada 370
>   arm: mvebu: add PCIe Device Tree informations for Armada XP
>   arm: mvebu: PCIe Device Tree informations for OpenBlocks AX3-4
>   arm: mvebu: PCIe Device Tree informations for Armada XP DB
>   arm: mvebu: PCIe Device Tree informations for Armada 370 Mirabox
>   arm: mvebu: PCIe Device Tree informations for Armada 370 DB
>   arm: mvebu: PCIe Device Tree informations for Armada XP GP
>   arm: mvebu: update defconfig with PCI and USB support
> 
>  .../devicetree/bindings/pci/mvebu-pci.txt          |  220 +++++
>  arch/arm/boot/dts/armada-370-db.dts                |   17 +
>  arch/arm/boot/dts/armada-370-mirabox.dts           |   16 +
>  arch/arm/boot/dts/armada-370.dtsi                  |   51 ++
>  arch/arm/boot/dts/armada-xp-db.dts                 |   33 +
>  arch/arm/boot/dts/armada-xp-gp.dts                 |   21 +
>  arch/arm/boot/dts/armada-xp-mv78230.dtsi           |  104 +++
>  arch/arm/boot/dts/armada-xp-mv78260.dtsi           |  122 +++
>  arch/arm/boot/dts/armada-xp-mv78460.dtsi           |  188 ++++
>  arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts   |    9 +
>  arch/arm/configs/mvebu_defconfig                   |    3 +
>  arch/arm/include/asm/mach/pci.h                    |   11 +
>  arch/arm/kernel/bios32.c                           |    6 +
>  arch/arm/mach-mvebu/Kconfig                        |    2 +
>  arch/microblaze/pci/pci-common.c                   |  110 +--
>  arch/mips/pci/pci.c                                |   50 +-
>  arch/powerpc/kernel/pci-common.c                   |   99 +--
>  drivers/clk/mvebu/clk-gating-ctrl.c                |   18 +-
>  drivers/of/address.c                               |   63 ++
>  drivers/of/of_pci.c                                |   59 +-
>  drivers/pci/Kconfig                                |    2 +
>  drivers/pci/Makefile                               |    3 +
>  drivers/pci/host/Kconfig                           |    8 +
>  drivers/pci/host/Makefile                          |    4 +
>  drivers/pci/host/pci-mvebu.c                       |  927 ++++++++++++++++++++
>  include/linux/of_address.h                         |   42 +
>  include/linux/of_pci.h                             |    2 +
>  27 files changed, 2009 insertions(+), 181 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/pci/mvebu-pci.txt
>  create mode 100644 drivers/pci/host/Kconfig
>  create mode 100644 drivers/pci/host/Makefile
>  create mode 100644 drivers/pci/host/pci-mvebu.c
> 
> -- 
> 1.7.9.5
> 
> 
> _______________________________________________
> 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] 37+ messages in thread

* Re: [PATCHv7 00/17] PCIe support for the Armada 370 and Armada XP SoCs
  2013-03-27 14:40 [PATCHv7 00/17] PCIe support for the Armada 370 and Armada XP SoCs Thomas Petazzoni
                   ` (17 preceding siblings ...)
  2013-03-31  1:05 ` [PATCHv7 00/17] PCIe support for the Armada 370 and Armada XP SoCs Jason Cooper
@ 2013-04-02 11:36 ` Linus Walleij
  2013-04-03 12:27 ` Thomas Petazzoni
  19 siblings, 0 replies; 37+ messages in thread
From: Linus Walleij @ 2013-04-02 11:36 UTC (permalink / raw)
  To: Thomas Petazzoni, Rob Herring
  Cc: Bjorn Helgaas, Grant Likely, Russell King, Lior Amsalem,
	Andrew Lunn, Jason Cooper, linux-pci, devicetree-discuss,
	Jason Gunthorpe, Maen Suleiman, Andrew Murray, Tawfik Bayouk,
	linux-arm-kernel, Mitch Bradley

On Wed, Mar 27, 2013 at 3:40 PM, Thomas Petazzoni
<thomas.petazzoni@free-electrons.com> wrote:

> As we are approaching 3.10, I would now like to get formal Acked-by,
> or disagreements from the following maintainers/developers :
>
>  * Grant Likely, as the OF maintainer, for patches 1, 2 and 3
>
>    [PATCH v5 01/17] of/pci: Provide support for parsing PCI DT ranges
>    [PATCH v5 02/17] of/pci: Add of_pci_get_devfn() function
>    [PATCH v5 03/17] of/pci: Add of_pci_parse_bus_range() function

I think Rob Herring can help out in reviewing this, as comaintainer
of devicetree stuff.

Yours,
Linus Walleij

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

* Re: [PATCHv7 00/17] PCIe support for the Armada 370 and Armada XP SoCs
  2013-03-27 14:40 [PATCHv7 00/17] PCIe support for the Armada 370 and Armada XP SoCs Thomas Petazzoni
                   ` (18 preceding siblings ...)
  2013-04-02 11:36 ` Linus Walleij
@ 2013-04-03 12:27 ` Thomas Petazzoni
  2013-04-03 16:31   ` Linus Walleij
  19 siblings, 1 reply; 37+ messages in thread
From: Thomas Petazzoni @ 2013-04-03 12:27 UTC (permalink / raw)
  To: Rob Herring, Bjorn Helgaas, Grant Likely, Russell King
  Cc: Lior Amsalem, Andrew Lunn, Jason Cooper, Arnd Bergmann,
	Olof Johansson, linux-pci, devicetree-discuss, Thierry Reding,
	Jason Gunthorpe, Maen Suleiman, Ezequiel Garcia, Gregory Clement,
	Andrew Murray, Tawfik Bayouk, linux-arm-kernel, Mitch Bradley

Bjorn, Rob, Grant, Russell,

Through this e-mail, I'd like to send you a kind reminder about this
patch series. The latest version has been sent a week ago, and there
has been only minor changes requested since v4 sent early March, i.e a
month ago. Therefore, I would hope for this series to enter 3.10.

But this patch set is touching areas you are the maintainer for, so I
would appreciate if you could do a formal review and give your comments
or your Ack. I would especially appreciate if you do so in the very
near future, so that if there are comments, I'll have the time to fix
them and resubmit and updated version in time.

Here are the patches, classified by maintainer area:

 * For Grant Likely and Rob Herring, the drivers/of patches:

   [PATCHv7 01/17] of/pci: Provide support for parsing PCI DT ranges property
   http://lists.infradead.org/pipermail/linux-arm-kernel/2013-March/158556.html

     this patch has been around since 3 months now, and has seen a
     number of iterations, first from Thierry Reding, and then by
     Andrew Murray. It is also used by Thierry Reding's PCIe driver,
     and possibly by the upcoming Exynos PCIe driver as well.

   [PATCHv7 02/17] of/pci: Add of_pci_get_devfn() function
   http://lists.infradead.org/pipermail/linux-arm-kernel/2013-March/158550.html

     this patch has been around since 3 months, with no major change
     since then.

   [PATCHv7 03/17] of/pci: Add of_pci_parse_bus_range() function
   http://lists.infradead.org/pipermail/linux-arm-kernel/2013-March/158551.html

     same thing.

 * For Bjorn Helgaas, the drivers/pci/ patches:

   [PATCHv7 04/17] pci: infrastructure to add drivers in drivers/pci/host
   http://lists.infradead.org/pipermail/linux-arm-kernel/2013-March/158552.html

   [PATCHv7 08/17] pci: PCIe driver for Marvell Armada 370/XP systems
   http://lists.infradead.org/pipermail/linux-arm-kernel/2013-March/158566.html

 * For Russell King, the arch/arm/kernel/ patch:

   [PATCHv7 05/17] arm: pci: add a align_resource hook
   http://lists.infradead.org/pipermail/linux-arm-kernel/2013-March/158553.html

     this patch has been around for more than two months now, and has
     been submitted last week to the patch tracking system, at
     http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=7683/1.

For more details, see the cover letter below, or of course, do not
hesitate to request for additional ones as needed.

Thanks a lot for your support,

Thomas


On Wed, 27 Mar 2013 15:40:17 +0100, Thomas Petazzoni wrote:
> Hello,
> 
> This series of patches introduces PCIe support for the Marvell Armada
> 370 and Armada XP. In the future, we plan to extend the driver to
> cover Kirkwood platforms, and possibly other Marvell EBU platforms as
> well.
> 
> As we are approaching 3.10, I would now like to get formal Acked-by,
> or disagreements from the following maintainers/developers :
> 
>  * Grant Likely, as the OF maintainer, for patches 1, 2 and 3
> 
>    [PATCH v5 01/17] of/pci: Provide support for parsing PCI DT ranges
>    [PATCH v5 02/17] of/pci: Add of_pci_get_devfn() function
>    [PATCH v5 03/17] of/pci: Add of_pci_parse_bus_range() function
> 
>  * Bjorn Helgaas, as the PCI maintainer, for patches 4 and 8
> 
>    [PATCH v5 04/17] pci: infrastructure to add drivers in drivers/pci/host
>    [PATCH v5 08/17] pci: PCIe driver for Marvell Armada 370/XP systems
> 
>  * Russell King, as the ARM maintainer, for patch 5
> 
>    [PATCH v5 05/17] arm: pci: add a align_resource hook
> 
>  * Arnd Bergmann, Mitch Bradley and Jason Gunthorpe, for patch 8 (the
>    PCIe driver itself), and specifically the Device Tree binding.
> 
>    [PATCH v5 08/17] pci: PCIe driver for Marvell Armada 370/XP systems
> 
> This patch set depends on:
> 
>  * The arm-soc/mvebu/cleanup branch in Arnd and Olof arm-soc tree
> 
>  * [PATCH v3 for 3.10] Introduce a Marvell EBU MBus driver
>    http://lists.infradead.org/pipermail/linux-arm-kernel/2013-March/156883.html
> 
> For easier testing, the code has been pushed to:
> 
>   git://github.com/MISL-EBU-System-SW/mainline-public.git marvell-pcie-v7
> 
> This PATCHv7 follows:
>  * PATCHv6, sent on March, 26st 2013
>  * PATCHv5, sent on March, 21st 2013
>  * PATCHv4, sent on March, 8th 2013
>  * PATCHv3, sent on February, 12th 2013
>  * PATCHv2, sent on January, 28th 2013
>  * RFCv1, sent on December, 7th 2012
> 
> Changes between v6 and v7:
> 
>  * Use assigned-addresses in the DT subnodes for the MMIO PCIe
>    registers, in order to align with what Thierry is doing on the
>    Tegra PCIe driver.
> 
>  * Added empty 'ranges;' properties in the subnodes, as requested by
>    Arnd. Note that due to this, it is not possible to remove the
>    #address-cells and #size-cells properties from the subnodes, as
>    Jason Gunthorpe requested, otherwise the DT compiler complains with:
> 
>      Warning (ranges_format): /soc/pcie-controller/pcie@1,0 has empty
>      "ranges" property but its #address-cells (2) differs from
>      /soc/pcie-controller (3)
> 
>      Warning (ranges_format): /soc/pcie-controller/pcie@1,0 has empty
>      "ranges" property but its #size-cells (1) differs from
>      /soc/pcie-controller (2)
> 
>  * Use the new RFCv3 patch from Andrew Murray for 'of/pci: Provide
>    support for parsing PCI DT ranges property'.
> 
>  * Updated the DT binding documentation accordingly.
> 
> Changes between v5 and v6:
> 
>  * Use pci_create_root_bus() + pci_scan_child_bus() instead of
>    pci_scan_root_bus(). This is needed to be able to add MSI support
>    later on. Moreover Thierry Reding suggested that
>    pci_scan_root_bus() "does a pci_bus_add_devices(), which is called
>    again in pci_common_init() in the ARM code". Thanks Thierry for
>    pointing out this issue.
> 
> Changes between v4 and v5:
> 
>  * Rebased on top of 3.9-rc2 + the new mvebu-mbus driver (v3).
> 
>  * Changed the names of the PCI DT sub-nodes to match the OF
>    specifications: they should be named pcie@DD,FF where DD is the
>    device number and FF the function number. Requested by Mitch
>    Bradley.
> 
>  * Add the device_type = "pci" property at the pcie-controller
>    level. Requested by Mitch Bradley.
> 
>  * Drop patch 'of/pci: Add of_pci_get_bus() function' because it
>    wasn't actually used in the rest of the patch series.
> 
>  * Updated the patch 'of/pci: Provide support for parsing PCI DT
>    ranges property' to use the latest version proposed by Andrew
>    Murray on the devicetree-discuss@ mailing list.
> 
> Changes between v3 and v4:
> 
>  * Rebased on top of 3.9-rc1.
> 
>  * Drop patch "ARM: pci: Allow passing per-controller private data"
>    because it was merged in 3.9.
> 
>  * Drop patch "lib: devres: don't enclose pcim_*() functions in
>    CONFIG_HAS_IOPORT", because it was merged in 3.9.
> 
>  * Added CONFIG_PCI_MVEBU=y in mvebu_defconfig, so that the right PCI
>    host controller driver is automatically enabled.
> 
>  * Instead of using the DT 'ranges' property to encode the PCIe
>    register ranges, use a 'reg' property on the main PCIe controller
>    DT node together with a 'reg-names' property. Suggested by Jason
>    Gunthorpe.
> 
>  * Don't select PCI_SW_HOST_BRIDGE and PCI_SW_PCI_PCI_BRIDGE, they
>    don't exist anymore. Reported by Bjorn Helgaas.
> 
>  * Added support for the Armada XP GP board.
> 
>  * Fix the 'ranges' property so that the memory range is an identity
>    map between CPU addresses and bus addresses. Suggested by Arnd
>    Bergmann.
> 
>  * Changed the 'ranges' property to have the I/O region after the
>    memory region.
> 
>  * Use the new mvebu-mbus driver API to create/remove address decoding
>    windows when needed. This remove the need to include
>    <mach/addr-map.h>. Requested by Arnd Bergmann.
> 
>  * Include directly into the driver the few common PCIe functions we
>    were using from arch/arm/plat-orion/pcie.c. This allows to remove
>    the inclusion of <plat/pcie.h>. Requested by Arnd Bergmann.
> 
>  * Directly set up the address decoding windows when the memory
>    base/limit and I/O base/limit are configured in the PCI-to-PCI
>    bridge instead of relying on the memory and I/O accesses being
>    enabled in the PCI_COMMAND register. Suggested by Bjorn Helgaas.
> 
>  * Added some comments on top of the calculations of the I/O
>    base/limit and memory base/limit. Suggested by Arnd Bergmann.
> 
>  * Changed a bit the way the "realio" resource is created, from
>    suggestions given by Arnd Bergmann.
> 
>  * Updated the Device Tree binding documentation. Reported by Jason
>    Gunthorpe.
> 
>  * Instead of using "marvell,armada-370-xp-pcie" as the DT compatible
>    string, use two separate compatible strings:
>    "marvell,armada-370-pcie" and "marvell,armada-xp-pcie". For now,
>    the driver does the same thing for both.
> 
> Changes between v2 and v3:
> 
>  * Use of_irq_map_pci() instead of of_irq_map_raw(), as suggested by
>    Andrew Murray. In order to do this, we moved the interrupt-map and
>    interrupt-map-mask DT properties from the main PCIe controller node
>    to the DT subnodes representing each PCIe interface.
> 
>  * Remove the usage of the emulated host bridge.
> 
>  * Move the emulated PCI-to-PCI bridge code into the Marvell PCI
>    driver itself, in order to allow a tighter integration. Suggested
>    by Bjorn Helgaas and Jason Gunthorpe.
> 
>  * Make the allocation of address decoding windows dynamic: it's when
>    memory accesses or I/O accesses are enabled at the PCI-to-PCI
>    bridge level that we allocate and setup the corresponding address
>    decoding window. Requested by Bjorn Helgaas.
> 
>  * Fixed the implementation of I/O accesses to use I/O addresses that
>    fall within the normal IO_SPACE_LIMIT. This required using the
>    "remap" functionality of address decoding windows, and therefore
>    some changes in the address decoding window allocator. Follows a
>    long discussion about I/O accesses.
> 
>  * Set up a correct bus number in the configuration of the PCIe
>    interfaces so that we don't have to fake bus numbers
>    anymore. Requested by Jason Gunthorpe.
> 
>  * Fix the of_pci_get_devfn() implementation according to Stephen
>    Warren's comment.
> 
>  * Use CFLAGS_ instead of ccflags to add the mach-mvebu and plat-orion
>    include paths when building the pci-mvebu driver. This ensures that
>    the include paths are only added when building this specific
>    driver. Requested by Stephen Warren.
> 
>  * Fix the ->resource_align() to only apply on bus 0 (the one on which
>    the emulated PCI-to-PCI bridges sit), and to request an alignment
>    on the size of the window (and not only 64 KB for I/O windows and 1
>    MB for memory windows).
> 
>  * Clarified the commit log of "clk: mvebu: create parent-child
>    relation for PCIe clocks on Armada 370"
> 
> Thanks,
> 
> Thomas
> 
> Andrew Murray (1):
>   of/pci: Provide support for parsing PCI DT ranges property
> 
> Thierry Reding (2):
>   of/pci: Add of_pci_get_devfn() function
>   of/pci: Add of_pci_parse_bus_range() function
> 
> Thomas Petazzoni (14):
>   pci: infrastructure to add drivers in drivers/pci/host
>   arm: pci: add a align_resource hook
>   clk: mvebu: create parent-child relation for PCIe clocks on Armada
>     370
>   clk: mvebu: add more PCIe clocks for Armada XP
>   pci: PCIe driver for Marvell Armada 370/XP systems
>   arm: mvebu: PCIe support is now available on mvebu
>   arm: mvebu: add PCIe Device Tree informations for Armada 370
>   arm: mvebu: add PCIe Device Tree informations for Armada XP
>   arm: mvebu: PCIe Device Tree informations for OpenBlocks AX3-4
>   arm: mvebu: PCIe Device Tree informations for Armada XP DB
>   arm: mvebu: PCIe Device Tree informations for Armada 370 Mirabox
>   arm: mvebu: PCIe Device Tree informations for Armada 370 DB
>   arm: mvebu: PCIe Device Tree informations for Armada XP GP
>   arm: mvebu: update defconfig with PCI and USB support
> 
>  .../devicetree/bindings/pci/mvebu-pci.txt          |  220 +++++
>  arch/arm/boot/dts/armada-370-db.dts                |   17 +
>  arch/arm/boot/dts/armada-370-mirabox.dts           |   16 +
>  arch/arm/boot/dts/armada-370.dtsi                  |   51 ++
>  arch/arm/boot/dts/armada-xp-db.dts                 |   33 +
>  arch/arm/boot/dts/armada-xp-gp.dts                 |   21 +
>  arch/arm/boot/dts/armada-xp-mv78230.dtsi           |  104 +++
>  arch/arm/boot/dts/armada-xp-mv78260.dtsi           |  122 +++
>  arch/arm/boot/dts/armada-xp-mv78460.dtsi           |  188 ++++
>  arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts   |    9 +
>  arch/arm/configs/mvebu_defconfig                   |    3 +
>  arch/arm/include/asm/mach/pci.h                    |   11 +
>  arch/arm/kernel/bios32.c                           |    6 +
>  arch/arm/mach-mvebu/Kconfig                        |    2 +
>  arch/microblaze/pci/pci-common.c                   |  110 +--
>  arch/mips/pci/pci.c                                |   50 +-
>  arch/powerpc/kernel/pci-common.c                   |   99 +--
>  drivers/clk/mvebu/clk-gating-ctrl.c                |   18 +-
>  drivers/of/address.c                               |   63 ++
>  drivers/of/of_pci.c                                |   59 +-
>  drivers/pci/Kconfig                                |    2 +
>  drivers/pci/Makefile                               |    3 +
>  drivers/pci/host/Kconfig                           |    8 +
>  drivers/pci/host/Makefile                          |    4 +
>  drivers/pci/host/pci-mvebu.c                       |  927 ++++++++++++++++++++
>  include/linux/of_address.h                         |   42 +
>  include/linux/of_pci.h                             |    2 +
>  27 files changed, 2009 insertions(+), 181 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/pci/mvebu-pci.txt
>  create mode 100644 drivers/pci/host/Kconfig
>  create mode 100644 drivers/pci/host/Makefile
>  create mode 100644 drivers/pci/host/pci-mvebu.c
> 



-- 
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* Re: [PATCHv7 00/17] PCIe support for the Armada 370 and Armada XP SoCs
  2013-04-03 12:27 ` Thomas Petazzoni
@ 2013-04-03 16:31   ` Linus Walleij
  0 siblings, 0 replies; 37+ messages in thread
From: Linus Walleij @ 2013-04-03 16:31 UTC (permalink / raw)
  To: Thomas Petazzoni
  Cc: Rob Herring, Bjorn Helgaas, Grant Likely, Russell King,
	Lior Amsalem, Andrew Lunn, Jason Cooper, linux-pci,
	devicetree-discuss@lists.ozlabs.org, Jason Gunthorpe,
	Maen Suleiman, Andrew Murray, Tawfik Bayouk,
	linux-arm-kernel@lists.infradead.org, Mitch Bradley

On Wed, Apr 3, 2013 at 2:27 PM, Thomas Petazzoni
<thomas.petazzoni@free-electrons.com> wrote:

> Bjorn, Rob, Grant, Russell,
>
> Through this e-mail, I'd like to send you a kind reminder about this
> patch series. The latest version has been sent a week ago, and there
> has been only minor changes requested since v4 sent early March, i.e a
> month ago. Therefore, I would hope for this series to enter 3.10.
>
> But this patch set is touching areas you are the maintainer for, so I
> would appreciate if you could do a formal review and give your comments
> or your Ack. I would especially appreciate if you do so in the very
> near future, so that if there are comments, I'll have the time to fix
> them and resubmit and updated version in time.
>
> Here are the patches, classified by maintainer area:

FYI I have applied patches 1 thru 3 and converted my PCI DT series
for the Integrator to use the new infrastructure, so you can add
Tested-by: Linus Walleij <linus.walleij@linaro.org>
on these if you wish. (Working fine.)

The Integrator PCI DT work is dependent on these patches so I
also have a strong interest to have them merged somewhere so I
can submit my series against them...

Yours,
Linus Walleij

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

* Re: [PATCHv7 06/17] clk: mvebu: create parent-child relation for PCIe clocks on Armada 370
  2013-03-27 14:40 ` [PATCHv7 06/17] clk: mvebu: create parent-child relation for PCIe clocks on Armada 370 Thomas Petazzoni
@ 2013-04-05 13:58   ` Thomas Petazzoni
  2013-04-10  8:09   ` Mike Turquette
  1 sibling, 0 replies; 37+ messages in thread
From: Thomas Petazzoni @ 2013-04-05 13:58 UTC (permalink / raw)
  To: Mike Turquette
  Cc: Lior Amsalem, Andrew Lunn, Russell King, Jason Cooper,
	Arnd Bergmann, Maen Suleiman, linux-pci, devicetree-discuss,
	Thierry Reding, Grant Likely, Olof Johansson, Ezequiel Garcia,
	Andrew Murray, Bjorn Helgaas, Gregory Clement, Tawfik Bayouk,
	Mitch Bradley, linux-arm-kernel, Jason Gunthorpe

Mike,

Could we have your opinion on this patch, and possibly a Acked-by to
pass it through arm-soc?

Thanks!

Thomas

On Wed, 27 Mar 2013 15:40:23 +0100, Thomas Petazzoni wrote:
> The Armada 370 has two gatable clocks for each PCIe interface, and we
> want both of them to be enabled. We therefore make one of the two
> clocks a child of the other, as we did for the sataX and sataXlnk
> clocks on Armada XP.
> 
> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
> Cc: Mike Turquette <mturquette@linaro.org>
> ---
>  drivers/clk/mvebu/clk-gating-ctrl.c |    4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/clk/mvebu/clk-gating-ctrl.c b/drivers/clk/mvebu/clk-gating-ctrl.c
> index ebf141d..b35785a 100644
> --- a/drivers/clk/mvebu/clk-gating-ctrl.c
> +++ b/drivers/clk/mvebu/clk-gating-ctrl.c
> @@ -119,8 +119,8 @@ static const struct mvebu_soc_descr __initconst armada_370_gating_descr[] = {
>  	{ "pex1_en", NULL,  2 },
>  	{ "ge1", NULL, 3 },
>  	{ "ge0", NULL, 4 },
> -	{ "pex0", NULL, 5 },
> -	{ "pex1", NULL, 9 },
> +	{ "pex0", "pex0_en", 5 },
> +	{ "pex1", "pex1_en", 9 },
>  	{ "sata0", NULL, 15 },
>  	{ "sdio", NULL, 17 },
>  	{ "tdm", NULL, 25 },



-- 
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* Re: [PATCHv7 07/17] clk: mvebu: add more PCIe clocks for Armada XP
  2013-03-27 14:40 ` [PATCHv7 07/17] clk: mvebu: add more PCIe clocks for Armada XP Thomas Petazzoni
@ 2013-04-05 14:59   ` Thomas Petazzoni
  2013-04-10  8:08   ` Mike Turquette
  1 sibling, 0 replies; 37+ messages in thread
From: Thomas Petazzoni @ 2013-04-05 14:59 UTC (permalink / raw)
  To: Mike Turquette
  Cc: Lior Amsalem, Andrew Lunn, Russell King, Jason Cooper,
	Arnd Bergmann, Maen Suleiman, linux-pci, devicetree-discuss,
	Thierry Reding, Grant Likely, Olof Johansson, Ezequiel Garcia,
	Andrew Murray, Bjorn Helgaas, Gregory Clement, Tawfik Bayouk,
	Mitch Bradley, linux-arm-kernel, Jason Gunthorpe

Mike,

Could we have your opinion on the below patch, and possibly an Acked-by
to carry it through the arm-soc tree?

Thanks,

Thomas

On Wed, 27 Mar 2013 15:40:24 +0100, Thomas Petazzoni wrote:
> The current revision of the datasheet only mentions the gatable clocks
> for the PCIe 0.0, 0.1, 0.2 and 0.3 interfaces, and forgot to mention
> the ones for the PCIe 1.0, 1.1, 1.2, 1.3, 2.0 and 3.0
> interfaces. After confirmation with Marvell engineers, this patch adds
> the missing gatable clocks for those PCIe interfaces.
> 
> It also changes the name of the previously existing PCIe gatable
> clocks, in order to match the naming using the datasheets.
> 
> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
> ---
>  drivers/clk/mvebu/clk-gating-ctrl.c |   14 ++++++++++----
>  1 file changed, 10 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/clk/mvebu/clk-gating-ctrl.c b/drivers/clk/mvebu/clk-gating-ctrl.c
> index b35785a..2f03723 100644
> --- a/drivers/clk/mvebu/clk-gating-ctrl.c
> +++ b/drivers/clk/mvebu/clk-gating-ctrl.c
> @@ -137,10 +137,14 @@ static const struct mvebu_soc_descr __initconst armada_xp_gating_descr[] = {
>  	{ "ge2", NULL,  2 },
>  	{ "ge1", NULL, 3 },
>  	{ "ge0", NULL, 4 },
> -	{ "pex0", NULL, 5 },
> -	{ "pex1", NULL, 6 },
> -	{ "pex2", NULL, 7 },
> -	{ "pex3", NULL, 8 },
> +	{ "pex00", NULL, 5 },
> +	{ "pex01", NULL, 6 },
> +	{ "pex02", NULL, 7 },
> +	{ "pex03", NULL, 8 },
> +	{ "pex10", NULL, 9 },
> +	{ "pex11", NULL, 10 },
> +	{ "pex12", NULL, 11 },
> +	{ "pex13", NULL, 12 },
>  	{ "bp", NULL, 13 },
>  	{ "sata0lnk", NULL, 14 },
>  	{ "sata0", "sata0lnk", 15 },
> @@ -152,6 +156,8 @@ static const struct mvebu_soc_descr __initconst armada_xp_gating_descr[] = {
>  	{ "xor0", NULL, 22 },
>  	{ "crypto", NULL, 23 },
>  	{ "tdm", NULL, 25 },
> +	{ "pex20", NULL, 26 },
> +	{ "pex30", NULL, 27 },
>  	{ "xor1", NULL, 28 },
>  	{ "sata1lnk", NULL, 29 },
>  	{ "sata1", "sata1lnk", 30 },



-- 
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* Re: [PATCHv7 08/17] pci: PCIe driver for Marvell Armada 370/XP systems
  2013-03-27 14:40 ` [PATCHv7 08/17] pci: PCIe driver for Marvell Armada 370/XP systems Thomas Petazzoni
@ 2013-04-08 20:29   ` Bjorn Helgaas
  2013-04-08 20:57     ` Thomas Petazzoni
  2013-04-08 21:31     ` Arnd Bergmann
  0 siblings, 2 replies; 37+ messages in thread
From: Bjorn Helgaas @ 2013-04-08 20:29 UTC (permalink / raw)
  To: Thomas Petazzoni
  Cc: Grant Likely, Russell King, linux-pci@vger.kernel.org, linux-arm,
	devicetree-discuss@lists.ozlabs.org, Lior Amsalem, Andrew Lunn,
	Jason Cooper, Arnd Bergmann, Maen Suleiman, Thierry Reding,
	Gregory Clement, Ezequiel Garcia, Olof Johansson, Tawfik Bayouk,
	Jason Gunthorpe, Mitch Bradley, Andrew Murray

On Wed, Mar 27, 2013 at 8:40 AM, Thomas Petazzoni
<thomas.petazzoni@free-electrons.com> wrote:
> This driver implements the support for the PCIe interfaces on the
> Marvell Armada 370/XP ARM SoCs. In the future, it might be extended to
> cover earlier families of Marvell SoCs, such as Dove, Orion and
> Kirkwood.
>
> The driver implements the hw_pci operations needed by the core ARM PCI
> code to setup PCI devices and get their corresponding IRQs, and the
> pci_ops operations that are used by the PCI core to read/write the
> configuration space of PCI devices.
>
> Since the PCIe interfaces of Marvell SoCs are completely separate and
> not linked together in a bus, this driver sets up an emulated PCI host
> bridge, with one PCI-to-PCI bridge as child for each hardware PCIe
> interface.
>
> In addition, this driver enumerates the different PCIe slots, and for
> those having a device plugged in, it sets up the necessary address
> decoding windows, using the new armada_370_xp_alloc_pcie_window()
> function from mach-mvebu/addr-map.c.
>
> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>

Acked-by: Bjorn Helgaas <bhelgaas@google.com>

A few trivial comments below; it's up to you whether you do anything
with them or not.  It's OK with me if you ignore them :)

The only thing I saw that might be a bug is the resource_size()
question in mvebu_pcie_probe().

Bjorn

> diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
> new file mode 100644
> index 0000000..3ad563f
> --- /dev/null
> +++ b/drivers/pci/host/Makefile
> @@ -0,0 +1,4 @@
> +obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
> +CFLAGS_pci-mvebu.o += \
> +       -I$(srctree)/arch/arm/plat-orion/include \
> +       -I$(srctree)/arch/arm/mach-mvebu/include

Too bad to have to adjust CFLAGS here.  Seems like I remember earlier
discussion, but I didn't pay much attention, and if this is the best
we can do, I guess it's OK.

> diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c
> new file mode 100644
> index 0000000..289babd
> --- /dev/null
> +++ b/drivers/pci/host/pci-mvebu.c
> @@ -0,0 +1,927 @@
> +/*
> + * PCIe driver for Marvell Armada 370 and Armada XP SoCs
> + *
> + * 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/kernel.h>
> +#include <linux/pci.h>
> +#include <linux/clk.h>
> +#include <linux/module.h>
> +#include <linux/mbus.h>
> +#include <linux/slab.h>
> +#include <linux/platform_device.h>
> +#include <linux/of_address.h>
> +#include <linux/of_pci.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_platform.h>
> +
> +/*
> + * PCIe unit register offsets.
> + */
> +#define PCIE_DEV_ID_OFF                0x0000
> +#define PCIE_CMD_OFF           0x0004
> +#define PCIE_DEV_REV_OFF       0x0008
> +#define PCIE_BAR_LO_OFF(n)     (0x0010 + ((n) << 3))
> +#define PCIE_BAR_HI_OFF(n)     (0x0014 + ((n) << 3))
> +#define PCIE_HEADER_LOG_4_OFF  0x0128
> +#define PCIE_BAR_CTRL_OFF(n)   (0x1804 + ((n - 1) * 4))

Strictly speaking, I suppose you should have "(((n) - 1) ..." here.

> +#define PCIE_WIN04_CTRL_OFF(n) (0x1820 + ((n) << 4))
> +#define PCIE_WIN04_BASE_OFF(n) (0x1824 + ((n) << 4))
> +#define PCIE_WIN04_REMAP_OFF(n)        (0x182c + ((n) << 4))
> +#define PCIE_WIN5_CTRL_OFF     0x1880
> +#define PCIE_WIN5_BASE_OFF     0x1884
> +#define PCIE_WIN5_REMAP_OFF    0x188c
> +#define PCIE_CONF_ADDR_OFF     0x18f8
> +#define  PCIE_CONF_ADDR_EN             0x80000000
> +#define  PCIE_CONF_REG(r)              ((((r) & 0xf00) << 16) | ((r) & 0xfc))
> +#define  PCIE_CONF_BUS(b)              (((b) & 0xff) << 16)
> +#define  PCIE_CONF_DEV(d)              (((d) & 0x1f) << 11)
> +#define  PCIE_CONF_FUNC(f)             (((f) & 0x7) << 8)
> +#define PCIE_CONF_DATA_OFF     0x18fc
> +#define PCIE_MASK_OFF          0x1910
> +#define PCIE_CTRL_OFF          0x1a00
> +#define  PCIE_CTRL_X1_MODE             0x0001
> +#define PCIE_STAT_OFF          0x1a04
> +#define  PCIE_STAT_DEV_OFFS            20
> +#define  PCIE_STAT_DEV_MASK            0x1f
> +#define  PCIE_STAT_BUS_OFFS            8
> +#define  PCIE_STAT_BUS_MASK            0xff
> +#define  PCIE_STAT_LINK_DOWN           1

Whoever wrote pci_regs.h came up with a style I kind of like: the bit
masks are already shifted so you can see where they are in the value,
and there are no #defines for the shifts, e.g.,

#define PCI_EXP_FLAGS_TYPE      0x00f0  /* Device/Port type */

The users of PCI_EXP_FLAGS_TYPE just have a bare ">> 4" where
necessary.  It seems like a good compromise that uses only one symbol
(good for grepping), gives good visual indication in the header file
of how the value is laid out, allows clearing bits without shifts, and
clearly shows what's happening at the uses.

But what you have is OK, too :)

> +#define PCIE_DEBUG_CTRL         0x1a60
> +#define  PCIE_DEBUG_SOFT_RESET         (1<<20)
> +
> +/*
> + * This product ID is registered by Marvell, and used when the Marvell
> + * SoC is not the root complex, but an endpoint on the PCIe bus. It is
> + * therefore safe to re-use this PCI ID for our emulated PCI-to-PCI
> + * bridge.
> + */
> +#define MARVELL_EMULATED_PCI_PCI_BRIDGE_ID 0x7846
> +
> +/* PCI configuration space of a PCI-to-PCI bridge */
> +struct mvebu_sw_pci_bridge {
> +       u16 vendor;
> +       u16 device;
> +       u16 command;
> +       u16 status;
> +       u16 class;
> +       u8 interface;
> +       u8 revision;
> +       u8 bist;
> +       u8 header_type;
> +       u8 latency_timer;
> +       u8 cache_line_size;
> +       u32 bar[2];
> +       u8 primary_bus;
> +       u8 secondary_bus;
> +       u8 subordinate_bus;
> +       u8 secondary_latency_timer;
> +       u8 iobase;
> +       u8 iolimit;
> +       u16 secondary_status;
> +       u16 membase;
> +       u16 memlimit;
> +       u16 prefmembase;
> +       u16 prefmemlimit;
> +       u32 prefbaseupper;
> +       u32 preflimitupper;
> +       u16 iobaseupper;
> +       u16 iolimitupper;
> +       u8 cappointer;
> +       u8 reserved1;
> +       u16 reserved2;
> +       u32 romaddr;
> +       u8 intline;
> +       u8 intpin;
> +       u16 bridgectrl;
> +};
> +
> +struct mvebu_pcie_port;
> +
> +/* Structure representing all PCIe interfaces */
> +struct mvebu_pcie {
> +       struct platform_device *pdev;
> +       struct mvebu_pcie_port *ports;
> +       struct resource io;
> +       struct resource realio;
> +       struct resource mem;
> +       struct resource busn;
> +       int nports;
> +};
> +
> +/* Structure representing one PCIe interface */
> +struct mvebu_pcie_port {
> +       char *name;
> +       void __iomem *base;
> +       spinlock_t conf_lock;
> +       int haslink;
> +       u32 port;
> +       u32 lane;
> +       int devfn;
> +       struct clk *clk;
> +       struct mvebu_sw_pci_bridge bridge;
> +       struct device_node *dn;
> +       struct mvebu_pcie *pcie;
> +       phys_addr_t memwin_base;
> +       size_t memwin_size;
> +       phys_addr_t iowin_base;
> +       size_t iowin_size;
> +};
> +
> +static int mvebu_pcie_link_up(void __iomem *base)

This could return bool, I guess.

I think I would make

  mvebu_pcie_link_up()
  mvebu_pcie_set_local_bus_nr()
  mvebu_pcie_setup_wins()
  mvebu_pcie_setup_hw()
  mvebu_pcie_hw_rd_conf()
  mvebu_pcie_hw_wr_conf()

all take a "struct mvebu_pcie_port *port" directly rather than having
the caller pass in "port->base", but maybe you have a reason for doing
otherwise.

> +{
> +       return !(readl(base + PCIE_STAT_OFF) & PCIE_STAT_LINK_DOWN);
> +}
> +
> +static void mvebu_pcie_set_local_bus_nr(void __iomem *base, int nr)
> +{
> +       u32 stat;
> +
> +       stat = readl(base + PCIE_STAT_OFF);
> +       stat &= ~(PCIE_STAT_BUS_MASK << PCIE_STAT_BUS_OFFS);
> +       stat |= nr << PCIE_STAT_BUS_OFFS;
> +       writel(stat, base + PCIE_STAT_OFF);
> +}
> +
> +/*
> + * Setup PCIE BARs and Address Decode Wins:
> + * BAR[0,2] -> disabled, BAR[1] -> covers all DRAM banks
> + * WIN[0-3] -> DRAM bank[0-3]
> + */
> +static void __init mvebu_pcie_setup_wins(void __iomem *base)
> +{
> +       const struct mbus_dram_target_info *dram;
> +       u32 size;
> +       int i;
> +
> +       dram = mv_mbus_dram_info();
> +
> +       /*
> +        * First, disable and clear BARs and windows.
> +        */

Typically single-line comments would be "/* ... */" all on one line.

> +       for (i = 1; i <= 2; i++) {

Interesting use of "i <= 2" rather than the typical "i < 3".

> +               writel(0, base + PCIE_BAR_CTRL_OFF(i));
> +               writel(0, base + PCIE_BAR_LO_OFF(i));
> +               writel(0, base + PCIE_BAR_HI_OFF(i));
> +       }
> +
> +       for (i = 0; i < 5; i++) {
> +               writel(0, base + PCIE_WIN04_CTRL_OFF(i));
> +               writel(0, base + PCIE_WIN04_BASE_OFF(i));
> +               writel(0, base + PCIE_WIN04_REMAP_OFF(i));
> +       }
> +
> +       writel(0, base + PCIE_WIN5_CTRL_OFF);
> +       writel(0, base + PCIE_WIN5_BASE_OFF);
> +       writel(0, base + PCIE_WIN5_REMAP_OFF);
> +
> +       /*
> +        * Setup windows for DDR banks.  Count total DDR size on the fly.
> +        */
> +       size = 0;
> +       for (i = 0; i < dram->num_cs; i++) {
> +               const struct mbus_dram_window *cs = dram->cs + i;
> +
> +               writel(cs->base & 0xffff0000, base + PCIE_WIN04_BASE_OFF(i));
> +               writel(0, base + PCIE_WIN04_REMAP_OFF(i));
> +               writel(((cs->size - 1) & 0xffff0000) |
> +                       (cs->mbus_attr << 8) |
> +                       (dram->mbus_dram_target_id << 4) | 1,
> +                               base + PCIE_WIN04_CTRL_OFF(i));
> +
> +               size += cs->size;
> +       }
> +
> +       /*
> +        * Round up 'size' to the nearest power of two.
> +        */
> +       if ((size & (size - 1)) != 0)
> +               size = 1 << fls(size);
> +
> +       /*
> +        * Setup BAR[1] to all DRAM banks.
> +        */
> +       writel(dram->cs[0].base, base + PCIE_BAR_LO_OFF(1));
> +       writel(0, base + PCIE_BAR_HI_OFF(1));
> +       writel(((size - 1) & 0xffff0000) | 1, base + PCIE_BAR_CTRL_OFF(1));
> +}
> +
> +static void __init mvebu_pcie_setup_hw(void __iomem *base)
> +{
> +       u16 cmd;
> +       u32 mask;
> +
> +       /*
> +        * Point PCIe unit MBUS decode windows to DRAM space.
> +        */
> +       mvebu_pcie_setup_wins(base);
> +
> +       /*
> +        * Master + slave enable.
> +        */
> +       cmd = readw(base + PCIE_CMD_OFF);
> +       cmd |= PCI_COMMAND_IO;
> +       cmd |= PCI_COMMAND_MEMORY;
> +       cmd |= PCI_COMMAND_MASTER;
> +       writew(cmd, base + PCIE_CMD_OFF);
> +
> +       /*
> +        * Enable interrupt lines A-D.
> +        */
> +       mask = readl(base + PCIE_MASK_OFF);
> +       mask |= 0x0f000000;

No #defines for these bits?

> +       writel(mask, base + PCIE_MASK_OFF);
> +}
> +
> +static int mvebu_pcie_hw_rd_conf(void __iomem *base, struct pci_bus *bus,
> +                                u32 devfn, int where, int size, u32 *val)
> +{
> +       writel(PCIE_CONF_BUS(bus->number) |
> +               PCIE_CONF_DEV(PCI_SLOT(devfn)) |
> +               PCIE_CONF_FUNC(PCI_FUNC(devfn)) |
> +               PCIE_CONF_REG(where) | PCIE_CONF_ADDR_EN,

A "PCIE_CONF_ADDR(busnr, devfn, where)" macro would be nice here.

> +                       base + PCIE_CONF_ADDR_OFF);
> +
> +       *val = readl(base + PCIE_CONF_DATA_OFF);
> +
> +       if (size == 1)
> +               *val = (*val >> (8 * (where & 3))) & 0xff;
> +       else if (size == 2)
> +               *val = (*val >> (8 * (where & 3))) & 0xffff;
> +
> +       return PCIBIOS_SUCCESSFUL;
> +}
> +
> +static int mvebu_pcie_hw_wr_conf(void __iomem *base, struct pci_bus *bus,
> +                             u32 devfn, int where, int size, u32 val)
> +{
> +       int ret = PCIBIOS_SUCCESSFUL;
> +
> +       writel(PCIE_CONF_BUS(bus->number) |
> +               PCIE_CONF_DEV(PCI_SLOT(devfn)) |
> +               PCIE_CONF_FUNC(PCI_FUNC(devfn)) |
> +               PCIE_CONF_REG(where) | PCIE_CONF_ADDR_EN,
> +                       base + PCIE_CONF_ADDR_OFF);
> +
> +       if (size == 4)
> +               writel(val, base + PCIE_CONF_DATA_OFF);
> +       else if (size == 2)
> +               writew(val, base + PCIE_CONF_DATA_OFF + (where & 3));
> +       else if (size == 1)
> +               writeb(val, base + PCIE_CONF_DATA_OFF + (where & 3));
> +       else
> +               ret = PCIBIOS_BAD_REGISTER_NUMBER;
> +
> +       return ret;
> +}
> +
> +static void mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port *port)
> +{
> +       phys_addr_t iobase;
> +
> +       /* Are the current iobase/iolimit values invalid? */

I first thought "current ... values" meant "the values before the
change."  If you used "new values" it might be clearer that this is
used to handle *writes* to the window base/size registers, and that
we're looking at the values being written.

> +       if (port->bridge.iolimit < port->bridge.iobase ||
> +           port->bridge.iolimitupper < port->bridge.iobaseupper) {
> +
> +               /* If a window was configured, remove it */
> +               if (port->iowin_base) {
> +                       mvebu_mbus_del_window(port->iowin_base,
> +                                             port->iowin_size);
> +                       port->iowin_base = 0;
> +                       port->iowin_size = 0;
> +               }
> +
> +               return;
> +       }
> +
> +       /*
> +        * We read the PCI-to-PCI bridge emulated registers, and
> +        * calculate the base address and size of the address decoding
> +        * window to setup, according to the PCI-to-PCI bridge
> +        * specifications. iobase is the bus address, port->iowin_base
> +        * is the CPU address.
> +        */
> +       iobase = ((port->bridge.iobase & 0xF0) << 8) |
> +               (port->bridge.iobaseupper << 16);
> +       port->iowin_base = port->pcie->io.start + iobase;
> +       port->iowin_size = ((0xFFF | ((port->bridge.iolimit & 0xF0) << 8) |
> +                           (port->bridge.iolimitupper << 16)) -
> +                           iobase);
> +
> +       mvebu_mbus_add_window_remap_flags(port->name, port->iowin_base,
> +                                         port->iowin_size,
> +                                         iobase,
> +                                         MVEBU_MBUS_PCI_IO);
> +
> +       pci_ioremap_io(iobase, port->iowin_base);
> +}
> +
> +static void mvebu_pcie_handle_membase_change(struct mvebu_pcie_port *port)
> +{
> +       /* Are the current membase/memlimit values invalid? */
> +       if (port->bridge.memlimit < port->bridge.membase) {
> +
> +               /* If a window was configured, remove it */
> +               if (port->memwin_base) {
> +                       mvebu_mbus_del_window(port->memwin_base,
> +                                             port->memwin_size);
> +                       port->memwin_base = 0;
> +                       port->memwin_size = 0;
> +               }
> +
> +               return;
> +       }
> +
> +       /*
> +        * We read the PCI-to-PCI bridge emulated registers, and
> +        * calculate the base address and size of the address decoding
> +        * window to setup, according to the PCI-to-PCI bridge
> +        * specifications.
> +        */
> +       port->memwin_base  = ((port->bridge.membase & 0xFFF0) << 16);
> +       port->memwin_size  =
> +               (((port->bridge.memlimit & 0xFFF0) << 16) | 0xFFFFF) -
> +               port->memwin_base;
> +
> +       mvebu_mbus_add_window_remap_flags(port->name, port->memwin_base,
> +                                         port->memwin_size,
> +                                         MVEBU_MBUS_NO_REMAP,
> +                                         MVEBU_MBUS_PCI_MEM);
> +}
> +
> +/*
> + * Initialize the configuration space of the PCI-to-PCI bridge
> + * associated with the given PCIe interface.
> + */
> +static void mvebu_sw_pci_bridge_init(struct mvebu_pcie_port *port)
> +{
> +       struct mvebu_sw_pci_bridge *bridge = &port->bridge;
> +
> +       memset(bridge, 0, sizeof(struct mvebu_sw_pci_bridge));
> +
> +       bridge->status = PCI_STATUS_CAP_LIST;
> +       bridge->class = PCI_CLASS_BRIDGE_PCI;
> +       bridge->vendor = PCI_VENDOR_ID_MARVELL;
> +       bridge->device = MARVELL_EMULATED_PCI_PCI_BRIDGE_ID;
> +       bridge->header_type = PCI_HEADER_TYPE_BRIDGE;
> +       bridge->cache_line_size = 0x10;
> +
> +       /* We support 32 bits I/O addressing */
> +       bridge->iobase = PCI_IO_RANGE_TYPE_32;
> +       bridge->iolimit = PCI_IO_RANGE_TYPE_32;
> +}
> +
> +/*
> + * Read the configuration space of the PCI-to-PCI bridge associated to
> + * the given PCIe interface.
> + */
> +static int mvebu_sw_pci_bridge_read(struct mvebu_pcie_port *port,
> +                                 unsigned int where, int size, u32 *value)
> +{
> +       struct mvebu_sw_pci_bridge *bridge = &port->bridge;
> +
> +       switch (where & ~3) {
> +       case PCI_VENDOR_ID:
> +               *value = bridge->device << 16 | bridge->vendor;
> +               break;
> +
> +       case PCI_COMMAND:
> +               *value = bridge->status << 16 | bridge->command;
> +               break;
> +
> +       case PCI_CLASS_REVISION:
> +               *value = bridge->class << 16 | bridge->interface << 8 |
> +                        bridge->revision;
> +               break;
> +
> +       case PCI_CACHE_LINE_SIZE:
> +               *value = bridge->bist << 24 | bridge->header_type << 16 |
> +                        bridge->latency_timer << 8 | bridge->cache_line_size;
> +               break;
> +
> +       case PCI_BASE_ADDRESS_0 ... PCI_BASE_ADDRESS_1:
> +               *value = bridge->bar[((where & ~3) - PCI_BASE_ADDRESS_0) / 4];
> +               break;
> +
> +       case PCI_PRIMARY_BUS:
> +               *value = (bridge->secondary_latency_timer << 24 |
> +                         bridge->subordinate_bus         << 16 |
> +                         bridge->secondary_bus           <<  8 |
> +                         bridge->primary_bus);
> +               break;
> +
> +       case PCI_IO_BASE:
> +               *value = (bridge->secondary_status << 16 |
> +                         bridge->iolimit          <<  8 |
> +                         bridge->iobase);
> +               break;
> +
> +       case PCI_MEMORY_BASE:
> +               *value = (bridge->memlimit << 16 | bridge->membase);
> +               break;
> +
> +       case PCI_PREF_MEMORY_BASE:
> +               *value = (bridge->prefmemlimit << 16 | bridge->prefmembase);
> +               break;
> +
> +       case PCI_PREF_BASE_UPPER32:
> +               *value = bridge->prefbaseupper;
> +               break;
> +
> +       case PCI_PREF_LIMIT_UPPER32:
> +               *value = bridge->preflimitupper;
> +               break;
> +
> +       case PCI_IO_BASE_UPPER16:
> +               *value = (bridge->iolimitupper << 16 | bridge->iobaseupper);
> +               break;
> +
> +       case PCI_ROM_ADDRESS1:
> +               *value = 0;
> +               break;
> +
> +       default:
> +               *value = 0xffffffff;
> +               return PCIBIOS_BAD_REGISTER_NUMBER;
> +       }
> +
> +       if (size == 2)
> +               *value = (*value >> (8 * (where & 3))) & 0xffff;
> +       else if (size == 1)
> +               *value = (*value >> (8 * (where & 3))) & 0xff;
> +
> +       return PCIBIOS_SUCCESSFUL;
> +}
> +
> +/* Write to the PCI-to-PCI bridge configuration space */
> +static int mvebu_sw_pci_bridge_write(struct mvebu_pcie_port *port,
> +                                    unsigned int where, int size, u32 value)
> +{
> +       struct mvebu_sw_pci_bridge *bridge = &port->bridge;
> +       u32 mask, reg;
> +       int err;
> +
> +       if (size == 4)
> +               mask = 0x0;
> +       else if (size == 2)
> +               mask = ~(0xffff << ((where & 3) * 8));
> +       else if (size == 1)
> +               mask = ~(0xff << ((where & 3) * 8));
> +       else
> +               return PCIBIOS_BAD_REGISTER_NUMBER;
> +
> +       err = mvebu_sw_pci_bridge_read(port, where & ~3, 4, &reg);
> +       if (err)
> +               return err;
> +
> +       value = (reg & mask) | value << ((where & 3) * 8);
> +
> +       switch (where & ~3) {
> +       case PCI_COMMAND:
> +               bridge->command = value & 0xffff;
> +               bridge->status = value >> 16;
> +               break;
> +
> +       case PCI_BASE_ADDRESS_0 ... PCI_BASE_ADDRESS_1:
> +               bridge->bar[((where & ~3) - PCI_BASE_ADDRESS_0) / 4] = value;
> +               break;
> +
> +       case PCI_IO_BASE:
> +               /*
> +                * We also keep bit 1 set, it is a read-only bit that
> +                * indicates we support 32 bits addressing for the
> +                * I/O
> +                */
> +               bridge->iobase = (value & 0xff) | PCI_IO_RANGE_TYPE_32;
> +               bridge->iolimit = ((value >> 8) & 0xff) | PCI_IO_RANGE_TYPE_32;
> +               bridge->secondary_status = value >> 16;
> +               mvebu_pcie_handle_iobase_change(port);
> +               break;
> +
> +       case PCI_MEMORY_BASE:
> +               bridge->membase = value & 0xffff;
> +               bridge->memlimit = value >> 16;
> +               mvebu_pcie_handle_membase_change(port);
> +               break;
> +
> +       case PCI_PREF_MEMORY_BASE:
> +               bridge->prefmembase = value & 0xffff;
> +               bridge->prefmemlimit = value >> 16;
> +               break;
> +
> +       case PCI_PREF_BASE_UPPER32:
> +               bridge->prefbaseupper = value;
> +               break;
> +
> +       case PCI_PREF_LIMIT_UPPER32:
> +               bridge->preflimitupper = value;
> +               break;
> +
> +       case PCI_IO_BASE_UPPER16:
> +               bridge->iobaseupper = value & 0xffff;
> +               bridge->iolimitupper = value >> 16;
> +               mvebu_pcie_handle_iobase_change(port);
> +               break;
> +
> +       case PCI_PRIMARY_BUS:
> +               bridge->primary_bus             = value & 0xff;
> +               bridge->secondary_bus           = (value >> 8) & 0xff;
> +               bridge->subordinate_bus         = (value >> 16) & 0xff;
> +               bridge->secondary_latency_timer = (value >> 24) & 0xff;
> +               mvebu_pcie_set_local_bus_nr(port->base, bridge->secondary_bus);
> +               break;
> +
> +       default:
> +               break;
> +       }
> +
> +       return PCIBIOS_SUCCESSFUL;
> +}
> +
> +static inline struct mvebu_pcie *sys_to_pcie(struct pci_sys_data *sys)
> +{
> +       return sys->private_data;
> +}
> +
> +/* Find the PCIe interface that corresponds to the given bus */
> +static struct mvebu_pcie_port *mvebu_find_port_from_bus(struct mvebu_pcie *pcie,
> +                                                       int bus)
> +{
> +       int porti;
> +
> +       for (porti = 0; porti < pcie->nports; porti++)
> +               if (pcie->ports[porti].bridge.secondary_bus == bus)
> +                       return &pcie->ports[porti];
> +
> +       return NULL;
> +}
> +
> +/* Find the PCIe interface that corresponds to the given devfn */
> +static struct mvebu_pcie_port *
> +mvebu_find_port_from_devfn(struct mvebu_pcie *pcie, int devfn)
> +{
> +       int porti;
> +
> +       for (porti = 0; porti < pcie->nports; porti++)
> +               if (pcie->ports[porti].devfn == devfn)
> +                       return &pcie->ports[porti];
> +
> +       return NULL;
> +}
> +
> +/* PCI configuration space write function */
> +static int mvebu_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
> +                             int where, int size, u32 val)
> +{
> +       struct mvebu_pcie *pcie = sys_to_pcie(bus->sysdata);
> +
> +       if (bus->number != 0) {
> +               /*
> +                * Accessing a real PCIe interface.
> +                */
> +               struct mvebu_pcie_port *port;
> +               unsigned long flags;
> +               int ret;
> +
> +               port = mvebu_find_port_from_bus(pcie, bus->number);
> +               if (!port)
> +                       return PCIBIOS_DEVICE_NOT_FOUND;
> +
> +               if (!port->haslink)
> +                       return PCIBIOS_DEVICE_NOT_FOUND;
> +
> +               if (PCI_SLOT(devfn) != 0)
> +                       return PCIBIOS_DEVICE_NOT_FOUND;
> +
> +               spin_lock_irqsave(&port->conf_lock, flags);
> +               ret = mvebu_pcie_hw_wr_conf(port->base, bus,
> +                                           PCI_DEVFN(1, PCI_FUNC(devfn)),
> +                                           where, size, val);
> +               spin_unlock_irqrestore(&port->conf_lock, flags);
> +
> +               return ret;
> +       } else {
> +               /*
> +                * Access the emulated PCI-to-PCI bridges.
> +                */
> +               struct mvebu_pcie_port *port;
> +               port = mvebu_find_port_from_devfn(pcie, devfn);
> +               if (!port)
> +                       return PCIBIOS_DEVICE_NOT_FOUND;
> +
> +               return mvebu_sw_pci_bridge_write(port, where, size, val);
> +       }
> +
> +       return PCIBIOS_SUCCESSFUL;

This last "return" is unreachable (I see you omitted it from the
rd_conf() path already :)).  This would be slightly simpler as:

  static struct mvebu_pcie_port *mvebu_find_port(struct mvebu_pcie *pcie,
      struct pci_bus *bus, int devfn)
  {
    int i;

    for (i = 0; i < pcie->nports; i++) {
      if ((bus->number == 0 && pcie->ports[i].devfn == devfn) ||
          (pcie->ports[porti].bridge.secondary_bus == bus->number))
        return &pcie->ports[i];
    }
    return NULL;
  }

  static int mvebu_pcie_wr_conf(struct pci_bus *bus, ...)
  {
    port = mvebu_find_port(pcie, bus, devfn);
    if (!port)
      return PCIBIOS_DEVICE_NOT_FOUND;

    if (bus->number == 0)
      return mvebu_sw_pci_bridge_write(port, where, size, val);

    if (!port->haslink || PCI_SLOT(devfn) != 0)
      return PCIBIOS_DEVICE_NOT_FOUND;

    ...
    return ret;
  }


> +}
> +
> +/* PCI configuration space read function */
> +static int mvebu_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
> +                             int size, u32 *val)
> +{
> +       struct mvebu_pcie *pcie = sys_to_pcie(bus->sysdata);
> +
> +       if (bus->number != 0) {
> +               /*
> +                * Accessing a real PCIe interface.
> +                */
> +               struct mvebu_pcie_port *port;
> +               unsigned long flags;
> +               int ret;
> +
> +               port = mvebu_find_port_from_bus(pcie, bus->number);
> +               if (!port) {
> +                       *val = 0xffffffff;
> +                       return PCIBIOS_DEVICE_NOT_FOUND;
> +               }
> +
> +               if (!port->haslink || PCI_SLOT(devfn) != 0) {
> +                       *val = 0xffffffff;
> +                       return PCIBIOS_DEVICE_NOT_FOUND;
> +               }
> +
> +               spin_lock_irqsave(&port->conf_lock, flags);
> +               ret = mvebu_pcie_hw_rd_conf(port->base, bus,
> +                                           PCI_DEVFN(1, PCI_FUNC(devfn)),
> +                                           where, size, val);
> +               spin_unlock_irqrestore(&port->conf_lock, flags);
> +
> +               return ret;
> +       } else {
> +               /*
> +                * Access the emulated PCI-to-PCI bridges.
> +                */
> +               struct mvebu_pcie_port *port;
> +               port = mvebu_find_port_from_devfn(pcie, devfn);
> +               if (!port) {
> +                       *val = 0xffffffff;
> +                       return PCIBIOS_DEVICE_NOT_FOUND;
> +               }
> +
> +               return mvebu_sw_pci_bridge_read(port, where, size, val);
> +       }
> +}
> +
> +static struct pci_ops mvebu_pcie_ops = {
> +       .read = mvebu_pcie_rd_conf,
> +       .write = mvebu_pcie_wr_conf,
> +};
> +
> +static int __init mvebu_pcie_setup(int nr, struct pci_sys_data *sys)
> +{
> +       struct mvebu_pcie *pcie = sys_to_pcie(sys);
> +       int i;
> +
> +       pci_add_resource_offset(&sys->resources, &pcie->realio, sys->io_offset);
> +       pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset);
> +       pci_add_resource(&sys->resources, &pcie->busn);
> +
> +       for (i = 0; i < pcie->nports; i++) {
> +               struct mvebu_pcie_port *port = &pcie->ports[i];
> +               mvebu_pcie_setup_hw(port->base);
> +       }
> +
> +       return 1;
> +}
> +
> +static int __init mvebu_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
> +{
> +       struct of_irq oirq;
> +       int ret;
> +
> +       ret = of_irq_map_pci(dev, &oirq);
> +       if (ret)
> +               return ret;
> +
> +       return irq_create_of_mapping(oirq.controller, oirq.specifier,
> +                                    oirq.size);
> +}
> +
> +static struct pci_bus *mvebu_pcie_scan_bus(int nr, struct pci_sys_data *sys)
> +{
> +       struct mvebu_pcie *pcie = sys_to_pcie(sys);
> +       struct pci_bus *bus;
> +
> +       bus = pci_create_root_bus(&pcie->pdev->dev, sys->busnr,
> +                                 &mvebu_pcie_ops, sys, &sys->resources);
> +       if (!bus)
> +               return NULL;
> +
> +       pci_scan_child_bus(bus);
> +
> +       return bus;
> +}
> +
> +resource_size_t mvebu_pcie_align_resource(struct pci_dev *dev,
> +                                         const struct resource *res,
> +                                         resource_size_t start,
> +                                         resource_size_t size,
> +                                         resource_size_t align)
> +{
> +       if (dev->bus->number != 0)
> +               return start;
> +
> +       /*
> +        * On the PCI-to-PCI bridge side, the I/O windows must have at
> +        * least a 64 KB size and be aligned on their size, and the
> +        * memory windows must have at least a 1 MB size and be
> +        * aligned on their size
> +        */
> +       if (res->flags & IORESOURCE_IO)
> +               return round_up(start, max((resource_size_t)SZ_64K, size));
> +       else if (res->flags & IORESOURCE_MEM)
> +               return round_up(start, max((resource_size_t)SZ_1M, size));
> +       else
> +               return start;
> +}
> +
> +static void mvebu_pcie_enable(struct mvebu_pcie *pcie)
> +{
> +       struct hw_pci hw;
> +
> +       memset(&hw, 0, sizeof(hw));
> +
> +       hw.nr_controllers = 1;
> +       hw.private_data   = (void **)&pcie;
> +       hw.setup          = mvebu_pcie_setup;
> +       hw.scan           = mvebu_pcie_scan_bus;
> +       hw.map_irq        = mvebu_pcie_map_irq;
> +       hw.ops            = &mvebu_pcie_ops;
> +       hw.align_resource = mvebu_pcie_align_resource;
> +
> +       pci_common_init(&hw);
> +}
> +
> +/*
> + * Looks up the list of register addresses encoded into the reg =
> + * <...> property for one that matches the given port/lane. Once
> + * found, maps it.
> + */
> +static void __iomem *mvebu_pcie_map_registers(struct platform_device *pdev,
> +                                             struct device_node *np,
> +                                             struct mvebu_pcie_port *port)
> +{
> +       struct resource regs;
> +       int ret = 0;
> +
> +       ret = of_address_to_resource(np, 0, &regs);
> +       if (ret)
> +               return NULL;
> +
> +       return devm_request_and_ioremap(&pdev->dev, &regs);
> +}
> +
> +static int __init mvebu_pcie_probe(struct platform_device *pdev)
> +{
> +       struct mvebu_pcie *pcie;
> +       struct device_node *np = pdev->dev.of_node;
> +       struct of_pci_range range;
> +       struct of_pci_range_parser parser;
> +       struct device_node *child;
> +       int i, ret;
> +
> +       pcie = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_pcie),
> +                           GFP_KERNEL);
> +       if (!pcie)
> +               return -ENOMEM;
> +
> +       pcie->pdev = pdev;
> +
> +       if (of_pci_range_parser(&parser, np))
> +               return -EINVAL;
> +
> +       /* Get the I/O and memory ranges from DT */
> +       for_each_of_pci_range(&parser, &range) {
> +               unsigned long restype = range.flags & IORESOURCE_TYPE_BITS;
> +               if (restype == IORESOURCE_IO) {
> +                       of_pci_range_to_resource(&range, np, &pcie->io);
> +                       of_pci_range_to_resource(&range, np, &pcie->realio);
> +                       pcie->io.name = "I/O";
> +                       pcie->realio.start = PCIBIOS_MIN_IO;
> +                       pcie->realio.end = min(resource_size(&pcie->io),
> +                                              IO_SPACE_LIMIT);

Using "resource_size(&pcie->io)" here seems strange -- are you
assuming that pcie->io starts at address zero?

> +               }
> +               if (restype == IORESOURCE_MEM) {
> +                       of_pci_range_to_resource(&range, np, &pcie->mem);
> +                       pcie->mem.name = "MEM";
> +               }
> +       }
> +
> +       /* Get the bus range */
> +       ret = of_pci_parse_bus_range(np, &pcie->busn);
> +       if (ret) {
> +               dev_err(&pdev->dev, "failed to parse bus-range property: %d\n",
> +                       ret);
> +               return ret;
> +       }
> +
> +       for_each_child_of_node(pdev->dev.of_node, child) {
> +               if (!of_device_is_available(child))
> +                       continue;
> +               pcie->nports++;
> +       }
> +
> +       pcie->ports = devm_kzalloc(&pdev->dev, pcie->nports *
> +                                  sizeof(struct mvebu_pcie_port),
> +                                  GFP_KERNEL);
> +       if (!pcie->ports)
> +               return -ENOMEM;
> +
> +       i = 0;
> +       for_each_child_of_node(pdev->dev.of_node, child) {
> +               struct mvebu_pcie_port *port = &pcie->ports[i];
> +
> +               if (!of_device_is_available(child))
> +                       continue;
> +
> +               port->pcie = pcie;
> +
> +               if (of_property_read_u32(child, "marvell,pcie-port",
> +                                        &port->port)) {
> +                       dev_warn(&pdev->dev,
> +                                "ignoring PCIe DT node, missing pcie-port property\n");
> +                       continue;
> +               }
> +
> +               if (of_property_read_u32(child, "marvell,pcie-lane",
> +                                        &port->lane))
> +                       port->lane = 0;
> +
> +               port->name = kasprintf(GFP_KERNEL, "pcie%d.%d",
> +                                      port->port, port->lane);
> +
> +               port->devfn = of_pci_get_devfn(child);
> +               if (port->devfn < 0)
> +                       continue;
> +
> +               port->base = mvebu_pcie_map_registers(pdev, child, port);
> +               if (!port->base) {
> +                       dev_err(&pdev->dev, "PCIe%d.%d: cannot map registers\n",
> +                               port->port, port->lane);
> +                       continue;
> +               }
> +
> +               if (mvebu_pcie_link_up(port->base)) {
> +                       port->haslink = 1;
> +                       dev_info(&pdev->dev, "PCIe%d.%d: link up\n",
> +                                port->port, port->lane);
> +               } else {
> +                       port->haslink = 0;
> +                       dev_info(&pdev->dev, "PCIe%d.%d: link down\n",
> +                                port->port, port->lane);
> +               }
> +
> +               port->clk = of_clk_get_by_name(child, NULL);
> +               if (!port->clk) {
> +                       dev_err(&pdev->dev, "PCIe%d.%d: cannot get clock\n",
> +                              port->port, port->lane);
> +                       iounmap(port->base);
> +                       port->haslink = 0;
> +                       continue;
> +               }
> +
> +               port->dn = child;
> +
> +               clk_prepare_enable(port->clk);
> +               spin_lock_init(&port->conf_lock);
> +
> +               mvebu_sw_pci_bridge_init(port);
> +
> +               i++;
> +       }
> +
> +       mvebu_pcie_enable(pcie);
> +
> +       return 0;
> +}
> +
> +static const struct of_device_id mvebu_pcie_of_match_table[] = {
> +       { .compatible = "marvell,armada-xp-pcie", },
> +       { .compatible = "marvell,armada-370-pcie", },
> +       {},
> +};
> +MODULE_DEVICE_TABLE(of, mvebu_pcie_of_match_table);
> +
> +static struct platform_driver mvebu_pcie_driver = {
> +       .driver = {
> +               .owner = THIS_MODULE,
> +               .name = "mvebu-pcie",
> +               .of_match_table =
> +                  of_match_ptr(mvebu_pcie_of_match_table),
> +       },
> +};
> +
> +static int mvebu_pcie_init(void)
> +{
> +       return platform_driver_probe(&mvebu_pcie_driver,
> +                                    mvebu_pcie_probe);
> +}
> +
> +subsys_initcall(mvebu_pcie_init);
> +
> +MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@free-electrons.com>");
> +MODULE_DESCRIPTION("Marvell EBU PCIe driver");
> +MODULE_LICENSE("GPLv2");
> --
> 1.7.9.5
>

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

* Re: [PATCHv7 04/17] pci: infrastructure to add drivers in drivers/pci/host
  2013-03-28  7:24       ` Thomas Petazzoni
@ 2013-04-08 20:32         ` Bjorn Helgaas
  0 siblings, 0 replies; 37+ messages in thread
From: Bjorn Helgaas @ 2013-04-08 20:32 UTC (permalink / raw)
  To: Thomas Petazzoni
  Cc: Neil Greatorex, Grant Likely, Russell King, Lior Amsalem,
	Andrew Lunn, Jason Cooper, Arnd Bergmann, Olof Johansson,
	linux-pci@vger.kernel.org, devicetree-discuss@lists.ozlabs.org,
	Thierry Reding, Jason Gunthorpe, Maen Suleiman, Ezequiel Garcia,
	Gregory Clement, Andrew Murray, Tawfik Bayouk, linux-arm,
	Mitch Bradley

On Thu, Mar 28, 2013 at 1:24 AM, Thomas Petazzoni
<thomas.petazzoni@free-electrons.com> wrote:
> Dear Neil Greatorex,
>
> On Thu, 28 Mar 2013 00:28:02 +0000, Neil Greatorex wrote:
>
>> Surely this patch should include the drivers/pci/host/Makefile or it will
>> not build?
>
> Ah, correct. I'll fix that up in the v8. Thank you for noticing!

With the fix, looks OK to me.

Bjorn

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

* Re: [PATCHv7 08/17] pci: PCIe driver for Marvell Armada 370/XP systems
  2013-04-08 20:29   ` Bjorn Helgaas
@ 2013-04-08 20:57     ` Thomas Petazzoni
  2013-04-08 21:34       ` Arnd Bergmann
  2013-04-08 21:31     ` Arnd Bergmann
  1 sibling, 1 reply; 37+ messages in thread
From: Thomas Petazzoni @ 2013-04-08 20:57 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Grant Likely, Russell King, linux-pci@vger.kernel.org, linux-arm,
	devicetree-discuss@lists.ozlabs.org, Lior Amsalem, Andrew Lunn,
	Jason Cooper, Arnd Bergmann, Maen Suleiman, Thierry Reding,
	Gregory Clement, Ezequiel Garcia, Olof Johansson, Tawfik Bayouk,
	Jason Gunthorpe, Mitch Bradley, Andrew Murray

Dear Bjorn Helgaas,

On Mon, 8 Apr 2013 14:29:59 -0600, Bjorn Helgaas wrote:

> > Signed-off-by: Thomas Petazzoni
> > <thomas.petazzoni@free-electrons.com>
> 
> Acked-by: Bjorn Helgaas <bhelgaas@google.com>
> 
> A few trivial comments below; it's up to you whether you do anything
> with them or not.  It's OK with me if you ignore them :)
> 
> The only thing I saw that might be a bug is the resource_size()
> question in mvebu_pcie_probe().

Thanks for the review!

> > diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
> > new file mode 100644
> > index 0000000..3ad563f
> > --- /dev/null
> > +++ b/drivers/pci/host/Makefile
> > @@ -0,0 +1,4 @@
> > +obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
> > +CFLAGS_pci-mvebu.o += \
> > +       -I$(srctree)/arch/arm/plat-orion/include \
> > +       -I$(srctree)/arch/arm/mach-mvebu/include
> 
> Too bad to have to adjust CFLAGS here.  Seems like I remember earlier
> discussion, but I didn't pay much attention, and if this is the best
> we can do, I guess it's OK.

Ah, indeed! This is now longer needed. The plat-orion include was
needed to get access to some PCIe functions, which are now part of the
driver, and the mach-mvebu header was needed to access some address
decoding window related functions, that are now part of the mvebu-mbus
driver.

> > +#define PCIE_BAR_CTRL_OFF(n)   (0x1804 + ((n - 1) * 4))
> 
> Strictly speaking, I suppose you should have "(((n) - 1) ..." here.

Correct, thanks.

> > +#define PCIE_STAT_OFF          0x1a04
> > +#define  PCIE_STAT_DEV_OFFS            20
> > +#define  PCIE_STAT_DEV_MASK            0x1f
> > +#define  PCIE_STAT_BUS_OFFS            8
> > +#define  PCIE_STAT_BUS_MASK            0xff
> > +#define  PCIE_STAT_LINK_DOWN           1
> 
> Whoever wrote pci_regs.h came up with a style I kind of like: the bit
> masks are already shifted so you can see where they are in the value,
> and there are no #defines for the shifts, e.g.,
> 
> #define PCI_EXP_FLAGS_TYPE      0x00f0  /* Device/Port type */
> 
> The users of PCI_EXP_FLAGS_TYPE just have a bare ">> 4" where
> necessary.  It seems like a good compromise that uses only one symbol
> (good for grepping), gives good visual indication in the header file
> of how the value is laid out, allows clearing bits without shifts, and
> clearly shows what's happening at the uses.
> 
> But what you have is OK, too :)

Hum, ok, I'll try to think of it. Maybe too much of a 'big' change at
this point, but I'll see.

> > +static int mvebu_pcie_link_up(void __iomem *base)
> 
> This could return bool, I guess.

Indeed.

> I think I would make
> 
>   mvebu_pcie_link_up()
>   mvebu_pcie_set_local_bus_nr()
>   mvebu_pcie_setup_wins()
>   mvebu_pcie_setup_hw()
>   mvebu_pcie_hw_rd_conf()
>   mvebu_pcie_hw_wr_conf()
> 
> all take a "struct mvebu_pcie_port *port" directly rather than having
> the caller pass in "port->base", but maybe you have a reason for doing
> otherwise.

I'll review this, I think your suggestion makes sense.

> > +       /*
> > +        * First, disable and clear BARs and windows.
> > +        */
> 
> Typically single-line comments would be "/* ... */" all on one line.

Correct.

> > +       for (i = 1; i <= 2; i++) {
> 
> Interesting use of "i <= 2" rather than the typical "i < 3".

I must confess this code comes from plat-orion/pcie.c, and I just
copy/pasted it (note: we intentionally don't use plat-orion/pcie.c to
avoid having to have to include a header in plat-orion/include, and
this plat-orion/pcie.c should ultimately go away once all Marvell EBU
platforms are migrated to use the new PCIe driver).

> > +       /*
> > +        * Enable interrupt lines A-D.
> > +        */
> > +       mask = readl(base + PCIE_MASK_OFF);
> > +       mask |= 0x0f000000;
> 
> No #defines for these bits?

Good point.

> > +       writel(mask, base + PCIE_MASK_OFF);
> > +}
> > +
> > +static int mvebu_pcie_hw_rd_conf(void __iomem *base, struct
> > pci_bus *bus,
> > +                                u32 devfn, int where, int size,
> > u32 *val) +{
> > +       writel(PCIE_CONF_BUS(bus->number) |
> > +               PCIE_CONF_DEV(PCI_SLOT(devfn)) |
> > +               PCIE_CONF_FUNC(PCI_FUNC(devfn)) |
> > +               PCIE_CONF_REG(where) | PCIE_CONF_ADDR_EN,
> 
> A "PCIE_CONF_ADDR(busnr, devfn, where)" macro would be nice here.

Right.

> > +static void mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port
> > *port) +{
> > +       phys_addr_t iobase;
> > +
> > +       /* Are the current iobase/iolimit values invalid? */
> 
> I first thought "current ... values" meant "the values before the
> change."  If you used "new values" it might be clearer that this is
> used to handle *writes* to the window base/size registers, and that
> we're looking at the values being written.

Ok, makes sense indeed.

> > +               return mvebu_sw_pci_bridge_write(port, where, size,
> > val);
> > +       }
> > +
> > +       return PCIBIOS_SUCCESSFUL;
> 
> This last "return" is unreachable (I see you omitted it from the
> rd_conf() path already :)).  This would be slightly simpler as:
> 
>   static struct mvebu_pcie_port *mvebu_find_port(struct mvebu_pcie
> *pcie, struct pci_bus *bus, int devfn)
>   {
>     int i;
> 
>     for (i = 0; i < pcie->nports; i++) {
>       if ((bus->number == 0 && pcie->ports[i].devfn == devfn) ||
>           (pcie->ports[porti].bridge.secondary_bus == bus->number))
>         return &pcie->ports[i];
>     }
>     return NULL;
>   }
> 
>   static int mvebu_pcie_wr_conf(struct pci_bus *bus, ...)
>   {
>     port = mvebu_find_port(pcie, bus, devfn);
>     if (!port)
>       return PCIBIOS_DEVICE_NOT_FOUND;
> 
>     if (bus->number == 0)
>       return mvebu_sw_pci_bridge_write(port, where, size, val);
> 
>     if (!port->haslink || PCI_SLOT(devfn) != 0)
>       return PCIBIOS_DEVICE_NOT_FOUND;
> 
>     ...
>     return ret;
>   }

Ok, I'll have a look at this.

> > IORESOURCE_TYPE_BITS;
> > +               if (restype == IORESOURCE_IO) {
> > +                       of_pci_range_to_resource(&range, np,
> > &pcie->io);
> > +                       of_pci_range_to_resource(&range, np,
> > &pcie->realio);
> > +                       pcie->io.name = "I/O";
> > +                       pcie->realio.start = PCIBIOS_MIN_IO;
> > +                       pcie->realio.end =
> > min(resource_size(&pcie->io),
> > +                                              IO_SPACE_LIMIT);
> 
> Using "resource_size(&pcie->io)" here seems strange -- are you
> assuming that pcie->io starts at address zero?

No, I'm assuming PCIBIOS_MIN_IO is always 0. So presumarly, this should
be something like:

	pcie->realio.end = min(PCIBIOS_MIN_IO +
				resource_size(&pcie->io),
				IO_SPACE_LIMIT);


Thanks for all your valuable comments!

Thomas
-- 
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* Re: [PATCHv7 08/17] pci: PCIe driver for Marvell Armada 370/XP systems
  2013-04-08 20:29   ` Bjorn Helgaas
  2013-04-08 20:57     ` Thomas Petazzoni
@ 2013-04-08 21:31     ` Arnd Bergmann
  2013-04-08 21:34       ` Thomas Petazzoni
  1 sibling, 1 reply; 37+ messages in thread
From: Arnd Bergmann @ 2013-04-08 21:31 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Thomas Petazzoni, Grant Likely, Russell King,
	linux-pci@vger.kernel.org, linux-arm,
	devicetree-discuss@lists.ozlabs.org, Lior Amsalem, Andrew Lunn,
	Jason Cooper, Maen Suleiman, Thierry Reding, Gregory Clement,
	Ezequiel Garcia, Olof Johansson, Tawfik Bayouk, Jason Gunthorpe,
	Mitch Bradley, Andrew Murray

On Monday 08 April 2013, Bjorn Helgaas wrote:
> On Wed, Mar 27, 2013 at 8:40 AM, Thomas Petazzoni
> 
> > diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
> > new file mode 100644
> > index 0000000..3ad563f
> > --- /dev/null
> > +++ b/drivers/pci/host/Makefile
> > @@ -0,0 +1,4 @@
> > +obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
> > +CFLAGS_pci-mvebu.o += \
> > +       -I$(srctree)/arch/arm/plat-orion/include \
> > +       -I$(srctree)/arch/arm/mach-mvebu/include
> 
> Too bad to have to adjust CFLAGS here.  Seems like I remember earlier
> discussion, but I didn't pay much attention, and if this is the best
> we can do, I guess it's OK.

I'm pretty sure I NAK'ed this part. I'm surprised it's still there.


	Arnd

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

* Re: [PATCHv7 08/17] pci: PCIe driver for Marvell Armada 370/XP systems
  2013-04-08 20:57     ` Thomas Petazzoni
@ 2013-04-08 21:34       ` Arnd Bergmann
  2013-04-08 21:53         ` Thomas Petazzoni
  0 siblings, 1 reply; 37+ messages in thread
From: Arnd Bergmann @ 2013-04-08 21:34 UTC (permalink / raw)
  To: Thomas Petazzoni
  Cc: Bjorn Helgaas, Grant Likely, Russell King,
	linux-pci@vger.kernel.org, linux-arm,
	devicetree-discuss@lists.ozlabs.org, Lior Amsalem, Andrew Lunn,
	Jason Cooper, Maen Suleiman, Thierry Reding, Gregory Clement,
	Ezequiel Garcia, Olof Johansson, Tawfik Bayouk, Jason Gunthorpe,
	Mitch Bradley, Andrew Murray

On Monday 08 April 2013, Thomas Petazzoni wrote:
> > > +                       pcie->io.name = "I/O";
> > > +                       pcie->realio.start = PCIBIOS_MIN_IO;
> > > +                       pcie->realio.end =
> > > min(resource_size(&pcie->io),
> > > +                                              IO_SPACE_LIMIT);
> > 
> > Using "resource_size(&pcie->io)" here seems strange -- are you
> > assuming that pcie->io starts at address zero?
> 
> No, I'm assuming PCIBIOS_MIN_IO is always 0. So presumarly, this should
> be something like:
> 
>         pcie->realio.end = min(PCIBIOS_MIN_IO +
>                                 resource_size(&pcie->io),
>                                 IO_SPACE_LIMIT);
> 

Normally PCIBIOS_MIN_IO is 0x1000, since the first 4096 ports are reserved
for ISA and PCMCIA compatible drivers and should not be assigned to
PCI devices. So the first port should get ports 0x1000 to 0xffff, later
ones can used the entire 65536 ports e.g. 0x10000 to 0x1ffff.

	Arnd

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

* Re: [PATCHv7 08/17] pci: PCIe driver for Marvell Armada 370/XP systems
  2013-04-08 21:31     ` Arnd Bergmann
@ 2013-04-08 21:34       ` Thomas Petazzoni
  0 siblings, 0 replies; 37+ messages in thread
From: Thomas Petazzoni @ 2013-04-08 21:34 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Bjorn Helgaas, Grant Likely, Russell King,
	linux-pci@vger.kernel.org, linux-arm,
	devicetree-discuss@lists.ozlabs.org, Lior Amsalem, Andrew Lunn,
	Jason Cooper, Maen Suleiman, Thierry Reding, Gregory Clement,
	Ezequiel Garcia, Olof Johansson, Tawfik Bayouk, Jason Gunthorpe,
	Mitch Bradley, Andrew Murray

Dear Arnd Bergmann,

On Mon, 8 Apr 2013 23:31:30 +0200, Arnd Bergmann wrote:

> > Too bad to have to adjust CFLAGS here.  Seems like I remember earlier
> > discussion, but I didn't pay much attention, and if this is the best
> > we can do, I guess it's OK.
> 
> I'm pretty sure I NAK'ed this part. I'm surprised it's still there.

As I said in my reply to Bjorn, it's a mistake. I did so much efforts
to get rid of the mach-mvebu and plat-orion dependencies, that in the
end, I forgot that the original reason was to get rid of those special
cflags.

For sure, I'll send a v8 that has those cflags removed, they are
unneeded.

Sorry for this.

Thomas
-- 
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* Re: [PATCHv7 08/17] pci: PCIe driver for Marvell Armada 370/XP systems
  2013-04-08 21:34       ` Arnd Bergmann
@ 2013-04-08 21:53         ` Thomas Petazzoni
  2013-04-08 22:14           ` Arnd Bergmann
  0 siblings, 1 reply; 37+ messages in thread
From: Thomas Petazzoni @ 2013-04-08 21:53 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Bjorn Helgaas, Grant Likely, Russell King,
	linux-pci@vger.kernel.org, linux-arm,
	devicetree-discuss@lists.ozlabs.org, Lior Amsalem, Andrew Lunn,
	Jason Cooper, Maen Suleiman, Thierry Reding, Gregory Clement,
	Ezequiel Garcia, Olof Johansson, Tawfik Bayouk, Jason Gunthorpe,
	Mitch Bradley, Andrew Murray

Dear Arnd Bergmann,

On Mon, 8 Apr 2013 23:34:12 +0200, Arnd Bergmann wrote:

> > No, I'm assuming PCIBIOS_MIN_IO is always 0. So presumarly, this should
> > be something like:
> > 
> >         pcie->realio.end = min(PCIBIOS_MIN_IO +
> >                                 resource_size(&pcie->io),
> >                                 IO_SPACE_LIMIT);
> > 
> 
> Normally PCIBIOS_MIN_IO is 0x1000, since the first 4096 ports are reserved
> for ISA and PCMCIA compatible drivers and should not be assigned to
> PCI devices. So the first port should get ports 0x1000 to 0xffff, later
> ones can used the entire 65536 ports e.g. 0x10000 to 0x1ffff.

Then I guess it should work with the code I'm proposing here, no?

Note: this pcie->realio region is global: it will be shared by all PCIe
interfaces.

Thomas
-- 
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* Re: [PATCHv7 08/17] pci: PCIe driver for Marvell Armada 370/XP systems
  2013-04-08 21:53         ` Thomas Petazzoni
@ 2013-04-08 22:14           ` Arnd Bergmann
  2013-04-09 19:06             ` Thomas Petazzoni
  0 siblings, 1 reply; 37+ messages in thread
From: Arnd Bergmann @ 2013-04-08 22:14 UTC (permalink / raw)
  To: Thomas Petazzoni
  Cc: Bjorn Helgaas, Grant Likely, Russell King,
	linux-pci@vger.kernel.org, linux-arm,
	devicetree-discuss@lists.ozlabs.org, Lior Amsalem, Andrew Lunn,
	Jason Cooper, Maen Suleiman, Thierry Reding, Gregory Clement,
	Ezequiel Garcia, Olof Johansson, Tawfik Bayouk, Jason Gunthorpe,
	Mitch Bradley, Andrew Murray

On Monday 08 April 2013, Thomas Petazzoni wrote:
> Dear Arnd Bergmann,
> 
> On Mon, 8 Apr 2013 23:34:12 +0200, Arnd Bergmann wrote:
> 
> > > No, I'm assuming PCIBIOS_MIN_IO is always 0. So presumarly, this should
> > > be something like:
> > > 
> > >         pcie->realio.end = min(PCIBIOS_MIN_IO +
> > >                                 resource_size(&pcie->io),
> > >                                 IO_SPACE_LIMIT);
> > > 
> > 
> > Normally PCIBIOS_MIN_IO is 0x1000, since the first 4096 ports are reserved
> > for ISA and PCMCIA compatible drivers and should not be assigned to
> > PCI devices. So the first port should get ports 0x1000 to 0xffff, later
> > ones can used the entire 65536 ports e.g. 0x10000 to 0x1ffff.
> 
> Then I guess it should work with the code I'm proposing here, no?
> 
> Note: this pcie->realio region is global: it will be shared by all PCIe
> interfaces.

I think it's still wrong, unless you guarantee that
resource_start(&pcie->io) is the same as PCIBIOS_MIN_IO.

Why don't you just read the start and end values from the ranges
property? I assume you want to run with io_offset=0, so you really
need

	pcie->realio.type = IORESOURCE_IO;
	pcie->realio.start = max(PCIBIOS_MIN_IO, range->pci_addr);
	pcie->realio.end = max(IO_SPACE_LIMIT, range->pci_addr + range->size);

	Arnd

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

* Re: [PATCHv7 08/17] pci: PCIe driver for Marvell Armada 370/XP systems
  2013-04-08 22:14           ` Arnd Bergmann
@ 2013-04-09 19:06             ` Thomas Petazzoni
  2013-04-09 19:09               ` Arnd Bergmann
  0 siblings, 1 reply; 37+ messages in thread
From: Thomas Petazzoni @ 2013-04-09 19:06 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Bjorn Helgaas, Grant Likely, Russell King,
	linux-pci@vger.kernel.org, linux-arm,
	devicetree-discuss@lists.ozlabs.org, Lior Amsalem, Andrew Lunn,
	Jason Cooper, Maen Suleiman, Thierry Reding, Gregory Clement,
	Ezequiel Garcia, Olof Johansson, Tawfik Bayouk, Jason Gunthorpe,
	Mitch Bradley, Andrew Murray

Dear Arnd Bergmann,

On Tue, 9 Apr 2013 00:14:06 +0200, Arnd Bergmann wrote:

> 	pcie->realio.type = IORESOURCE_IO;
> 	pcie->realio.start = max(PCIBIOS_MIN_IO, range->pci_addr);
> 	pcie->realio.end = max(IO_SPACE_LIMIT, range->pci_addr + range->size);

Shouldn't this last line be using "min()" so that we guarantee we don't
have an I/O region that goes beyond IO_SPACE_LIMIT?

Thanks,

Thomas
-- 
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* Re: [PATCHv7 08/17] pci: PCIe driver for Marvell Armada 370/XP systems
  2013-04-09 19:06             ` Thomas Petazzoni
@ 2013-04-09 19:09               ` Arnd Bergmann
  0 siblings, 0 replies; 37+ messages in thread
From: Arnd Bergmann @ 2013-04-09 19:09 UTC (permalink / raw)
  To: Thomas Petazzoni
  Cc: Bjorn Helgaas, Grant Likely, Russell King,
	linux-pci@vger.kernel.org, linux-arm,
	devicetree-discuss@lists.ozlabs.org, Lior Amsalem, Andrew Lunn,
	Jason Cooper, Maen Suleiman, Thierry Reding, Gregory Clement,
	Ezequiel Garcia, Olof Johansson, Tawfik Bayouk, Jason Gunthorpe,
	Mitch Bradley, Andrew Murray

On Tuesday 09 April 2013, Thomas Petazzoni wrote:
> Dear Arnd Bergmann,
> 
> On Tue, 9 Apr 2013 00:14:06 +0200, Arnd Bergmann wrote:
> 
> >       pcie->realio.type = IORESOURCE_IO;
> >       pcie->realio.start = max(PCIBIOS_MIN_IO, range->pci_addr);
> >       pcie->realio.end = max(IO_SPACE_LIMIT, range->pci_addr + range->size);
> 
> Shouldn't this last line be using "min()" so that we guarantee we don't
> have an I/O region that goes beyond IO_SPACE_LIMIT?
> 

Yes, of course. Sorry for not typing what I was thinking ;-)

	Arnd

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

* Re: [PATCHv7 07/17] clk: mvebu: add more PCIe clocks for Armada XP
  2013-03-27 14:40 ` [PATCHv7 07/17] clk: mvebu: add more PCIe clocks for Armada XP Thomas Petazzoni
  2013-04-05 14:59   ` Thomas Petazzoni
@ 2013-04-10  8:08   ` Mike Turquette
  1 sibling, 0 replies; 37+ messages in thread
From: Mike Turquette @ 2013-04-10  8:08 UTC (permalink / raw)
  To: Thomas Petazzoni, Bjorn Helgaas, Grant Likely, Russell King
  Cc: Lior Amsalem, Andrew Lunn, Jason Cooper, Arnd Bergmann,
	Olof Johansson, linux-pci, devicetree-discuss, Thierry Reding,
	Jason Gunthorpe, Maen Suleiman, Ezequiel Garcia, Gregory Clement,
	Andrew Murray, Tawfik Bayouk, linux-arm-kernel, Mitch Bradley

Quoting Thomas Petazzoni (2013-03-27 07:40:24)
> The current revision of the datasheet only mentions the gatable clocks
> for the PCIe 0.0, 0.1, 0.2 and 0.3 interfaces, and forgot to mention
> the ones for the PCIe 1.0, 1.1, 1.2, 1.3, 2.0 and 3.0
> interfaces. After confirmation with Marvell engineers, this patch adds
> the missing gatable clocks for those PCIe interfaces.
> 
> It also changes the name of the previously existing PCIe gatable
> clocks, in order to match the naming using the datasheets.
> 
> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>

Acked-by: Mike Turquette <mturquette@linaro.org>

> ---
>  drivers/clk/mvebu/clk-gating-ctrl.c |   14 ++++++++++----
>  1 file changed, 10 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/clk/mvebu/clk-gating-ctrl.c b/drivers/clk/mvebu/clk-gating-ctrl.c
> index b35785a..2f03723 100644
> --- a/drivers/clk/mvebu/clk-gating-ctrl.c
> +++ b/drivers/clk/mvebu/clk-gating-ctrl.c
> @@ -137,10 +137,14 @@ static const struct mvebu_soc_descr __initconst armada_xp_gating_descr[] = {
>         { "ge2", NULL,  2 },
>         { "ge1", NULL, 3 },
>         { "ge0", NULL, 4 },
> -       { "pex0", NULL, 5 },
> -       { "pex1", NULL, 6 },
> -       { "pex2", NULL, 7 },
> -       { "pex3", NULL, 8 },
> +       { "pex00", NULL, 5 },
> +       { "pex01", NULL, 6 },
> +       { "pex02", NULL, 7 },
> +       { "pex03", NULL, 8 },
> +       { "pex10", NULL, 9 },
> +       { "pex11", NULL, 10 },
> +       { "pex12", NULL, 11 },
> +       { "pex13", NULL, 12 },
>         { "bp", NULL, 13 },
>         { "sata0lnk", NULL, 14 },
>         { "sata0", "sata0lnk", 15 },
> @@ -152,6 +156,8 @@ static const struct mvebu_soc_descr __initconst armada_xp_gating_descr[] = {
>         { "xor0", NULL, 22 },
>         { "crypto", NULL, 23 },
>         { "tdm", NULL, 25 },
> +       { "pex20", NULL, 26 },
> +       { "pex30", NULL, 27 },
>         { "xor1", NULL, 28 },
>         { "sata1lnk", NULL, 29 },
>         { "sata1", "sata1lnk", 30 },
> -- 
> 1.7.9.5
> 
> 
> _______________________________________________
> 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] 37+ messages in thread

* Re: [PATCHv7 06/17] clk: mvebu: create parent-child relation for PCIe clocks on Armada 370
  2013-03-27 14:40 ` [PATCHv7 06/17] clk: mvebu: create parent-child relation for PCIe clocks on Armada 370 Thomas Petazzoni
  2013-04-05 13:58   ` Thomas Petazzoni
@ 2013-04-10  8:09   ` Mike Turquette
  1 sibling, 0 replies; 37+ messages in thread
From: Mike Turquette @ 2013-04-10  8:09 UTC (permalink / raw)
  To: Thomas Petazzoni, Bjorn Helgaas, Grant Likely, Russell King
  Cc: linux-pci, linux-arm-kernel, devicetree-discuss, Lior Amsalem,
	Andrew Lunn, Jason Cooper, Arnd Bergmann, Maen Suleiman,
	Thierry Reding, Gregory Clement, Ezequiel Garcia, Olof Johansson,
	Tawfik Bayouk, Jason Gunthorpe, Mitch Bradley, Andrew Murray

Quoting Thomas Petazzoni (2013-03-27 07:40:23)
> The Armada 370 has two gatable clocks for each PCIe interface, and we
> want both of them to be enabled. We therefore make one of the two
> clocks a child of the other, as we did for the sataX and sataXlnk
> clocks on Armada XP.
> 
> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
> Cc: Mike Turquette <mturquette@linaro.org>

Acked-by: Mike Turquette <mturquette@linaro.org>

> ---
>  drivers/clk/mvebu/clk-gating-ctrl.c |    4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/clk/mvebu/clk-gating-ctrl.c b/drivers/clk/mvebu/clk-gating-ctrl.c
> index ebf141d..b35785a 100644
> --- a/drivers/clk/mvebu/clk-gating-ctrl.c
> +++ b/drivers/clk/mvebu/clk-gating-ctrl.c
> @@ -119,8 +119,8 @@ static const struct mvebu_soc_descr __initconst armada_370_gating_descr[] = {
>         { "pex1_en", NULL,  2 },
>         { "ge1", NULL, 3 },
>         { "ge0", NULL, 4 },
> -       { "pex0", NULL, 5 },
> -       { "pex1", NULL, 9 },
> +       { "pex0", "pex0_en", 5 },
> +       { "pex1", "pex1_en", 9 },
>         { "sata0", NULL, 15 },
>         { "sdio", NULL, 17 },
>         { "tdm", NULL, 25 },
> -- 
> 1.7.9.5

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

end of thread, other threads:[~2013-04-10  8:09 UTC | newest]

Thread overview: 37+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-03-27 14:40 [PATCHv7 00/17] PCIe support for the Armada 370 and Armada XP SoCs Thomas Petazzoni
2013-03-27 14:40 ` [PATCHv7 01/17] of/pci: Provide support for parsing PCI DT ranges property Thomas Petazzoni
2013-03-27 14:40 ` [PATCHv7 02/17] of/pci: Add of_pci_get_devfn() function Thomas Petazzoni
2013-03-27 14:40 ` [PATCHv7 03/17] of/pci: Add of_pci_parse_bus_range() function Thomas Petazzoni
2013-03-27 14:40 ` [PATCHv7 04/17] pci: infrastructure to add drivers in drivers/pci/host Thomas Petazzoni
     [not found]   ` <CAAfodu2t4j4ZASzdaKV0QarffXRwMgkMESGy=dDq1oMfTANEeg@mail.gmail.com>
     [not found]     ` <CAAfodu2t4j4ZASzdaKV0QarffXRwMgkMESGy=dDq1oMfTANEeg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2013-03-28  7:24       ` Thomas Petazzoni
2013-04-08 20:32         ` Bjorn Helgaas
2013-03-27 14:40 ` [PATCHv7 05/17] arm: pci: add a align_resource hook Thomas Petazzoni
2013-03-27 14:40 ` [PATCHv7 06/17] clk: mvebu: create parent-child relation for PCIe clocks on Armada 370 Thomas Petazzoni
2013-04-05 13:58   ` Thomas Petazzoni
2013-04-10  8:09   ` Mike Turquette
2013-03-27 14:40 ` [PATCHv7 07/17] clk: mvebu: add more PCIe clocks for Armada XP Thomas Petazzoni
2013-04-05 14:59   ` Thomas Petazzoni
2013-04-10  8:08   ` Mike Turquette
2013-03-27 14:40 ` [PATCHv7 08/17] pci: PCIe driver for Marvell Armada 370/XP systems Thomas Petazzoni
2013-04-08 20:29   ` Bjorn Helgaas
2013-04-08 20:57     ` Thomas Petazzoni
2013-04-08 21:34       ` Arnd Bergmann
2013-04-08 21:53         ` Thomas Petazzoni
2013-04-08 22:14           ` Arnd Bergmann
2013-04-09 19:06             ` Thomas Petazzoni
2013-04-09 19:09               ` Arnd Bergmann
2013-04-08 21:31     ` Arnd Bergmann
2013-04-08 21:34       ` Thomas Petazzoni
2013-03-27 14:40 ` [PATCHv7 09/17] arm: mvebu: PCIe support is now available on mvebu Thomas Petazzoni
2013-03-27 14:40 ` [PATCHv7 10/17] arm: mvebu: add PCIe Device Tree informations for Armada 370 Thomas Petazzoni
2013-03-27 14:40 ` [PATCHv7 11/17] arm: mvebu: add PCIe Device Tree informations for Armada XP Thomas Petazzoni
2013-03-27 14:40 ` [PATCHv7 12/17] arm: mvebu: PCIe Device Tree informations for OpenBlocks AX3-4 Thomas Petazzoni
2013-03-27 14:40 ` [PATCHv7 13/17] arm: mvebu: PCIe Device Tree informations for Armada XP DB Thomas Petazzoni
2013-03-27 14:40 ` [PATCHv7 14/17] arm: mvebu: PCIe Device Tree informations for Armada 370 Mirabox Thomas Petazzoni
2013-03-27 14:40 ` [PATCHv7 15/17] arm: mvebu: PCIe Device Tree informations for Armada 370 DB Thomas Petazzoni
2013-03-27 14:40 ` [PATCHv7 16/17] arm: mvebu: PCIe Device Tree informations for Armada XP GP Thomas Petazzoni
2013-03-27 14:40 ` [PATCHv7 17/17] arm: mvebu: update defconfig with PCI and USB support Thomas Petazzoni
2013-03-31  1:05 ` [PATCHv7 00/17] PCIe support for the Armada 370 and Armada XP SoCs Jason Cooper
2013-04-02 11:36 ` Linus Walleij
2013-04-03 12:27 ` Thomas Petazzoni
2013-04-03 16:31   ` Linus Walleij

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