Support for Generic PCI Host Controller
Subsystems (10)
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
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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
PATCH v7 2/4 PCI: ARM: add support for generic PCI host controller
In reply to Will DeaconThis 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
@@ -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
@@ -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
@@ -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
PATCH v7 3/4 MAINTAINERS: add entry for generic PCI host controller driver
In reply to Will DeaconAdd myself as the maintainer for the generic PCI host controller driver.
--- MAINTAINERS | 8 ++++++++ 1 file changed, 8 insertions(+)
MAINTAINERS +8 -0
@@ -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
PATCH v7 4/4 PCI: Generic Configuration Access Mechanism support
In reply to Will DeaconFrom: 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
@@ -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
@@ -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
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
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_datais the ARM specific structure that doesn't exist elsewhere, andsys->private_datawouldn't typically point to structpci_cfg_windowson 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
v7 cover Support for Generic PCI Host Controller
In reply to Will DeaconQuoted 8 lines · Will Deacon
- Removed redundant
MIGHT_HAVE_PCIselections 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
v7 cover Support for Generic PCI Host Controller
Hi Arnd,
Quoted 4 lines · Arnd Bergmann
Quoted 3 lines · Will Deacon
- Removed redundant
MIGHT_HAVE_PCIselections 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