Skip to contentSkip to conversation

Support for Generic PCI Host Controller

PATCH Superseded Will Deacon 2 participants 9 messages May 23, 2014 – May 25, 2014

Subsystems (10)
lore
Share & tools
lore
#0 lore raw

v7 cover Support for Generic PCI Host Controller

Hi all,

This is version 7 of the generic PCI host controller series that has previously been posted here:

v1: http://lists.infradead.org/pipermail/linux-arm-kernel/2014-February/229679.html
v2: http://lists.infradead.org/pipermail/linux-arm-kernel/2014-February/232213.html
v3: http://lists.infradead.org/pipermail/linux-arm-kernel/2014-February/233491.html
v4: http://lists.infradead.org/pipermail/linux-arm-kernel/2014-February/235468.html
v5: http://lists.infradead.org/pipermail/linux-arm-kernel/2014-March/237540.html

      http://lists.infradead.org/pipermail/linux-arm-kernel/2014-May/252915.html

v6: http://lists.infradead.org/pipermail/linux-arm-kernel/2014-May/253993.html

Changes since v6 include:

- Removed redundant MIGHT_HAVE_PCI selections from multiplatform-enabled SoCs

- Included patch from Srikanth for generic Configuration Space access to be factored out and used by other drivers

- Fixed minor issue in I/O port allocation (I had a >= instead of a >)

All comments welcome,

Will

Srikanth Thokala (1):
PCI: Generic Configuration Access Mechanism support

Will Deacon (3):
ARM: kconfig: allow PCI support to be selected with ARCH_MULTIPLATFORM
PCI: ARM: add support for generic PCI host controller
MAINTAINERS: add entry for generic PCI host controller driver

 .../devicetree/bindings/pci/host-generic-pci.txt   | 100 ++++++
 MAINTAINERS                                        |   8 +
 arch/arm/Kconfig                                   |   1 +
 arch/arm/mach-bcm/Kconfig                          |   1 -
 arch/arm/mach-cns3xxx/Kconfig                      |   1 -
 arch/arm/mach-imx/Kconfig                          |   1 -
 arch/arm/mach-mvebu/Kconfig                        |   1 -
 arch/arm/mach-shmobile/Kconfig                     |   1 -
 arch/arm/mach-tegra/Kconfig                        |   1 -
 drivers/pci/Makefile                               |   2 +-
 drivers/pci/host/Kconfig                           |   7 +
 drivers/pci/host/Makefile                          |   1 +
 drivers/pci/host/pci-host-generic.c                | 388 +++++++++++++++++++++
 drivers/pci/pci-cfg.c                              | 162 +++++++++
 include/linux/pci.h                                |  34 ++
 15 files changed, 702 insertions(+), 7 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pci/host-generic-pci.txt
 create mode 100644 drivers/pci/host/pci-host-generic.c
 create mode 100644 drivers/pci/pci-cfg.c
Signature · 1 line
1.9.2
#1 lore raw

PATCH v7 1/4 ARM: kconfig: allow PCI support to be selected with ARCH_MULTIPLATFORM

When targetting ARCH_MULTIPLATFORM, we may include support for SoCs with PCI-capable devices (e.g. mach-virt with virtio-pci).

This patch allows PCI support to be selected for these SoCs by selecting CONFIG_MIGHT_HAVE_PCI when CONFIG_ARCH_MULTIPLATFORM=y and removes the individual selections from multi-platform enabled SoCs.

---
 arch/arm/Kconfig               | 1 +
 arch/arm/mach-bcm/Kconfig      | 1 -
 arch/arm/mach-cns3xxx/Kconfig  | 1 -
 arch/arm/mach-imx/Kconfig      | 1 -
 arch/arm/mach-mvebu/Kconfig    | 1 -
 arch/arm/mach-shmobile/Kconfig | 1 -
 arch/arm/mach-tegra/Kconfig    | 1 -
 7 files changed, 1 insertion(+), 6 deletions(-)
arch/arm/Kconfig +1 -0
index db3c5414223e..860bea828ac4 100644
@@ -314,6 +314,7 @@ config ARCH_MULTIPLATFORM
 	select CLKSRC_OF
 	select COMMON_CLK
 	select GENERIC_CLOCKEVENTS
+	select MIGHT_HAVE_PCI
 	select MULTI_IRQ_HANDLER
 	select SPARSE_IRQ
 	select USE_OF
arch/arm/mach-bcm/Kconfig +0 -1
index 49c914cd9c7a..764c129b5eee 100644
@@ -55,7 +55,6 @@ config ARCH_BCM_5301X
 	select GENERIC_CLOCKEVENTS
 	select ARM_GLOBAL_TIMER
 	select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
-	select MIGHT_HAVE_PCI
 	help
 	  Support for Broadcom BCM470X and BCM5301X SoCs with ARM CPU cores.
 
arch/arm/mach-cns3xxx/Kconfig +0 -1
index dce8decd5d46..66838f42037f 100644
@@ -1,7 +1,6 @@
 config ARCH_CNS3XXX
 	bool "Cavium Networks CNS3XXX family" if ARCH_MULTI_V6
 	select ARM_GIC
-	select MIGHT_HAVE_PCI
 	select PCI_DOMAINS if PCI
 	help
 	  Support for Cavium Networks CNS3XXX platform.
arch/arm/mach-imx/Kconfig +0 -1
index 5740296dc429..50bb546b893a 100644
@@ -796,7 +796,6 @@ config SOC_IMX6Q
 	select ARM_ERRATA_764369 if SMP
 	select HAVE_ARM_SCU if SMP
 	select HAVE_ARM_TWD if SMP
-	select MIGHT_HAVE_PCI
 	select PCI_DOMAINS if PCI
 	select PINCTRL_IMX6Q
 	select SOC_IMX6
arch/arm/mach-mvebu/Kconfig +0 -1
index 3f73eecbcfb0..120301ebd324 100644
@@ -9,7 +9,6 @@ config ARCH_MVEBU
 	select MVEBU_MBUS
 	select ZONE_DMA if ARM_LPAE
 	select ARCH_REQUIRE_GPIOLIB
-	select MIGHT_HAVE_PCI
 	select PCI_QUIRKS if PCI
 	select OF_ADDRESS_PCI
 
arch/arm/mach-shmobile/Kconfig +0 -1
index 0f92ba8e7884..905003898913 100644
@@ -8,7 +8,6 @@ config ARCH_SHMOBILE_MULTI
 	select HAVE_ARM_SCU if SMP
 	select HAVE_ARM_TWD if SMP
 	select ARM_GIC
-	select MIGHT_HAVE_PCI
 	select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
 	select NO_IOPORT_MAP
 	select PINCTRL
arch/arm/mach-tegra/Kconfig +0 -1
index 55b305d51669..e16999e5b735 100644
@@ -7,7 +7,6 @@ config ARCH_TEGRA
 	select CLKSRC_MMIO
 	select HAVE_ARM_SCU if SMP
 	select HAVE_ARM_TWD if SMP
-	select MIGHT_HAVE_PCI
 	select PINCTRL
 	select ARCH_HAS_RESET_CONTROLLER
 	select RESET_CONTROLLER
Signature · 1 line
1.9.2
#2 lore raw

PATCH v7 2/4 PCI: ARM: add support for generic PCI host controller

In reply to Will Deacon

This patch adds support for a generic PCI host controller, such as a firmware-initialised device with static windows or an emulation by something such as kvmtool.

The controller itself has no configuration registers and has its address spaces described entirely by the device-tree (using the bindings from ePAPR). Both CAM and ECAM are supported for Config Space accesses.

Corresponding documentation is added for the DT binding.

---
 .../devicetree/bindings/pci/host-generic-pci.txt   | 100 ++++++
 drivers/pci/host/Kconfig                           |   7 +
 drivers/pci/host/Makefile                          |   1 +
 drivers/pci/host/pci-host-generic.c                | 388 +++++++++++++++++++++
 4 files changed, 496 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/host-generic-pci.txt
 create mode 100644 drivers/pci/host/pci-host-generic.c
Documentation/devicetree/bindings/pci/host-generic-pci.txt new file +100 -0
new file mode 100644
index 000000000000..f0b0436807b4
@@ -0,0 +1,100 @@
+* Generic PCI host controller
+
+Firmware-initialised PCI host controllers and PCI emulations, such as the
+virtio-pci implementations found in kvmtool and other para-virtualised
+systems, do not require driver support for complexities such as regulator
+and clock management. In fact, the controller may not even require the
+configuration of a control interface by the operating system, instead
+presenting a set of fixed windows describing a subset of IO, Memory and
+Configuration Spaces.
+
+Such a controller can be described purely in terms of the standardized device
+tree bindings communicated in pci.txt:
+
+
+Properties of the host controller node:
+
+- compatible     : Must be "pci-host-cam-generic" or "pci-host-ecam-generic"
+                   depending on the layout of configuration space (CAM vs
+                   ECAM respectively).
+
+- device_type    : Must be "pci".
+
+- ranges         : As described in IEEE Std 1275-1994, but must provide
+                   at least a definition of non-prefetchable memory. One
+                   or both of prefetchable Memory and IO Space may also
+                   be provided.
+
+- bus-range      : Optional property (also described in IEEE Std 1275-1994)
+                   to indicate the range of bus numbers for this controller.
+                   If absent, defaults to <0 255> (i.e. all buses).
+
+- #address-cells : Must be 3.
+
+- #size-cells    : Must be 2.
+
+- reg            : The Configuration Space base address and size, as accessed
+                   from the parent bus.
+
+
+Properties of the /chosen node:
+
+- linux,pci-probe-only
+                 : Optional property which takes a single-cell argument.
+                   If '0', then Linux will assign devices in its usual manner,
+                   otherwise it will not try to assign devices and instead use
+                   them as they are configured already.
+
+Configuration Space is assumed to be memory-mapped (as opposed to being
+accessed via an ioport) and laid out with a direct correspondence to the
+geography of a PCI bus address by concatenating the various components to
+form an offset.
+
+For CAM, this 24-bit offset is:
+
+        cfg_offset(bus, device, function, register) =
+                   bus << 16 | device << 11 | function << 8 | register
+
+Whilst ECAM extends this by 4 bits to accomodate 4k of function space:
+
+        cfg_offset(bus, device, function, register) =
+                   bus << 20 | device << 15 | function << 12 | register
+
+Interrupt mapping is exactly as described in `Open Firmware Recommended
+Practice: Interrupt Mapping' and requires the following properties:
+
+- #interrupt-cells   : Must be 1
+
+- interrupt-map      : <see aforementioned specification>
+
+- interrupt-map-mask : <see aforementioned specification>
+
+
+Example:
+
+pci {
+    compatible = "pci-host-cam-generic"
+    device_type = "pci";
+    #address-cells = <3>;
+    #size-cells = <2>;
+    bus-range = <0x0 0x1>;
+
+    // CPU_PHYSICAL(2)  SIZE(2)
+    reg = <0x0 0x40000000  0x0 0x1000000>;
+
+    // BUS_ADDRESS(3)  CPU_PHYSICAL(2)  SIZE(2)
+    ranges = <0x01000000 0x0 0x01000000  0x0 0x01000000  0x0 0x00010000>,
+             <0x02000000 0x0 0x41000000  0x0 0x41000000  0x0 0x3f000000>;
+
+
+    #interrupt-cells = <0x1>;
+
+    // PCI_DEVICE(3)  INT#(1)  CONTROLLER(PHANDLE)  CONTROLLER_DATA(3)
+    interrupt-map = <  0x0 0x0 0x0  0x1  &gic  0x0 0x4 0x1
+                     0x800 0x0 0x0  0x1  &gic  0x0 0x5 0x1
+                    0x1000 0x0 0x0  0x1  &gic  0x0 0x6 0x1
+                    0x1800 0x0 0x0  0x1  &gic  0x0 0x7 0x1>;
+
+    // PCI_DEVICE(3)  INT#(1)
+    interrupt-map-mask = <0xf800 0x0 0x0  0x7>;
+}
drivers/pci/host/Kconfig +7 -0
index a6f67ec8882f..32d446effbb3 100644
@@ -33,4 +33,11 @@ config PCI_RCAR_GEN2
 	  There are 3 internal PCI controllers available with a single
 	  built-in EHCI/OHCI host controller present on each one.
 
+config PCI_HOST_GENERIC
+	bool "Generic PCI host controller"
+	depends on ARM && OF
+	help
+	  Say Y here if you want to support a simple generic PCI host
+	  controller, such as the one emulated by kvmtool.
+
 endmenu
drivers/pci/host/Makefile +1 -0
index 13fb3333aa05..bd1bf1ab4ac8 100644
@@ -4,3 +4,4 @@ obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
 obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
 obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
 obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
+obj-$(CONFIG_PCI_HOST_GENERIC) += pci-host-generic.o
drivers/pci/host/pci-host-generic.c new file +388 -0

388 lines not on this page · raw message

Signature · 1 line
1.9.2
#3 lore raw

PATCH v7 3/4 MAINTAINERS: add entry for generic PCI host controller driver

In reply to Will Deacon

Add myself as the maintainer for the generic PCI host controller driver.

---
 MAINTAINERS | 8 ++++++++
 1 file changed, 8 insertions(+)
MAINTAINERS +8 -0
index 51ebb779c5f3..fc1d6ff43067 100644
@@ -6751,6 +6751,14 @@ L:	linux-pci at vger.kernel.org
 S:	Maintained
 F:	drivers/pci/host/*designware*
 
+PCI DRIVER FOR GENERIC OF HOSTS
+M:	Will Deacon <[email protected]>
+L:	linux-pci at vger.kernel.org
+L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
+S:	Maintained
+F:	Documentation/devicetree/bindings/pci/host-generic-pci.txt
+F:	drivers/pci/host/pci-host-generic.c
+
 PCMCIA SUBSYSTEM
 P:	Linux PCMCIA Team
 L:	linux-pcmcia at lists.infradead.org
Signature · 1 line
1.9.2
#4 lore raw

PATCH v7 4/4 PCI: Generic Configuration Access Mechanism support

In reply to Will Deacon

From: Srikanth Thokala <[email protected]>

This patch adds support for a generic CAM and ECAM configuration space accesses.

---
 drivers/pci/Makefile  |   2 +-
 drivers/pci/pci-cfg.c | 162 ++++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/pci.h   |  34 +++++++++++
 3 files changed, 197 insertions(+), 1 deletion(-)
 create mode 100644 drivers/pci/pci-cfg.c
drivers/pci/Makefile +1 -1
index e04fe2d9df3b..37cfc3356e84 100644
@@ -4,7 +4,7 @@
 
 obj-y		+= access.o bus.o probe.o host-bridge.o remove.o pci.o \
 			pci-driver.o search.o pci-sysfs.o rom.o setup-res.o \
-			irq.o vpd.o setup-bus.o vc.o
+			irq.o vpd.o setup-bus.o vc.o pci-cfg.o
 obj-$(CONFIG_PROC_FS) += proc.o
 obj-$(CONFIG_SYSFS) += slot.o
 
drivers/pci/pci-cfg.c new file +162 -0

162 lines not on this page · raw message

include/linux/pci.h +34 -0
index aab57b4abe7f..6ebe21ebec1a 100644
@@ -1806,4 +1806,38 @@ static inline struct eeh_dev *pci_dev_to_eeh_dev(struct pci_dev *pdev)
  */
 struct pci_dev *pci_find_upstream_pcie_bridge(struct pci_dev *pdev);
 
+/**
+ * struct pci_cfg_bus_ops - PCI bus configuration operations
+ * @bus_shift: Bus number
+ * @map_bus: Function pointer to get the configuration space address
+ * @is_valid_cfg_access: Function pointer to check for a valid device/function
+ */
+struct pci_cfg_bus_ops {
+	u32 bus_shift;
+	void __iomem *(*map_bus)(struct pci_bus *, unsigned int, int);
+	/*
+	 * This function pointer is to check if we are addressing a valid
+	 * device's function under a particular bus.
+	 */
+	int (*is_valid_cfg_access)(struct pci_bus *, unsigned int);
+};
+
+/**
+ * struct pci_cfg_windows - PCI bus configuration memory windows
+ * @res: Configuration space resource
+ * @bus_range: Bus range
+ * @win: Configuration space memory windows
+ * @ops: PCI bus configuration operations
+ */
+struct pci_cfg_windows {
+	struct resource	res;
+	struct resource	bus_range;
+	void __iomem **win;
+	struct pci_cfg_bus_ops *ops;
+};
+
+extern struct pci_ops pci_cfg_ops;
+extern struct pci_cfg_bus_ops pci_cfg_ecam_bus_ops;
+extern struct pci_cfg_bus_ops pci_cfg_cam_bus_ops;
+
 #endif /* LINUX_PCI_H */
Signature · 1 line
1.9.2
#5 lore raw

PATCH v7 4/4 PCI: Generic Configuration Access Mechanism support

drivers/pci/pci-cfg.c line 63

Quoted 10 lines · Will Deacon
drivers/pci/pci-cfg.c new file +10 -0
+static void __iomem *pci_cfg_map_bus_ecam(struct pci_bus *bus,
+                                         unsigned int devfn,
+                                         int where)
+{
+       struct pci_sys_data *sys = bus->sysdata;
+       struct pci_cfg_windows *cfg = sys->private_data;
+       resource_size_t idx = bus->number - cfg->bus_range.start;
+
+       return cfg->win[idx] + ((devfn << PCI_CFG_ECAM_DEV_NUM) | where);
+}

I just noticed that this function makes the code rather non-generic, because struct pci_sys_data is the ARM specific structure that doesn't exist elsewhere, and sys->private_data wouldn't typically point to struct pci_cfg_windows on anything other than your generic PCI host.

I'd say let's drop this for now. I know it was my idea to do it like this, but it seems it's more complex than I had hoped to get this right, and I'd really prefer to merge the other three patches for 3.16 if possible. We can factor it out later if we get more users.

Arnd

#6 lore raw

PATCH v7 4/4 PCI: Generic Configuration Access Mechanism support

Quoted 16 lines · Arnd Bergmann

drivers/pci/pci-cfg.c line 63

Quoted 10 lines · Will Deacon
drivers/pci/pci-cfg.c new file +10 -0
+static void __iomem *pci_cfg_map_bus_ecam(struct pci_bus *bus,
+                                         unsigned int devfn,
+                                         int where)
+{
+       struct pci_sys_data *sys = bus->sysdata;
+       struct pci_cfg_windows *cfg = sys->private_data;
+       resource_size_t idx = bus->number - cfg->bus_range.start;
+
+       return cfg->win[idx] + ((devfn << PCI_CFG_ECAM_DEV_NUM) | where);
+}

I just noticed that this function makes the code rather non-generic, because struct pci_sys_data is the ARM specific structure that doesn't exist elsewhere, and sys->private_data wouldn't typically point to struct pci_cfg_windows on anything other than your generic PCI host.

Indeed. That's what I was refering to initially when I suggested some potential alignment on the private_data across host controller drivers trying to use this.

Quoted 4 lines

I'd say let's drop this for now. I know it was my idea to do it like this, but it seems it's more complex than I had hoped to get this right, and I'd really prefer to merge the other three patches for 3.16 if possible. We can factor it out later if we get more users.

Sure, I think we all had good intentions. I'll send a pull for the first three patches -- should it go via arm-soc or Bjorn's PCI tree?

Cheers,

Will

#7 lore raw

v7 cover Support for Generic PCI Host Controller

In reply to Will Deacon
Quoted 8 lines · Will Deacon

- Removed redundant MIGHT_HAVE_PCI selections from multiplatform-enabled SoCs

- Included patch from Srikanth for generic Configuration Space access to be factored out and used by other drivers

- Fixed minor issue in I/O port allocation (I had a >= instead of a >)

It seems strange that you include the patch from Srikanth but then use a separate copy of the same code in patch 2. Is that intentional?

Arnd

#8 lore raw

v7 cover Support for Generic PCI Host Controller

Hi Arnd,

Quoted 4 lines · Arnd Bergmann
Quoted 3 lines · Will Deacon

- Removed redundant MIGHT_HAVE_PCI selections from multiplatform-enabled SoCs

Quoted 8 lines
Quoted 5 lines

- Included patch from Srikanth for generic Configuration Space access to be factored out and used by other drivers

- Fixed minor issue in I/O port allocation (I had a >= instead of a >)

It seems strange that you include the patch from Srikanth but then use a separate copy of the same code in patch 2. Is that intentional?

That was a combination of me not being sure about the status of Srikanth's patch (the review didn't seem to conclude) but also then forgetting to move over to using it.

However, judging by your most recent comments, I'm glad I didn't spend any time on it!

Will