adding PCI support to AXS10x
Subsystems (5)
v2 cover adding PCI support to AXS10x
This patch set has the goal to add suppport for DesignWare PCIe RC in ARC AXS10x. It includes the necessary tweaks to the ARC architecture, necessary tweaks to the PCI subsystem and a new driver (pcie-snpsdev). This new driver will be used extensively in the PCIe RC Prototyping Kit.
The patches were produced against Bjorn Helgaas' repository. It was properly tested in an IP Prototyping Kit.
Joao Pinto (2):
PCI support added to ARC
add new platform driver for PCI RC
.../devicetree/bindings/pci/pcie-snpsdev.txt | 28 ++ MAINTAINERS | 7 + arch/arc/Kconfig | 23 ++ arch/arc/include/asm/dma.h | 5 + arch/arc/include/asm/io.h | 10 + arch/arc/include/asm/mach/pci.h | 97 ++++++ arch/arc/include/asm/pci.h | 34 ++ arch/arc/kernel/Makefile | 1 + arch/arc/kernel/pcibios.c | 358 +++++++++++++++++++++ arch/arc/mm/ioremap.c | 10 +- arch/arc/plat-axs10x/Kconfig | 1 + drivers/pci/Makefile | 1 + drivers/pci/host/Kconfig | 5 + drivers/pci/host/Makefile | 1 + drivers/pci/host/pcie-designware.c | 15 + drivers/pci/host/pcie-designware.h | 1 + drivers/pci/host/pcie-snpsdev.c | 288 +++++++++++++++++ 17 files changed, 884 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/pci/pcie-snpsdev.txt create mode 100644 arch/arc/include/asm/mach/pci.h create mode 100644 arch/arc/include/asm/pci.h create mode 100644 arch/arc/kernel/pcibios.c create mode 100644 drivers/pci/host/pcie-snpsdev.c
Signature · 1 line
1.8.1.5
PATCH v2 1/2 PCI support added to ARC
This patch adds PCI support to ARC and updates drivers/pci Makefile enabling the ARC arch to use the generic PCI setup functions.
---
Change v1 -> v2:
- In arch/arc/Kconfig, the new menu entry (Bus Configuration) was moved to the slot between sourcing of drivers/Kconfig and fs/Kconfig (Vineet Gupta)
- In arch/arc/plat-axs10x/Kconfig the "select MIGHT_HAVE_PCI" option was placed in order as suggested (Vineet Gupta)
- ioport_map() and ioport_unmap() were static inlined and included in the io.h (Vineet Gupta)
- pcibios_min_io and pcibios_min_mem declaration moved topcibios.c (Vineet Gupta)
- pr_err() replaced by dev_err() in pcibios_enable_device() (Bjorn Helgaas)
- string simplified in pcibios_enable_device() (Vineet Gupta)
- pci_host_bridge_window structure was replaced by resource_entry structure, and list_for_each_entry() for resource_list_for_each_entry() in pcibios.c
arch/arc/Kconfig | 23 +++ arch/arc/include/asm/dma.h | 5 + arch/arc/include/asm/io.h | 10 ++ arch/arc/include/asm/mach/pci.h | 97 +++++++++++ arch/arc/include/asm/pci.h | 34 ++++ arch/arc/kernel/Makefile | 1 + arch/arc/kernel/pcibios.c | 358 ++++++++++++++++++++++++++++++++++++++++ arch/arc/mm/ioremap.c | 10 +- arch/arc/plat-axs10x/Kconfig | 1 + drivers/pci/Makefile | 1 + 10 files changed, 539 insertions(+), 1 deletion(-) create mode 100644 arch/arc/include/asm/mach/pci.h create mode 100644 arch/arc/include/asm/pci.h create mode 100644 arch/arc/kernel/pcibios.c
arch/arc/Kconfig +23 -0
@@ -19,6 +19,7 @@ config ARC select GENERIC_FIND_FIRST_BIT # for now, we don't need GENERIC_IRQ_PROBE, CONFIG_GENERIC_IRQ_CHIP select GENERIC_IRQ_SHOW + select GENERIC_PCI_IOMAP select GENERIC_PENDING_IRQ if SMP select GENERIC_SMP_IDLE_THREAD select HAVE_ARCH_KGDB
@@ -39,6 +40,9 @@ config ARC select PERF_USE_VMALLOC select HAVE_DEBUG_STACKOVERFLOW +config MIGHT_HAVE_PCI + bool + config TRACE_IRQFLAGS_SUPPORT def_bool y
@@ -570,6 +574,25 @@ endmenu # "ARC Architecture Configuration" source "mm/Kconfig" source "net/Kconfig" source "drivers/Kconfig" + +menu "Bus Support" + +config PCI + bool "PCI support" if MIGHT_HAVE_PCI + help + PCI is the name of a bus system, i.e. the way the CPU talks to the other stuff inside + your box.Find out if your board/platform have PCI. + Note: PCIE support for Synopsys Device will be available only when + HAPS DX is configured with PCIE RC bitmap. If you have PCI, say Y, otherwise N. + +config PCI_SYSCALL + def_bool PCI + +source "drivers/pci/Kconfig" +source "drivers/pci/pcie/Kconfig" + +endmenu + source "fs/Kconfig" source "arch/arc/Kconfig.debug" source "security/Kconfig"
arch/arc/include/asm/dma.h +5 -0
@@ -10,5 +10,10 @@#define ASM_ARC_DMA_H #define MAX_DMA_ADDRESS 0xC0000000 +#ifdef CONFIG_PCI +extern int isa_dma_bridge_buggy; +#else +#define isa_dma_bridge_buggy (0) +#endif #endif
arch/arc/include/asm/io.h +10 -0
@@ -16,7 +16,17 @@extern void __iomem *ioremap (unsigned long physaddr,unsigned long size);extern void __iomem *ioremap_prot (phys_addr_t offset,unsigned long size,unsigned long flags); +static inline void __iomem *ioport_map (unsigned long port,unsigned int nr) +{ +return (void __iomem *)port; +} + +static inline void ioport_unmap (void __iomem *addr) +{ +} +extern void iounmap (const void __iomem *addr); +extern int pci_ioremap_io (unsigned int offset,phys_addr_t phys_addr);#define ioremap_nocache (phy, sz) ioremap(phy, sz)#define ioremap_wc (phy, sz) ioremap(phy, sz)
arch/arc/include/asm/mach/pci.h new file +97 -0
97 lines not on this page · raw message
arch/arc/include/asm/pci.h new file +34 -0
@@ -0,0 +1,34 @@ +/* +* Copyright (C) 2015-2016 Synopsys, Inc. (www.synopsys.com) +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#ifndef _ASM_ARC_PCI_H +#define _ASM_ARC_PCI_H + +#ifdef __KERNEL__ +#include <asm-generic/pci-dma-compat.h> +#include <asm-generic/pci-bridge.h> + +#include <asm/mach/pci.h> /* for pci_sys_data */ + +extern unsigned long pcibios_min_io; +#define PCIBIOS_MIN_IO pcibios_min_io +extern unsigned long pcibios_min_mem; +#define PCIBIOS_MIN_MEM pcibios_min_mem + +#define pcibios_assign_all_busses () 1 +/* +* The PCI address space does equal the physical memory address space. +* The networking and block device layers use this boolean for bounce +* buffer decisions. +*/ +#define PCI_DMA_BUS_IS_PHYS (1) + +#endif /* __KERNEL__ */ + +#endif /* _ASM_ARC_PCI_H */ +
arch/arc/kernel/Makefile +1 -0
@@ -12,6 +12,7 @@ obj-y := arcksyms.o setup.o irq.o time.o reset.o ptrace.o process.o devtree.o obj-y += signal.o traps.o sys.o troubleshoot.o stacktrace.o disasm.o clk.o obj-$(CONFIG_ISA_ARCOMPACT) += entry-compact.o intc-compact.o obj-$(CONFIG_ISA_ARCV2) += entry-arcv2.o intc-arcv2.o +obj-$(CONFIG_PCI) += pcibios.o obj-$(CONFIG_MODULES) += arcksyms.o module.o obj-$(CONFIG_SMP) += smp.o
arch/arc/kernel/pcibios.c new file +358 -0
358 lines not on this page · raw message
arch/arc/mm/ioremap.c +9 -1
@@ -13,6 +13,7 @@#include <linux/mm.h> #include <linux/slab.h> #include <linux/cache.h> +#include <linux/sizes.h> void __iomem *ioremap (unsigned long paddr,unsigned long size) {
@@ -80,7 +81,6 @@ void __iomem *ioremap_prot(phys_addr_t paddr, unsigned long size, }EXPORT_SYMBOL (ioremap_prot); -void iounmap (const void __iomem *addr) {if (addr >= (void __force __iomem *)ARC_UNCACHED_ADDR_SPACE )
@@ -89,3 +89,11 @@ void iounmap(const void __iomem *addr)vfree ((void *)(PAGE_MASK & (unsigned long __force )addr)); }EXPORT_SYMBOL (iounmap); + +#ifdef CONFIG_PCI +int pci_ioremap_io (unsigned int offset,phys_addr_t phys_addr) +{ +return ioremap_nocache (phys_addr + offset,SZ_64K ); +} +EXPORT_SYMBOL_GPL (pci_ioremap_io); +#endif
arch/arc/plat-axs10x/Kconfig +1 -0
@@ -11,6 +11,7 @@ menuconfig ARC_PLAT_AXS10X select DW_APB_ICTL select GPIO_DWAPB select OF_GPIO + select MIGHT_HAVE_PCI select GENERIC_IRQ_CHIP select ARCH_REQUIRE_GPIOLIB help
drivers/pci/Makefile +1 -0
@@ -32,6 +32,7 @@ obj-$(CONFIG_PCI_IOV) += iov.o # Some architectures use the generic PCI setup functions # obj-$(CONFIG_ALPHA) += setup-irq.o +obj-$(CONFIG_ARC) += setup-irq.o obj-$(CONFIG_ARM) += setup-irq.o obj-$(CONFIG_ARM64) += setup-irq.o obj-$(CONFIG_UNICORE32) += setup-irq.o
Signature · 1 line
1.8.1.5
Re: [PATCH v2 1/2] PCI support added to ARC
Quoted 4 lines · Joao Pinto
This patch adds PCI support to ARC and updates
drivers/pciMakefileenabling the ARC arch to use the generic PCI setup functions.Signed-off-by Joao Pinto <[email protected]>
Checkpatch complains about some whitespace errors (new blank lines at EOF).
Hmmm, almost all of this appears to be copied straight from arch/arm, but almost none of it is actually used. If that's true, it's good because you can make the patches much smaller. But it's a little bit bad, too, because it means we almost merged a bunch of dead code.
Quoted 196 lines
---
Change v1 -> v2:
- Inarch/arc/Kconfig, the new menu entry (Bus Configuration) was moved to the slot between sourcing ofdrivers/Kconfigand fs/Kconfig (Vineet Gupta)
- Inarch/arc/plat-axs10x/Kconfigthe "selectMIGHT_HAVE_PCI" option was placed in order as suggested (Vineet Gupta)
-ioport_map()andioport_unmap()were static inlined and included in theio.h(Vineet Gupta)
-pcibios_min_ioandpcibios_min_memdeclaration moved topcibios.c(Vineet Gupta)
-pr_err()replaced bydev_err()inpcibios_enable_device()(Bjorn Helgaas)
- string simplified inpcibios_enable_device()(Vineet Gupta)
-pci_host_bridge_windowstructure was replaced byresource_entrystructure, andlist_for_each_entry()forresource_list_for_each_entry()inpcibios.carch/arc/Kconfig | 23 +++ arch/arc/include/asm/dma.h | 5 + arch/arc/include/asm/io.h | 10 ++ arch/arc/include/asm/mach/pci.h | 97 +++++++++++ arch/arc/include/asm/pci.h | 34 ++++ arch/arc/kernel/Makefile | 1 + arch/arc/kernel/pcibios.c | 358 ++++++++++++++++++++++++++++++++++++++++ arch/arc/mm/ioremap.c | 10 +- arch/arc/plat-axs10x/Kconfig | 1 + drivers/pci/Makefile | 1 + 10 files changed, 539 insertions(+), 1 deletion(-) create mode 100644 arch/arc/include/asm/mach/pci.h create mode 100644 arch/arc/include/asm/pci.h create mode 100644 arch/arc/kernel/pcibios.carch/arc/Kconfig +23
-0@@ -19,6 +19,7 @@ config ARC select GENERIC_FIND_FIRST_BIT # for now, we don't need GENERIC_IRQ_PROBE, CONFIG_GENERIC_IRQ_CHIP select GENERIC_IRQ_SHOW + select GENERIC_PCI_IOMAP select GENERIC_PENDING_IRQ if SMP select GENERIC_SMP_IDLE_THREAD select HAVE_ARCH_KGDB@@ -39,6 +40,9 @@ config ARC select PERF_USE_VMALLOC select HAVE_DEBUG_STACKOVERFLOW +config MIGHT_HAVE_PCI + bool + config TRACE_IRQFLAGS_SUPPORT def_bool y@@ -570,6 +574,25 @@ endmenu # "ARC Architecture Configuration" source "mm/Kconfig" source "net/Kconfig" source "drivers/Kconfig" + +menu "Bus Support" + +config PCI + bool "PCI support" if MIGHT_HAVE_PCI + help + PCI is the name of a bus system, i.e. the way the CPU talks to the other stuff inside + your box.Find out if your board/platform have PCI. + Note: PCIE support for Synopsys Device will be available only when + HAPS DX is configured with PCIE RC bitmap. If you have PCI, say Y, otherwise N. + +config PCI_SYSCALL + def_bool PCI + +source "drivers/pci/Kconfig" +source "drivers/pci/pcie/Kconfig" + +endmenu + source "fs/Kconfig" source "arch/arc/Kconfig.debug" source "security/Kconfig"arch/arc/include/asm/dma.h +5
-0@@ -10,5 +10,10 @@#define ASM_ARC_DMA_H #define MAX_DMA_ADDRESS 0xC0000000 +#ifdef CONFIG_PCI +extern int isa_dma_bridge_buggy; +#else +#define isa_dma_bridge_buggy (0) +#endif #endif arch/arc/include/asm/io.h +10
-0@@ -16,7 +16,17 @@extern void __iomem *ioremap (unsigned long physaddr,unsigned long size);extern void __iomem *ioremap_prot (phys_addr_t offset,unsigned long size,unsigned long flags); +static inline void __iomem *ioport_map (unsigned long port,unsigned int nr) +{ +return (void __iomem *)port; +} + +static inline void ioport_unmap (void __iomem *addr) +{ +} +extern void iounmap (const void __iomem *addr); +extern int pci_ioremap_io (unsigned int offset,phys_addr_t phys_addr);#define ioremap_nocache (phy, sz) ioremap(phy, sz)#define ioremap_wc (phy, sz) ioremap(phy, sz)arch/arc/include/asm/mach/pci.h new file +75
-0@@ -0,0 +1,97 @@ +/* +* arch/arc/include/asm/mach/pci.h +* +* Copyright (C) 2004-2014 Synopsys, Inc. (www.synopsys.com) +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#ifndef __ASM_MACH_PCI_H +#define __ASM_MACH_PCI_H + +#include <linux/ioport.h> + +struct pci_sys_data ; +struct pci_ops ; +struct pci_bus ; +struct device ; + +struct hw_pci { +#ifdef CONFIG_PCI_DOMAINS +int domain; +#endif +struct pci_ops *ops; +int nr_controllers; +void **private_data; +int (*setup)(int nr,struct pci_sys_data *); +struct pci_bus *(*scan)(int nr,struct pci_sys_data *); +void (*preinit)(void ); +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); +void (*add_bus)(struct pci_bus *bus); +void (*remove_bus)(struct pci_bus *bus); +}; + +/* +* Per-controller structure +*/ +struct pci_sys_data { +#ifdef CONFIG_PCI_DOMAINS +int domain; +#endif +struct list_head node; +int busnr;/* primary bus number */ +u64 mem_offset;/* bus->cpu memory mapping offset */ +unsigned long io_offset;/* bus->cpu IO mapping offset */ +struct pci_bus *bus;/* PCI bus */ +struct list_head resources;/* root bus resources (apertures) */ +struct resource io_res; +char io_res_name[12 ]; +/* Bridge swizzling */ +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 (*add_bus)(struct pci_bus *bus); +void (*remove_bus)(struct pci_bus *bus); +void *private_data;/* platform controller private data */ +}; + +/* +* Call this with your hw_pci struct to initialise the PCI system. +*/
arch/arc/include/asm/mach/pci.h line 85
Quoted 10 lines
arch/arc/include/asm/mach/pci.h new file +10
-0+void pci_common_init_dev (struct device *,struct hw_pci *); + +/* +* Compatibility wrapper for older platforms that do not care about +* passing the parent device. +*/ +static inline void pci_common_init (struct hw_pci *hw) +{ +pci_common_init_dev (NULL , hw); +}
All the above stuff (hw_pci, pci_sys_data, pci_common_init_dev(), pci_common_init()) appears to be unused.
Quoted 120 lines
arch/arc/include/asm/mach/pci.h new file +12
-0+ +/* +* Setup early fixed I/O mapping. +*/ +#if defined(CONFIG_PCI ) +extern void pci_map_io_early (unsigned long pfn); +#else +static inline void pci_map_io_early (unsigned long pfn) {} +#endif + +#endif /* __ASM_MACH_PCI_H */ +arch/arc/include/asm/pci.h new file +34
-0@@ -0,0 +1,34 @@ +/* +* Copyright (C) 2015-2016 Synopsys, Inc. (www.synopsys.com) +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#ifndef _ASM_ARC_PCI_H +#define _ASM_ARC_PCI_H + +#ifdef __KERNEL__ +#include <asm-generic/pci-dma-compat.h> +#include <asm-generic/pci-bridge.h> + +#include <asm/mach/pci.h> /* for pci_sys_data */ + +extern unsigned long pcibios_min_io; +#define PCIBIOS_MIN_IO pcibios_min_io +extern unsigned long pcibios_min_mem; +#define PCIBIOS_MIN_MEM pcibios_min_mem + +#define pcibios_assign_all_busses () 1 +/* +* The PCI address space does equal the physical memory address space. +* The networking and block device layers use this boolean for bounce +* buffer decisions. +*/ +#define PCI_DMA_BUS_IS_PHYS (1) + +#endif /* __KERNEL__ */ + +#endif /* _ASM_ARC_PCI_H */ +arch/arc/kernel/Makefile +1
-0@@ -12,6 +12,7 @@ obj-y := arcksyms.o setup.o irq.o time.o reset.o ptrace.o process.o devtree.o obj-y += signal.o traps.o sys.o troubleshoot.o stacktrace.o disasm.o clk.o obj-$(CONFIG_ISA_ARCOMPACT) += entry-compact.o intc-compact.o obj-$(CONFIG_ISA_ARCV2) += entry-arcv2.o intc-arcv2.o +obj-$(CONFIG_PCI) += pcibios.o obj-$(CONFIG_MODULES) += arcksyms.o module.o obj-$(CONFIG_SMP) += smp.oarch/arc/kernel/pcibios.c new file +50
-0@@ -0,0 +1,358 @@ +/* +* Copyright (C) 2014-2015 Synopsys, Inc. (www.synopsys.com) +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +* +*/ + +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/delay.h> +#include <linux/string.h> +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/errno.h> +#include <linux/bootmem.h> +#include <linux/sizes.h> +#include <linux/slab.h> + +#include <asm/pci.h> +#include <asm/mach/pci.h> + +unsigned long pcibios_min_io =0x100 ; +EXPORT_SYMBOL (pcibios_min_io); + +unsigned long pcibios_min_mem =0x100000 ; +EXPORT_SYMBOL (pcibios_min_mem); + +static int pcibios_init_resources (int busnr,struct pci_sys_data *sys) +{ +int ret; +struct resource_entry *window; + +if (list_empty (&sys->resources)) { +pci_add_resource_offset (&sys->resources, + &iomem_resource, sys->mem_offset); + } + +resource_list_for_each_entry (window, &sys->resources) { +if (resource_type (window->res) ==IORESOURCE_IO ) +return 0 ; + } + + sys->io_res.start = (busnr *SZ_64K ) ? : pcibios_min_io; + sys->io_res.end = (busnr +1 ) *SZ_64K -1 ; + sys->io_res.flags =IORESOURCE_IO ; + sys->io_res.name = sys->io_res_name; +sprintf (sys->io_res_name,"PCI%d I/O" , busnr); +
arch/arc/kernel/pcibios.c line 60
Quoted 10 lines
arch/arc/kernel/pcibios.c new file +10
-0+ ret =request_resource (&ioport_resource, &sys->io_res); +if (ret) { +pr_err ("PCI: unable to allocate I/O port region (%d)\n" , ret); +return ret; + } +pci_add_resource_offset (&sys->resources, &sys->io_res, + sys->io_offset); + +return 0 ; +}
Appears unused.
Quoted 45 lines
arch/arc/kernel/pcibios.c new file +45
-0+static void pcibios_init_hw (struct device *parent,struct hw_pci *hw, +struct list_head *head) +{ +struct pci_sys_data *sys =NULL ; +int ret; +int nr, busnr; + +for (nr = busnr =0 ; nr < hw->nr_controllers; nr++) { + sys =kzalloc (sizeof (struct pci_sys_data ),GFP_KERNEL ); +if (!sys) +panic ("PCI: unable to allocate sys data!" ); + +#ifdef CONFIG_PCI_DOMAINS + sys->domain = hw->domain; +#endif + sys->busnr = busnr; + sys->swizzle = hw->swizzle; + sys->map_irq = hw->map_irq; + sys->align_resource = hw->align_resource; + sys->add_bus = hw->add_bus; + sys->remove_bus = hw->remove_bus; +INIT_LIST_HEAD (&sys->resources); + + +if (hw->private_data) + sys->private_data = hw->private_data[nr]; + + ret = hw->setup (nr, sys); + +if (ret >0 ) { + ret =pcibios_init_resources (nr, sys); +if (ret) { +kfree (sys); +break ; + } + +if (hw->scan) + sys->bus = hw->scan (nr, sys); +else + sys->bus =pci_scan_root_bus (parent, sys->busnr, + hw->ops, sys, &sys->resources); + +if (!sys->bus) +panic ("PCI: unable to scan bus!" ); +
arch/arc/kernel/pcibios.c line 117
Quoted 10 lines
arch/arc/kernel/pcibios.c new file +10
-0+ busnr = sys->bus->busn_res.end +1 ; + +list_add (&sys->node, head); + }else { +kfree (sys); +if (ret <0 ) +break ; + } + } +}
Appears unused.
arch/arc/kernel/pcibios.c line 130
Quoted 12 lines
arch/arc/kernel/pcibios.c new file +12
-0+int pcibios_root_bridge_prepare (struct pci_host_bridge *bridge) +{ +return 0 ; +} + +void pcibios_add_bus (struct pci_bus *bus) +{ +} + +void pcibios_remove_bus (struct pci_bus *bus) +{ +}
The above three are Unnecessary since drivers/pci/probe.c defines default (weak) versions.
Quoted 17 lines
arch/arc/kernel/pcibios.c new file +17
-0+/* +* Swizzle the device pin each time we cross a bridge. If a platform does +* not provide a swizzle function, we perform the standard PCI swizzling. +* +* The default swizzling walks up the bus tree one level at a time, applying +* the standard swizzle function at each step, stopping when it finds the PCI +* root bus. This will return the slot number of the bridge device on the +* root bus and the interrupt pin on that device which should correspond +* with the downstream device interrupt. +* +* Platforms may override this, in which case the slot and pin returned +* depend entirely on the platform code. However, please note that the +* PCI standard swizzle is implemented on plug-in cards and Cardbus based +* PCI extenders, so it can not be ignored. +*/ +static u8 pcibios_swizzle (struct pci_dev *dev,u8 *pin) +{
arch/arc/kernel/pcibios.c line 158
Quoted 10 lines
arch/arc/kernel/pcibios.c new file +10
-0+int slot; +struct pci_sys_data *sys = dev->sysdata; + +if (sys->swizzle) + slot = sys->swizzle (dev, pin); +else + slot =pci_common_swizzle (dev, pin); + +return slot; +}
Appears unused.
arch/arc/kernel/pcibios.c line 172
Quoted 13 lines
arch/arc/kernel/pcibios.c new file +13
-0+/* +* Map a slot/pin to an IRQ. +*/ +static int pcibios_map_irq (const struct pci_dev *dev,u8 slot,u8 pin) +{ +struct pci_sys_data *sys = dev->sysdata; +int irq =-1 ; + +if (sys->map_irq) + irq = sys->map_irq (dev, slot, pin); + +return irq; +}
Appears unused.
Quoted 25 lines
arch/arc/kernel/pcibios.c new file +25
-0+void pci_common_init_dev (struct device *parent,struct hw_pci *hw) +{ +struct pci_sys_data *sys; +LIST_HEAD (head); + +pci_add_flags (PCI_REASSIGN_ALL_RSRC ); +if (hw->preinit) + hw->preinit (); +pcibios_init_hw (parent, hw, &head); +if (hw->postinit) + hw->postinit (); + +pci_fixup_irqs (pcibios_swizzle, pcibios_map_irq); + +list_for_each_entry (sys, &head, node) { +struct pci_bus *bus = sys->bus; + +if (!pci_has_flag (PCI_PROBE_ONLY )) { +/* +* Size the bridge windows. +*/ +pci_bus_size_bridges (bus); + +/* +* Assign resources.
arch/arc/kernel/pcibios.c line 208
Quoted 10 lines
arch/arc/kernel/pcibios.c new file +10
-0+*/ +pci_bus_assign_resources (bus); + } + +/* +* Tell drivers about devices found. +*/ +pci_bus_add_devices (bus); + } +}
Appears unused.
Quoted 41 lines
arch/arc/kernel/pcibios.c new file +41
-0+/* +* We don't have to worry about legacy ISA devices, so nothing to do here +*/ +resource_size_t pcibios_align_resource (void *data,const struct resource *res, +resource_size_t size,resource_size_t align) +{ +return res->start; +} + +/** +* pcibios_enable_device - Enable I/O and memory. +* @dev: PCI device to be enabled +*/ +int pcibios_enable_device (struct pci_dev *pci_dev,int mask) +{ +u16 cmd, old_cmd; +int idx; +struct resource *r; + +pci_read_config_word (pci_dev,PCI_COMMAND , &cmd); + old_cmd = cmd; +for (idx =0 ; idx <6 ; idx++) { +/* Only set up the requested stuff */ +if (!(mask & (1 << idx))) +continue ; + + r = pci_dev->resource + idx; +if (!r->start && r->end) { +dev_err (&pci_dev->dev,"PCI: Device %s not available\n" , +pci_name (pci_dev)); +return -EINVAL ; + } +if (r->flags &IORESOURCE_IO ) + cmd |=PCI_COMMAND_IO ; +if (r->flags &IORESOURCE_MEM ) + cmd |=PCI_COMMAND_MEMORY ; + } + +/* +* Bridges (eg, cardbus bridges) need to be fully enabled +*/
arch/arc/kernel/pcibios.c line 260
Quoted 10 lines
arch/arc/kernel/pcibios.c new file +10
-0+if ((pci_dev->class >>16 ) ==PCI_BASE_CLASS_BRIDGE ) + cmd |=PCI_COMMAND_IO |PCI_COMMAND_MEMORY ; + +if (cmd != old_cmd) { +pr_info ("PCI: enabling device %s (%04x -> %04x)\n" , +pci_name (pci_dev), old_cmd, cmd); +pci_write_config_word (pci_dev,PCI_COMMAND , cmd); + } +return 0 ; +}
There's a default (weak) version of pcibios_enable_device(). You should omit this definition and use the default unless your arch requires something special.
Quoted 88 lines
arch/arc/kernel/pcibios.c new file +88
-0+ +/* +* If the bus contains any of these devices, then we must not turn on +* parity checking of any kind. Currently this is CyberPro 20x0 only. +*/ +static inline int pdev_bad_for_parity (struct pci_dev *dev) +{ +return ((dev->vendor ==PCI_VENDOR_ID_INTERG && + (dev->device ==PCI_DEVICE_ID_INTERG_2000 || + dev->device ==PCI_DEVICE_ID_INTERG_2010 )) || + (dev->vendor ==PCI_VENDOR_ID_ITE && + dev->device ==PCI_DEVICE_ID_ITE_8152 )); + +} + +/* +* pcibios_fixup_bus - Called after each bus is probed, +* but before its children are examined. +*/ +void pcibios_fixup_bus (struct pci_bus *bus) +{ +struct pci_dev *dev; +u16 features =PCI_COMMAND_SERR |PCI_COMMAND_PARITY + |PCI_COMMAND_FAST_BACK ; + +/* +* Walk the devices on this bus, working out what we can +* and can't support. +*/ +list_for_each_entry (dev, &bus->devices, bus_list) { +u16 status; + +pci_read_config_word (dev,PCI_STATUS , &status); + +/* +* If any device on this bus does not support fast back +* to back transfers, then the bus as a whole is not able +* to support them. Having fast back to back transfers +* on saves us one PCI cycle per transaction. +*/ +if (!(status &PCI_STATUS_FAST_BACK )) + features &= ~PCI_COMMAND_FAST_BACK ; + +if (pdev_bad_for_parity (dev)) + features &= ~(PCI_COMMAND_SERR |PCI_COMMAND_PARITY ); + +switch (dev->class >>8 ) { +case PCI_CLASS_BRIDGE_PCI : +pci_read_config_word (dev,PCI_BRIDGE_CONTROL , &status); + status |=PCI_BRIDGE_CTL_PARITY + |PCI_BRIDGE_CTL_MASTER_ABORT ; + status &= ~(PCI_BRIDGE_CTL_BUS_RESET + |PCI_BRIDGE_CTL_FAST_BACK ); +pci_write_config_word (dev,PCI_BRIDGE_CONTROL , status); +break ; + +case PCI_CLASS_BRIDGE_CARDBUS : +pci_read_config_word (dev,PCI_CB_BRIDGE_CONTROL , + &status); + status |=PCI_CB_BRIDGE_CTL_PARITY + |PCI_CB_BRIDGE_CTL_MASTER_ABORT ; +pci_write_config_word (dev,PCI_CB_BRIDGE_CONTROL , + status); +break ; + } + } + +/* +* Now walk the devices again, this time setting them up. +*/ +list_for_each_entry (dev, &bus->devices, bus_list) { +u16 cmd; + +pci_read_config_word (dev,PCI_COMMAND , &cmd); + cmd |= features; +pci_write_config_word (dev,PCI_COMMAND , cmd); + +pci_write_config_byte (dev,PCI_CACHE_LINE_SIZE , +L1_CACHE_BYTES >>2 ); + } + +/* +* Propagate the flags to the PCI bridge. +*/ +if (bus->self && bus->self->hdr_type ==PCI_HEADER_TYPE_BRIDGE ) { +if (features &PCI_COMMAND_FAST_BACK ) + bus->bridge_ctl |=PCI_BRIDGE_CTL_FAST_BACK ; +if (features &PCI_COMMAND_PARITY )
arch/arc/kernel/pcibios.c line 358
Quoted 10 lines
arch/arc/kernel/pcibios.c new file +10
-0+ bus->bridge_ctl |=PCI_BRIDGE_CTL_PARITY ; + } + +/* +* Report what we did for this bus +*/ +pr_info ("PCI: bus%d: Fast back to back transfers %sabled\n" , + bus->number, (features &PCI_COMMAND_FAST_BACK ) ?"en" :"dis" ); +} +EXPORT_SYMBOL (pcibios_fixup_bus);
This pcibios_fixup_bus() implementation has been blindly copied all over the place, but I don't think it's relevant for most arches. I think you could probably make it an empty function as on arm64.
Quoted 63 lines
arch/arc/mm/ioremap.c +9
-1@@ -13,6 +13,7 @@#include <linux/mm.h> #include <linux/slab.h> #include <linux/cache.h> +#include <linux/sizes.h> void __iomem *ioremap (unsigned long paddr,unsigned long size) {@@ -80,7 +81,6 @@ void __iomem *ioremap_prot(phys_addr_t paddr, unsigned long size, }EXPORT_SYMBOL (ioremap_prot); -void iounmap (const void __iomem *addr) {if (addr >= (void __force __iomem *)ARC_UNCACHED_ADDR_SPACE )@@ -89,3 +89,11 @@ void iounmap(const void __iomem *addr)vfree ((void *)(PAGE_MASK & (unsigned long __force )addr)); }EXPORT_SYMBOL (iounmap); + +#ifdef CONFIG_PCI +int pci_ioremap_io (unsigned int offset,phys_addr_t phys_addr) +{ +return ioremap_nocache (phys_addr + offset,SZ_64K ); +} +EXPORT_SYMBOL_GPL (pci_ioremap_io); +#endif arch/arc/plat-axs10x/Kconfig +1
-0@@ -11,6 +11,7 @@ menuconfig ARC_PLAT_AXS10X select DW_APB_ICTL select GPIO_DWAPB select OF_GPIO + select MIGHT_HAVE_PCI select GENERIC_IRQ_CHIP select ARCH_REQUIRE_GPIOLIB helpdrivers/pci/Makefile +1
-0@@ -32,6 +32,7 @@ obj-$(CONFIG_PCI_IOV) += iov.o # Some architectures use the generic PCI setup functions # obj-$(CONFIG_ALPHA) += setup-irq.o +obj-$(CONFIG_ARC) += setup-irq.o obj-$(CONFIG_ARM) += setup-irq.o obj-$(CONFIG_ARM64) += setup-irq.o obj-$(CONFIG_UNICORE32) += setup-irq.oSignature · 6 lines
1.8.1.5 -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 1/2] PCI support added to ARC
Hi Bjorn,
Thanks for the review. I am going to simplify the code and send a v3 patch set.
Joao
Quoted 737 lines · Bjorn Helgaas
Quoted 4 lines · Joao Pinto
This patch adds PCI support to ARC and updates
drivers/pciMakefileenabling the ARC arch to use the generic PCI setup functions.Signed-off-by Joao Pinto <[email protected]>Checkpatch complains about some whitespace errors (new blank lines at EOF).
Hmmm, almost all of this appears to be copied straight from
arch/arm, but almost none of it is actually used. If that's true, it's good because you can make the patches much smaller. But it's a little bit bad, too, because it means we almost merged a bunch of dead code.Quoted 196 lines
---
Change v1 -> v2:
- Inarch/arc/Kconfig, the new menu entry (Bus Configuration) was moved to the slot between sourcing ofdrivers/Kconfigand fs/Kconfig (Vineet Gupta)
- Inarch/arc/plat-axs10x/Kconfigthe "selectMIGHT_HAVE_PCI" option was placed in order as suggested (Vineet Gupta)
-ioport_map()andioport_unmap()were static inlined and included in theio.h(Vineet Gupta)
-pcibios_min_ioandpcibios_min_memdeclaration moved topcibios.c(Vineet Gupta)
-pr_err()replaced bydev_err()inpcibios_enable_device()(Bjorn Helgaas)
- string simplified inpcibios_enable_device()(Vineet Gupta)
-pci_host_bridge_windowstructure was replaced byresource_entrystructure, andlist_for_each_entry()forresource_list_for_each_entry()inpcibios.carch/arc/Kconfig | 23 +++ arch/arc/include/asm/dma.h | 5 + arch/arc/include/asm/io.h | 10 ++ arch/arc/include/asm/mach/pci.h | 97 +++++++++++ arch/arc/include/asm/pci.h | 34 ++++ arch/arc/kernel/Makefile | 1 + arch/arc/kernel/pcibios.c | 358 ++++++++++++++++++++++++++++++++++++++++ arch/arc/mm/ioremap.c | 10 +- arch/arc/plat-axs10x/Kconfig | 1 + drivers/pci/Makefile | 1 + 10 files changed, 539 insertions(+), 1 deletion(-) create mode 100644 arch/arc/include/asm/mach/pci.h create mode 100644 arch/arc/include/asm/pci.h create mode 100644 arch/arc/kernel/pcibios.carch/arc/Kconfig +23
-0@@ -19,6 +19,7 @@ config ARC select GENERIC_FIND_FIRST_BIT # for now, we don't need GENERIC_IRQ_PROBE, CONFIG_GENERIC_IRQ_CHIP select GENERIC_IRQ_SHOW + select GENERIC_PCI_IOMAP select GENERIC_PENDING_IRQ if SMP select GENERIC_SMP_IDLE_THREAD select HAVE_ARCH_KGDB@@ -39,6 +40,9 @@ config ARC select PERF_USE_VMALLOC select HAVE_DEBUG_STACKOVERFLOW +config MIGHT_HAVE_PCI + bool + config TRACE_IRQFLAGS_SUPPORT def_bool y@@ -570,6 +574,25 @@ endmenu # "ARC Architecture Configuration" source "mm/Kconfig" source "net/Kconfig" source "drivers/Kconfig" + +menu "Bus Support" + +config PCI + bool "PCI support" if MIGHT_HAVE_PCI + help + PCI is the name of a bus system, i.e. the way the CPU talks to the other stuff inside + your box.Find out if your board/platform have PCI. + Note: PCIE support for Synopsys Device will be available only when + HAPS DX is configured with PCIE RC bitmap. If you have PCI, say Y, otherwise N. + +config PCI_SYSCALL + def_bool PCI + +source "drivers/pci/Kconfig" +source "drivers/pci/pcie/Kconfig" + +endmenu + source "fs/Kconfig" source "arch/arc/Kconfig.debug" source "security/Kconfig"arch/arc/include/asm/dma.h +5
-0@@ -10,5 +10,10 @@#define ASM_ARC_DMA_H #define MAX_DMA_ADDRESS 0xC0000000 +#ifdef CONFIG_PCI +extern int isa_dma_bridge_buggy; +#else +#define isa_dma_bridge_buggy (0) +#endif #endif arch/arc/include/asm/io.h +10
-0@@ -16,7 +16,17 @@extern void __iomem *ioremap (unsigned long physaddr,unsigned long size);extern void __iomem *ioremap_prot (phys_addr_t offset,unsigned long size,unsigned long flags); +static inline void __iomem *ioport_map (unsigned long port,unsigned int nr) +{ +return (void __iomem *)port; +} + +static inline void ioport_unmap (void __iomem *addr) +{ +} +extern void iounmap (const void __iomem *addr); +extern int pci_ioremap_io (unsigned int offset,phys_addr_t phys_addr);#define ioremap_nocache (phy, sz) ioremap(phy, sz)#define ioremap_wc (phy, sz) ioremap(phy, sz)arch/arc/include/asm/mach/pci.h new file +75
-0@@ -0,0 +1,97 @@ +/* +* arch/arc/include/asm/mach/pci.h +* +* Copyright (C) 2004-2014 Synopsys, Inc. (www.synopsys.com) +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#ifndef __ASM_MACH_PCI_H +#define __ASM_MACH_PCI_H + +#include <linux/ioport.h> + +struct pci_sys_data ; +struct pci_ops ; +struct pci_bus ; +struct device ; + +struct hw_pci { +#ifdef CONFIG_PCI_DOMAINS +int domain; +#endif +struct pci_ops *ops; +int nr_controllers; +void **private_data; +int (*setup)(int nr,struct pci_sys_data *); +struct pci_bus *(*scan)(int nr,struct pci_sys_data *); +void (*preinit)(void ); +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); +void (*add_bus)(struct pci_bus *bus); +void (*remove_bus)(struct pci_bus *bus); +}; + +/* +* Per-controller structure +*/ +struct pci_sys_data { +#ifdef CONFIG_PCI_DOMAINS +int domain; +#endif +struct list_head node; +int busnr;/* primary bus number */ +u64 mem_offset;/* bus->cpu memory mapping offset */ +unsigned long io_offset;/* bus->cpu IO mapping offset */ +struct pci_bus *bus;/* PCI bus */ +struct list_head resources;/* root bus resources (apertures) */ +struct resource io_res; +char io_res_name[12 ]; +/* Bridge swizzling */ +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 (*add_bus)(struct pci_bus *bus); +void (*remove_bus)(struct pci_bus *bus); +void *private_data;/* platform controller private data */ +}; + +/* +* Call this with your hw_pci struct to initialise the PCI system. +*/ arch/arc/include/asm/mach/pci.h line 85
Quoted 10 lines
arch/arc/include/asm/mach/pci.h new file +10
-0+void pci_common_init_dev (struct device *,struct hw_pci *); + +/* +* Compatibility wrapper for older platforms that do not care about +* passing the parent device. +*/ +static inline void pci_common_init (struct hw_pci *hw) +{ +pci_common_init_dev (NULL , hw); +}All the above stuff (
hw_pci,pci_sys_data,pci_common_init_dev(),pci_common_init()) appears to be unused.Quoted 120 lines
arch/arc/include/asm/mach/pci.h new file +12
-0+ +/* +* Setup early fixed I/O mapping. +*/ +#if defined(CONFIG_PCI ) +extern void pci_map_io_early (unsigned long pfn); +#else +static inline void pci_map_io_early (unsigned long pfn) {} +#endif + +#endif /* __ASM_MACH_PCI_H */ +arch/arc/include/asm/pci.h new file +34
-0@@ -0,0 +1,34 @@ +/* +* Copyright (C) 2015-2016 Synopsys, Inc. (www.synopsys.com) +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#ifndef _ASM_ARC_PCI_H +#define _ASM_ARC_PCI_H + +#ifdef __KERNEL__ +#include <asm-generic/pci-dma-compat.h> +#include <asm-generic/pci-bridge.h> + +#include <asm/mach/pci.h> /* for pci_sys_data */ + +extern unsigned long pcibios_min_io; +#define PCIBIOS_MIN_IO pcibios_min_io +extern unsigned long pcibios_min_mem; +#define PCIBIOS_MIN_MEM pcibios_min_mem + +#define pcibios_assign_all_busses () 1 +/* +* The PCI address space does equal the physical memory address space. +* The networking and block device layers use this boolean for bounce +* buffer decisions. +*/ +#define PCI_DMA_BUS_IS_PHYS (1) + +#endif /* __KERNEL__ */ + +#endif /* _ASM_ARC_PCI_H */ +arch/arc/kernel/Makefile +1
-0@@ -12,6 +12,7 @@ obj-y := arcksyms.o setup.o irq.o time.o reset.o ptrace.o process.o devtree.o obj-y += signal.o traps.o sys.o troubleshoot.o stacktrace.o disasm.o clk.o obj-$(CONFIG_ISA_ARCOMPACT) += entry-compact.o intc-compact.o obj-$(CONFIG_ISA_ARCV2) += entry-arcv2.o intc-arcv2.o +obj-$(CONFIG_PCI) += pcibios.o obj-$(CONFIG_MODULES) += arcksyms.o module.o obj-$(CONFIG_SMP) += smp.oarch/arc/kernel/pcibios.c new file +50
-0@@ -0,0 +1,358 @@ +/* +* Copyright (C) 2014-2015 Synopsys, Inc. (www.synopsys.com) +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +* +*/ + +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/delay.h> +#include <linux/string.h> +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/errno.h> +#include <linux/bootmem.h> +#include <linux/sizes.h> +#include <linux/slab.h> + +#include <asm/pci.h> +#include <asm/mach/pci.h> + +unsigned long pcibios_min_io =0x100 ; +EXPORT_SYMBOL (pcibios_min_io); + +unsigned long pcibios_min_mem =0x100000 ; +EXPORT_SYMBOL (pcibios_min_mem); + +static int pcibios_init_resources (int busnr,struct pci_sys_data *sys) +{ +int ret; +struct resource_entry *window; + +if (list_empty (&sys->resources)) { +pci_add_resource_offset (&sys->resources, + &iomem_resource, sys->mem_offset); + } + +resource_list_for_each_entry (window, &sys->resources) { +if (resource_type (window->res) ==IORESOURCE_IO ) +return 0 ; + } + + sys->io_res.start = (busnr *SZ_64K ) ? : pcibios_min_io; + sys->io_res.end = (busnr +1 ) *SZ_64K -1 ; + sys->io_res.flags =IORESOURCE_IO ; + sys->io_res.name = sys->io_res_name; +sprintf (sys->io_res_name,"PCI%d I/O" , busnr); +arch/arc/kernel/pcibios.c line 60
Quoted 10 lines
arch/arc/kernel/pcibios.c new file +10
-0+ ret =request_resource (&ioport_resource, &sys->io_res); +if (ret) { +pr_err ("PCI: unable to allocate I/O port region (%d)\n" , ret); +return ret; + } +pci_add_resource_offset (&sys->resources, &sys->io_res, + sys->io_offset); + +return 0 ; +}Appears unused.
Quoted 45 lines
arch/arc/kernel/pcibios.c new file +45
-0+static void pcibios_init_hw (struct device *parent,struct hw_pci *hw, +struct list_head *head) +{ +struct pci_sys_data *sys =NULL ; +int ret; +int nr, busnr; + +for (nr = busnr =0 ; nr < hw->nr_controllers; nr++) { + sys =kzalloc (sizeof (struct pci_sys_data ),GFP_KERNEL ); +if (!sys) +panic ("PCI: unable to allocate sys data!" ); + +#ifdef CONFIG_PCI_DOMAINS + sys->domain = hw->domain; +#endif + sys->busnr = busnr; + sys->swizzle = hw->swizzle; + sys->map_irq = hw->map_irq; + sys->align_resource = hw->align_resource; + sys->add_bus = hw->add_bus; + sys->remove_bus = hw->remove_bus; +INIT_LIST_HEAD (&sys->resources); + + +if (hw->private_data) + sys->private_data = hw->private_data[nr]; + + ret = hw->setup (nr, sys); + +if (ret >0 ) { + ret =pcibios_init_resources (nr, sys); +if (ret) { +kfree (sys); +break ; + } + +if (hw->scan) + sys->bus = hw->scan (nr, sys); +else + sys->bus =pci_scan_root_bus (parent, sys->busnr, + hw->ops, sys, &sys->resources); + +if (!sys->bus) +panic ("PCI: unable to scan bus!" ); +arch/arc/kernel/pcibios.c line 117
Quoted 10 lines
arch/arc/kernel/pcibios.c new file +10
-0+ busnr = sys->bus->busn_res.end +1 ; + +list_add (&sys->node, head); + }else { +kfree (sys); +if (ret <0 ) +break ; + } + } +}Appears unused.
arch/arc/kernel/pcibios.c line 130
Quoted 12 lines
arch/arc/kernel/pcibios.c new file +12
-0+int pcibios_root_bridge_prepare (struct pci_host_bridge *bridge) +{ +return 0 ; +} + +void pcibios_add_bus (struct pci_bus *bus) +{ +} + +void pcibios_remove_bus (struct pci_bus *bus) +{ +}The above three are Unnecessary since
drivers/pci/probe.cdefines default (weak) versions.Quoted 17 lines
arch/arc/kernel/pcibios.c new file +17
-0+/* +* Swizzle the device pin each time we cross a bridge. If a platform does +* not provide a swizzle function, we perform the standard PCI swizzling. +* +* The default swizzling walks up the bus tree one level at a time, applying +* the standard swizzle function at each step, stopping when it finds the PCI +* root bus. This will return the slot number of the bridge device on the +* root bus and the interrupt pin on that device which should correspond +* with the downstream device interrupt. +* +* Platforms may override this, in which case the slot and pin returned +* depend entirely on the platform code. However, please note that the +* PCI standard swizzle is implemented on plug-in cards and Cardbus based +* PCI extenders, so it can not be ignored. +*/ +static u8 pcibios_swizzle (struct pci_dev *dev,u8 *pin) +{arch/arc/kernel/pcibios.c line 158
Quoted 10 lines
arch/arc/kernel/pcibios.c new file +10
-0+int slot; +struct pci_sys_data *sys = dev->sysdata; + +if (sys->swizzle) + slot = sys->swizzle (dev, pin); +else + slot =pci_common_swizzle (dev, pin); + +return slot; +}Appears unused.
arch/arc/kernel/pcibios.c line 172
Quoted 13 lines
arch/arc/kernel/pcibios.c new file +13
-0+/* +* Map a slot/pin to an IRQ. +*/ +static int pcibios_map_irq (const struct pci_dev *dev,u8 slot,u8 pin) +{ +struct pci_sys_data *sys = dev->sysdata; +int irq =-1 ; + +if (sys->map_irq) + irq = sys->map_irq (dev, slot, pin); + +return irq; +}Appears unused.
Quoted 25 lines
arch/arc/kernel/pcibios.c new file +25
-0+void pci_common_init_dev (struct device *parent,struct hw_pci *hw) +{ +struct pci_sys_data *sys; +LIST_HEAD (head); + +pci_add_flags (PCI_REASSIGN_ALL_RSRC ); +if (hw->preinit) + hw->preinit (); +pcibios_init_hw (parent, hw, &head); +if (hw->postinit) + hw->postinit (); + +pci_fixup_irqs (pcibios_swizzle, pcibios_map_irq); + +list_for_each_entry (sys, &head, node) { +struct pci_bus *bus = sys->bus; + +if (!pci_has_flag (PCI_PROBE_ONLY )) { +/* +* Size the bridge windows. +*/ +pci_bus_size_bridges (bus); + +/* +* Assign resources. arch/arc/kernel/pcibios.c line 208
Quoted 10 lines
arch/arc/kernel/pcibios.c new file +10
-0+*/ +pci_bus_assign_resources (bus); + } + +/* +* Tell drivers about devices found. +*/ +pci_bus_add_devices (bus); + } +}Appears unused.
Quoted 41 lines
arch/arc/kernel/pcibios.c new file +41
-0+/* +* We don't have to worry about legacy ISA devices, so nothing to do here +*/ +resource_size_t pcibios_align_resource (void *data,const struct resource *res, +resource_size_t size,resource_size_t align) +{ +return res->start; +} + +/** +* pcibios_enable_device - Enable I/O and memory. +* @dev: PCI device to be enabled +*/ +int pcibios_enable_device (struct pci_dev *pci_dev,int mask) +{ +u16 cmd, old_cmd; +int idx; +struct resource *r; + +pci_read_config_word (pci_dev,PCI_COMMAND , &cmd); + old_cmd = cmd; +for (idx =0 ; idx <6 ; idx++) { +/* Only set up the requested stuff */ +if (!(mask & (1 << idx))) +continue ; + + r = pci_dev->resource + idx; +if (!r->start && r->end) { +dev_err (&pci_dev->dev,"PCI: Device %s not available\n" , +pci_name (pci_dev)); +return -EINVAL ; + } +if (r->flags &IORESOURCE_IO ) + cmd |=PCI_COMMAND_IO ; +if (r->flags &IORESOURCE_MEM ) + cmd |=PCI_COMMAND_MEMORY ; + } + +/* +* Bridges (eg, cardbus bridges) need to be fully enabled +*/ arch/arc/kernel/pcibios.c line 260
Quoted 10 lines
arch/arc/kernel/pcibios.c new file +10
-0+if ((pci_dev->class >>16 ) ==PCI_BASE_CLASS_BRIDGE ) + cmd |=PCI_COMMAND_IO |PCI_COMMAND_MEMORY ; + +if (cmd != old_cmd) { +pr_info ("PCI: enabling device %s (%04x -> %04x)\n" , +pci_name (pci_dev), old_cmd, cmd); +pci_write_config_word (pci_dev,PCI_COMMAND , cmd); + } +return 0 ; +}There's a default (weak) version of
pcibios_enable_device(). You should omit this definition and use the default unless your arch requires something special.Quoted 88 lines
arch/arc/kernel/pcibios.c new file +88
-0+ +/* +* If the bus contains any of these devices, then we must not turn on +* parity checking of any kind. Currently this is CyberPro 20x0 only. +*/ +static inline int pdev_bad_for_parity (struct pci_dev *dev) +{ +return ((dev->vendor ==PCI_VENDOR_ID_INTERG && + (dev->device ==PCI_DEVICE_ID_INTERG_2000 || + dev->device ==PCI_DEVICE_ID_INTERG_2010 )) || + (dev->vendor ==PCI_VENDOR_ID_ITE && + dev->device ==PCI_DEVICE_ID_ITE_8152 )); + +} + +/* +* pcibios_fixup_bus - Called after each bus is probed, +* but before its children are examined. +*/ +void pcibios_fixup_bus (struct pci_bus *bus) +{ +struct pci_dev *dev; +u16 features =PCI_COMMAND_SERR |PCI_COMMAND_PARITY + |PCI_COMMAND_FAST_BACK ; + +/* +* Walk the devices on this bus, working out what we can +* and can't support. +*/ +list_for_each_entry (dev, &bus->devices, bus_list) { +u16 status; + +pci_read_config_word (dev,PCI_STATUS , &status); + +/* +* If any device on this bus does not support fast back +* to back transfers, then the bus as a whole is not able +* to support them. Having fast back to back transfers +* on saves us one PCI cycle per transaction. +*/ +if (!(status &PCI_STATUS_FAST_BACK )) + features &= ~PCI_COMMAND_FAST_BACK ; + +if (pdev_bad_for_parity (dev)) + features &= ~(PCI_COMMAND_SERR |PCI_COMMAND_PARITY ); + +switch (dev->class >>8 ) { +case PCI_CLASS_BRIDGE_PCI : +pci_read_config_word (dev,PCI_BRIDGE_CONTROL , &status); + status |=PCI_BRIDGE_CTL_PARITY + |PCI_BRIDGE_CTL_MASTER_ABORT ; + status &= ~(PCI_BRIDGE_CTL_BUS_RESET + |PCI_BRIDGE_CTL_FAST_BACK ); +pci_write_config_word (dev,PCI_BRIDGE_CONTROL , status); +break ; + +case PCI_CLASS_BRIDGE_CARDBUS : +pci_read_config_word (dev,PCI_CB_BRIDGE_CONTROL , + &status); + status |=PCI_CB_BRIDGE_CTL_PARITY + |PCI_CB_BRIDGE_CTL_MASTER_ABORT ; +pci_write_config_word (dev,PCI_CB_BRIDGE_CONTROL , + status); +break ; + } + } + +/* +* Now walk the devices again, this time setting them up. +*/ +list_for_each_entry (dev, &bus->devices, bus_list) { +u16 cmd; + +pci_read_config_word (dev,PCI_COMMAND , &cmd); + cmd |= features; +pci_write_config_word (dev,PCI_COMMAND , cmd); + +pci_write_config_byte (dev,PCI_CACHE_LINE_SIZE , +L1_CACHE_BYTES >>2 ); + } + +/* +* Propagate the flags to the PCI bridge. +*/ +if (bus->self && bus->self->hdr_type ==PCI_HEADER_TYPE_BRIDGE ) { +if (features &PCI_COMMAND_FAST_BACK ) + bus->bridge_ctl |=PCI_BRIDGE_CTL_FAST_BACK ; +if (features &PCI_COMMAND_PARITY )arch/arc/kernel/pcibios.c line 358
Quoted 10 lines
arch/arc/kernel/pcibios.c new file +10
-0+ bus->bridge_ctl |=PCI_BRIDGE_CTL_PARITY ; + } + +/* +* Report what we did for this bus +*/ +pr_info ("PCI: bus%d: Fast back to back transfers %sabled\n" , + bus->number, (features &PCI_COMMAND_FAST_BACK ) ?"en" :"dis" ); +} +EXPORT_SYMBOL (pcibios_fixup_bus);This
pcibios_fixup_bus()implementation has been blindly copied all over the place, but I don't think it's relevant for most arches. I think you could probably make it an empty function as on arm64.Quoted 63 lines
arch/arc/mm/ioremap.c +9
-1@@ -13,6 +13,7 @@#include <linux/mm.h> #include <linux/slab.h> #include <linux/cache.h> +#include <linux/sizes.h> void __iomem *ioremap (unsigned long paddr,unsigned long size) {@@ -80,7 +81,6 @@ void __iomem *ioremap_prot(phys_addr_t paddr, unsigned long size, }EXPORT_SYMBOL (ioremap_prot); -void iounmap (const void __iomem *addr) {if (addr >= (void __force __iomem *)ARC_UNCACHED_ADDR_SPACE )@@ -89,3 +89,11 @@ void iounmap(const void __iomem *addr)vfree ((void *)(PAGE_MASK & (unsigned long __force )addr)); }EXPORT_SYMBOL (iounmap); + +#ifdef CONFIG_PCI +int pci_ioremap_io (unsigned int offset,phys_addr_t phys_addr) +{ +return ioremap_nocache (phys_addr + offset,SZ_64K ); +} +EXPORT_SYMBOL_GPL (pci_ioremap_io); +#endif arch/arc/plat-axs10x/Kconfig +1
-0@@ -11,6 +11,7 @@ menuconfig ARC_PLAT_AXS10X select DW_APB_ICTL select GPIO_DWAPB select OF_GPIO + select MIGHT_HAVE_PCI select GENERIC_IRQ_CHIP select ARCH_REQUIRE_GPIOLIB helpdrivers/pci/Makefile +1
-0@@ -32,6 +32,7 @@ obj-$(CONFIG_PCI_IOV) += iov.o # Some architectures use the generic PCI setup functions # obj-$(CONFIG_ALPHA) += setup-irq.o +obj-$(CONFIG_ARC) += setup-irq.o obj-$(CONFIG_ARM) += setup-irq.o obj-$(CONFIG_ARM64) += setup-irq.o obj-$(CONFIG_UNICORE32) += setup-irq.oSignature · 6 lines
1.8.1.5 -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH v2 2/2 add new platform driver for PCI RC
In reply to Joao PintoThis patch adds a new driver that will be the reference platform driver for all PCI RC IP Protoyping Kits based on ARC SDP. This patch is composed by:
-Changes to pcie-designware driver add a function that enables the feature of starting the LTSSM (Link Train Status State) used by the new driver -MAINTAINERS file was updated to include the new driver -Documentation/devicetree/bindings/pci was updated to include the new driver documentation
-New driver called pcie-snpsdev
---
Changes v1 -> v2 (Bjorn Helgaas):
- Fixups snpsdev_pcie_fixup_bridge() and snpsdev_pcie_fixup_res() were removed from the driver (these functions were for specific tests only and not usefull in mainline)
- Driver' comments were reviewed (fix Typos and excessive comments removal)
- Removed unnecessary definitions in the driver source (PCIE_PHY_CTRL and PCIE_PHY_STAT)
.../devicetree/bindings/pci/pcie-snpsdev.txt | 28 ++ MAINTAINERS | 7 + drivers/pci/host/Kconfig | 5 + drivers/pci/host/Makefile | 1 + drivers/pci/host/pcie-designware.c | 15 ++ drivers/pci/host/pcie-designware.h | 1 + drivers/pci/host/pcie-snpsdev.c | 288 +++++++++++++++++++++ 7 files changed, 345 insertions(+) create mode 100644 Documentation/devicetree/bindings/pci/pcie-snpsdev.txt create mode 100644 drivers/pci/host/pcie-snpsdev.c
Documentation/devicetree/bindings/pci/pcie-snpsdev.txt new file +28 -0
@@ -0,0 +1,28 @@ +Synopsys PCI RC IP Prototyping Kit +---------------------------------- + +This is the reference platform driver to be used in the Synopsys PCI RC IP +Prototyping Kits. + +Required properties: +- compatible: "snps,pcie-snpsdev"; +- reg: A list of physical regions to access the device. +- interrupts: interrupt for the device. +- #address-cells: must be 3. +- #size-cells: must be 2. + +Example configuration: + + pcie: pcie@0xdffff000 { + #interrupt-cells = <1>; + compatible = "snps,pcie-snpsdev"; + reg = <0xdffff000 0x1000>; + interrupts = <25>, <24>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + ranges = <0x00000800 0 0xd0000000 0xd0000000 0 0x00002000 + 0x81000000 0 0x00000000 0xde000000 0 0x00010000 + 0x82000000 0 0xd0400000 0xd0400000 0 0x0d000000>; + num-lanes = <1>; + };
MAINTAINERS +7 -0
@@ -8230,6 +8230,13 @@ S: Maintained F: Documentation/devicetree/bindings/pci/hisilicon-pcie.txt F: drivers/pci/host/pcie-hisi.c +PCI DRIVER FOR SYNOPSYS PROTOTYPING DEVICE +M: Joao Pinto <[email protected]> +L: [email protected] +S: Maintained +F: Documentation/devicetree/bindings/pci/pcie-snpsdev.txt +F: drivers/pci/host/pcie-snpsdev.c + PCMCIA SUBSYSTEM P: Linux PCMCIA Team L: [email protected]
drivers/pci/host/Kconfig +5 -0
@@ -172,4 +172,9 @@ config PCI_HISI help Say Y here if you want PCIe controller support on HiSilicon HIP05 SoC +config PCIE_SNPSDEV + bool "Platform Driver for Synopsys Device" + select PCIEPORTBUS + select PCIE_DW + endmenu
drivers/pci/host/Makefile +1 -0
@@ -20,3 +20,4 @@ obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-iproc-bcma.o obj-$(CONFIG_PCIE_ALTERA) += pcie-altera.o obj-$(CONFIG_PCIE_ALTERA_MSI) += pcie-altera-msi.o obj-$(CONFIG_PCI_HISI) += pcie-hisi.o +obj-$(CONFIG_PCIE_SNPSDEV) += pcie-snpsdev.o
drivers/pci/host/pcie-designware.c +15 -0
@@ -22,9 +22,15 @@#include <linux/pci_regs.h> #include <linux/platform_device.h> #include <linux/types.h> +#include <linux/delay.h> +#include <linux/sizes.h> #include "pcie-designware.h" +/* Synopsys Default PCIE Control and Status Register Memory-Mapped */ +#define LINK_CONTROL_LINK_STATUS_REG 0x80 +#define PCIE_RETRAIN_LINK_MASK (1<<5) +/* Synopsis specific PCIE configuration registers */ #define PCIE_PORT_LINK_CONTROL 0x710#define PORT_LINK_MODE_MASK (0x3f << 16)
@@ -706,6 +712,15 @@ static struct pci_ops dw_pcie_ops = { .write = dw_pcie_wr_conf, }; +void dw_pcie_link_retrain (struct pcie_port *pp) +{ +u32 val =0 ; + +dw_pcie_readl_rc (pp,LINK_CONTROL_LINK_STATUS_REG , &val); + val = val |PCIE_RETRAIN_LINK_MASK ; +dw_pcie_writel_rc (pp, val,LINK_CONTROL_LINK_STATUS_REG ); +} +void dw_pcie_setup_rc (struct pcie_port *pp) {u32 val;
drivers/pci/host/pcie-designware.h +1 -0
@@ -79,5 +79,6 @@ void dw_pcie_msi_init(struct pcie_port *pp);int dw_pcie_link_up (struct pcie_port *pp);void dw_pcie_setup_rc (struct pcie_port *pp);int dw_pcie_host_init (struct pcie_port *pp); +void dw_pcie_link_retrain (struct pcie_port *pp);#endif /* _PCIE_DESIGNWARE_H */
drivers/pci/host/pcie-snpsdev.c new file +288 -0
288 lines not on this page · raw message
Signature · 1 line
1.8.1.5
kbuild test robot
build botRe: [PATCH v2 2/2] add new platform driver for PCI RC
reproduce:
Hi Joao,
[auto build test ERROR on arc/for-next] [also build test ERROR on v4.4-rc5] [cannot apply to next-20151216]
url: https://github.com/0day-ci/linux/commits/Joao-Pinto/adding-PCI-support-to-AXS10x/20151216-221835 base: https://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc for-next config: i386-allmodconfig (attached as .config) reproduce: # save the attached .config to linux build tree make ARCH=i386
All errors (new ones prefixed by >>):
drivers/pci/host/pcie-designware.c: In function 'dw_pcie_host_init':
>> drivers/pci/host/pcie-designware.c:560:7: error: implicit declaration of function 'pci_has_flag' [-Werror=implicit-function-declaration]
if (!pci_has_flag(PCI_PROBE_ONLY)) {
^
>> drivers/pci/host/pcie-designware.c:560:20: error: 'PCI_PROBE_ONLY' undeclared (first use in this function)
if (!pci_has_flag(PCI_PROBE_ONLY)) {
^ drivers/pci/host/pcie-designware.c:560:20: note: each undeclared identifier is reported only once for each function it appears in
cc1: some warnings being treated as errors
vim +/pci_has_flag +560 drivers/pci/host/pcie-designware.c
cbce7900 Zhou Wang 2015-10-29 554
cbce7900 Zhou Wang 2015-10-29 555 #ifdef CONFIG_ARM
cbce7900 Zhou Wang 2015-10-29 556 /* support old dtbs that incorrectly describe IRQs */
cbce7900 Zhou Wang 2015-10-29 557 pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
0815f957 Yijing Wang 2014-11-11 558 #endif
0815f957 Yijing Wang 2014-11-11 559
cbce7900 Zhou Wang 2015-10-29 @560 if (!pci_has_flag(PCI_PROBE_ONLY)) {
cbce7900 Zhou Wang 2015-10-29 561 pci_bus_size_bridges(bus);
cbce7900 Zhou Wang 2015-10-29 562 pci_bus_assign_resources(bus);
4b1ced84 Jingoo Han 2013-07-31 563 :::::: The code at line 560 was first introduced by commit
:::::: cbce7900598c26a12652f8ca9c41c5b29034c38d PCI: designware: Make driver arch-agnostic
:::::: TO: Zhou Wang <[email protected]> :::::: CC: Bjorn Helgaas <[email protected]>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
Re: [PATCH v2 2/2] add new platform driver for PCI RC
In reply to Joao PintoQuoted 11 lines · Joao Pinto
This patch adds a new driver that will be the reference platform driver for all PCI RC IP Protoyping Kits based on ARC SDP. This patch is composed by:
-Changes to pcie-designware driver add a function that enables the feature of starting the LTSSM (Link Train Status State) used by the new driver
(quoted diff) +0
-2-MAINTAINERS file was updated to include the new driver -Documentation/devicetree/bindings/pci was updated to include the new driverdocumentation
-New driver called pcie-snpsdevSigned-off-by Joao Pinto <[email protected]>
Quoted 8 lines
---
Changes v1 -> v2 (Bjorn Helgaas):
- Fixupssnpsdev_pcie_fixup_bridge()andsnpsdev_pcie_fixup_res()were removed from the driver (these functions were for specific tests only and not usefull in mainline)
- Driver' comments were reviewed (fix Typos and excessive comments removal)
- Removed unnecessary definitions in the driver source (PCIE_PHY_CTRLandPCIE_PHY_STAT)
Thanks for cleaning that stuff up. It's better if you can remove your testing infrastructure before posting it, to avoid wasting reviewers' time, but thanks for doing it now.
Quoted 92 lines
.../devicetree/bindings/pci/pcie-snpsdev.txt | 28 ++ MAINTAINERS | 7 + drivers/pci/host/Kconfig | 5 + drivers/pci/host/Makefile | 1 + drivers/pci/host/pcie-designware.c | 15 ++ drivers/pci/host/pcie-designware.h | 1 + drivers/pci/host/pcie-snpsdev.c | 288 +++++++++++++++++++++ 7 files changed, 345 insertions(+) create mode 100644 Documentation/devicetree/bindings/pci/pcie-snpsdev.txt create mode 100644 drivers/pci/host/pcie-snpsdev.cDocumentation/devicetree/bindings/pci/pcie-snpsdev.txt new file +28
-0@@ -0,0 +1,28 @@ +Synopsys PCI RC IP Prototyping Kit +---------------------------------- + +This is the reference platform driver to be used in the Synopsys PCI RC IP +Prototyping Kits. + +Required properties: +- compatible: "snps,pcie-snpsdev"; +- reg: A list of physical regions to access the device. +- interrupts: interrupt for the device. +- #address-cells: must be 3. +- #size-cells: must be 2. + +Example configuration: + + pcie: pcie@0xdffff000 { + #interrupt-cells = <1>; + compatible = "snps,pcie-snpsdev"; + reg = <0xdffff000 0x1000>; + interrupts = <25>, <24>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + ranges = <0x00000800 0 0xd0000000 0xd0000000 0 0x00002000 + 0x81000000 0 0x00000000 0xde000000 0 0x00010000 + 0x82000000 0 0xd0400000 0xd0400000 0 0x0d000000>; + num-lanes = <1>; + };MAINTAINERS +7
-0@@ -8230,6 +8230,13 @@ S: Maintained F: Documentation/devicetree/bindings/pci/hisilicon-pcie.txt F: drivers/pci/host/pcie-hisi.c +PCI DRIVER FOR SYNOPSYS PROTOTYPING DEVICE +M: Joao Pinto <[email protected]> +L: [email protected] +S: Maintained +F: Documentation/devicetree/bindings/pci/pcie-snpsdev.txt +F: drivers/pci/host/pcie-snpsdev.c + PCMCIA SUBSYSTEM P: Linux PCMCIA Team L: [email protected]drivers/pci/host/Kconfig +5
-0@@ -172,4 +172,9 @@ config PCI_HISI help Say Y here if you want PCIe controller support on HiSilicon HIP05 SoC +config PCIE_SNPSDEV + bool "Platform Driver for Synopsys Device" + select PCIEPORTBUS + select PCIE_DW + endmenudrivers/pci/host/Makefile +1
-0@@ -20,3 +20,4 @@ obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-iproc-bcma.o obj-$(CONFIG_PCIE_ALTERA) += pcie-altera.o obj-$(CONFIG_PCIE_ALTERA_MSI) += pcie-altera-msi.o obj-$(CONFIG_PCI_HISI) += pcie-hisi.o +obj-$(CONFIG_PCIE_SNPSDEV) += pcie-snpsdev.odrivers/pci/host/pcie-designware.c +0
-0@@ -22,9 +22,15 @@#include <linux/pci_regs.h>
drivers/pci/host/pcie-designware.c line 32
Quoted 10 lines
drivers/pci/host/pcie-designware.c +5
-0#include <linux/platform_device.h> #include <linux/types.h> +#include <linux/delay.h> +#include <linux/sizes.h> #include "pcie-designware.h" +/* Synopsys Default PCIE Control and Status Register Memory-Mapped */ +#define LINK_CONTROL_LINK_STATUS_REG 0x80 +#define PCIE_RETRAIN_LINK_MASK (1<<5)
Is this actually the Link Control register in the standard PCIe Capability? If so, please use PCI_EXP_LNKCTL and PCI_EXP_LNKCTL_RL instead of defining duplicate symbols here.
Quoted 139 lines
drivers/pci/host/pcie-designware.c +9
-0/* Synopsis specific PCIE configuration registers */ #define PCIE_PORT_LINK_CONTROL 0x710#define PORT_LINK_MODE_MASK (0x3f << 16)@@ -706,6 +712,15 @@ static struct pci_ops dw_pcie_ops = { .write = dw_pcie_wr_conf, }; +void dw_pcie_link_retrain (struct pcie_port *pp) +{ +u32 val =0 ; + +dw_pcie_readl_rc (pp,LINK_CONTROL_LINK_STATUS_REG , &val); + val = val |PCIE_RETRAIN_LINK_MASK ; +dw_pcie_writel_rc (pp, val,LINK_CONTROL_LINK_STATUS_REG ); +} +void dw_pcie_setup_rc (struct pcie_port *pp) {u32 val;drivers/pci/host/pcie-designware.h +1
-0@@ -79,5 +79,6 @@ void dw_pcie_msi_init(struct pcie_port *pp);int dw_pcie_link_up (struct pcie_port *pp);void dw_pcie_setup_rc (struct pcie_port *pp);int dw_pcie_host_init (struct pcie_port *pp); +void dw_pcie_link_retrain (struct pcie_port *pp);#endif /* _PCIE_DESIGNWARE_H */ drivers/pci/host/pcie-snpsdev.c new file +103
-0@@ -0,0 +1,288 @@ +/* +* PCIe RC driver for Synopsys Designware Core +* +* Copyright (C) 2015-2016 Synopsys, Inc. (www.synopsys.com) +* +* Authors: Manjunath Bettegowda <[email protected]>, +* Jie Deng <[email protected]> +* Joao Pinto <[email protected]> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/gpio.h> +#include <linux/interrupt.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/of_gpio.h> +#include <linux/pci.h> +#include <linux/platform_device.h> +#include <linux/resource.h> +#include <linux/signal.h> +#include <linux/types.h> + +#include "pcie-designware.h" + +#define to_snpsdev_pcie (x) container_of(x, struct snpsdev_pcie, pp) + +struct snpsdev_pcie { +void __iomem *mem_base;/* Memory Base to access Core's [RC] +* Config Space Layout +*/ +struct pcie_port pp;/* RC Root Port specific structure - +* DWC_PCIE_RC stuff +*/ +}; + +#define SIZE_1GB 0x40000000 +#define PCI_EQUAL_CONTROL_PHY 0x00000707 + +/* PCIe Port Logic registers (memory-mapped) */ +#define PLR_OFFSET 0x700 +#define PCIE_PHY_DEBUG_R0 (PLR_OFFSET + 0x28)/* 0x728 */ +#define PCIE_PHY_DEBUG_R1 (PLR_OFFSET + 0x2c)/* 0x72c */ + +/* This handler was created for future work */ +static irqreturn_t snpsdev_pcie_irq_handler (int irq,void *arg) +{ +return IRQ_NONE ; +} + +static irqreturn_t snpsdev_pcie_msi_irq_handler (int irq,void *arg) +{ +struct pcie_port *pp = arg; + +dw_handle_msi_irq (pp); + +return IRQ_HANDLED ; +} + +static void snpsdev_pcie_init_phy (struct pcie_port *pp) +{ +/* write Lane 0 Equalization Control fields register */ +writel (PCI_EQUAL_CONTROL_PHY , pp->dbi_base +0x154 ); +} + +static int snpsdev_pcie_deassert_core_reset (struct pcie_port *pp) +{ +return 0 ; +} + +/* +* snpsdev_pcie_host_init() +* Platform specific host/RC initialization +* a. Assert the core reset +* b. Assert and deassert phy reset and initialize the phy +* c. De-Assert the core reset +* d. Initializet the Root Port (BARs/Memory Or IO/ Interrupt/ Commnad Reg) +* e. Initiate Link startup procedure +* +*/ +static void snpsdev_pcie_host_init (struct pcie_port *pp) +{ +int count =0 ; + +/* Initialize Phy (Reset/poweron/control-inputs ) */ +snpsdev_pcie_init_phy (pp); + +/* de-assert core reset */ +snpsdev_pcie_deassert_core_reset (pp); + +/* We expect the PCIe Link to be up by this time */ +dw_pcie_setup_rc (pp); + +/* Start LTSSM here */ +dw_pcie_link_retrain (pp); + +/* Check for Link up indication */ +while (!dw_pcie_link_up (pp)) { +usleep_range (1000 ,1100 );
drivers/pci/host/pcie-snpsdev.c line 113
Quoted 10 lines
drivers/pci/host/pcie-snpsdev.c new file +10
-0+ count++; +if (count ==20 ) { +dev_err (pp->dev,"phy link never came up\n" ); +dev_dbg (pp->dev, +"PL_DEBUG0: 0x%08x, DEBUG_R1: 0x%08x\n" , +readl (pp->dbi_base +PCIE_PHY_DEBUG_R0 ), +readl (pp->dbi_base +PCIE_PHY_DEBUG_R1 )); +break ; + } + }
Can you move the link init stuff to a snpsdev_pcie_establish_link() function so it's structured the same way as the other DW-based drivers?
Quoted 151 lines
drivers/pci/host/pcie-snpsdev.c new file +151
-0+ +if (IS_ENABLED (CONFIG_PCI_MSI )) +dw_pcie_msi_init (pp); +} + +static int snpsdev_pcie_link_up (struct pcie_port *pp) +{ +u32 status; + +/* Bit number 36: reports LTSSM PHY Link UP; Available in bit 3 of +* PCIE_PHY_DEBUG_R1 +*/ + status =readl (pp->dbi_base +PCIE_PHY_DEBUG_R1 ) & (0x1 <<4 ); +if (status !=0 ) +return 1 ; + +/* TODO:Now Link is in L0;Initiate GEN2/GEN3 migration if RC Supports*/ +return 0 ; +} + +/** +* This is RC operation structure +* snpsdev_pcie_link_up: the function which initiates the phy link up procedure +* snpsdev_pcie_host_init: the function which does the host/RC Root port +* initialization. +*/ +static struct pcie_host_ops snpsdev_pcie_host_ops = { + .link_up = snpsdev_pcie_link_up, + .host_init = snpsdev_pcie_host_init, +}; + +/** +* snpsdev_add_pcie_port +* This function +* a. installs the interrupt handler +* b. registers host operations in the pcie_port structure +*/ +static int snpsdev_add_pcie_port (struct pcie_port *pp, +struct platform_device *pdev) +{ +int ret; + + pp->irq =platform_get_irq (pdev,1 ); + +if (pp->irq <0 ) { +if (pp->irq != -EPROBE_DEFER ) +dev_err (&pdev->dev,"cannot get irq\n" ); +return pp->irq; + } + + ret =devm_request_irq (&pdev->dev, pp->irq, snpsdev_pcie_irq_handler, +IRQF_SHARED ,"snpsdev-pcie" , pp); + +if (ret) { +dev_err (&pdev->dev,"failed to request irq\n" ); +return ret; + } + +if (IS_ENABLED (CONFIG_PCI_MSI )) { + pp->msi_irq =platform_get_irq (pdev,0 ); + +if (pp->msi_irq <0 ) { +if (pp->msi_irq != -EPROBE_DEFER ) +dev_err (&pdev->dev,"cannot get msi irq\n" ); +return pp->msi_irq; + } + + ret =devm_request_irq (&pdev->dev, pp->msi_irq, + snpsdev_pcie_msi_irq_handler, +IRQF_SHARED ,"snpsdev-pcie-msi" , pp); +if (ret) { +dev_err (&pdev->dev,"failed to request msi irq\n" ); +return ret; + } + } + + pp->root_bus_nr =-1 ; + pp->ops = &snpsdev_pcie_host_ops; + +/* Below function: +* Checks for range property from DT +* Gets the IO and MEMORY and CONFIG-Space ranges from DT +* Does IOREMAPS on the physical addresses +* Gets the num-lanes from DT +* Gets MSI capability from DT +* Calls the platform specific host initialization +* Program the correct class, BAR0, Link width, in Config space +* Then it calls pci common init routine +* Then it calls function to assign "unassigned resources" +*/ + ret =dw_pcie_host_init (pp); +if (ret) { +dev_err (&pdev->dev,"failed to initialize host\n" ); +return ret; + } + +return 0 ; +} + +/** +* snpsdev_pcie_rc_probe() +* This function gets called as part of pcie registration. if the id matches +* the platform driver framework will call this function. +* +* @pdev: Pointer to the platform_device structure +* +* Returns zero on success; Negative errorno on failure +*/ +static int __init snpsdev_pcie_rc_probe (struct platform_device *pdev) +{ +struct snpsdev_pcie *snpsdev_pcie; +struct pcie_port *pp; +struct resource *dwc_pcie_rc_res;/* Resource from DT */ +int ret; + + snpsdev_pcie =devm_kzalloc (&pdev->dev,sizeof (*snpsdev_pcie), +GFP_KERNEL ); +if (!snpsdev_pcie) +return -ENOMEM ; + + pp = &snpsdev_pcie->pp; + pp->dev = &pdev->dev; + + dwc_pcie_rc_res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); + +if (!dwc_pcie_rc_res) +return -ENODEV ; + + snpsdev_pcie->mem_base =devm_ioremap_resource (&pdev->dev, + dwc_pcie_rc_res); +if (IS_ERR (snpsdev_pcie->mem_base)) { + ret =PTR_ERR (snpsdev_pcie->mem_base); +return ret; + } + pp->dbi_base = snpsdev_pcie->mem_base; + + ret =snpsdev_add_pcie_port (pp, pdev); +if (ret <0 ) +return ret; + +platform_set_drvdata (pdev, snpsdev_pcie); + +return 0 ; +} + +static int __exit snpsdev_pcie_rc_remove(struct platform_device *pdev) +{ +return 0 ; +} + +static const struct of_device_id snpsdev_pcie_rc_of_match[] = {
drivers/pci/host/pcie-snpsdev.c line 274
Quoted 10 lines
drivers/pci/host/pcie-snpsdev.c new file +10
-0+ { .compatible = "snps,pcie-snpsdev", }, + {}, +}; +MODULE_DEVICE_TABLE (of, snpsdev_pcie_rc_of_match); + +static struct platform_driver snpsdev_pcie_rc_driver = { + .remove =__exit_p (snpsdev_pcie_rc_remove), + .driver = { + .name ="pcie-snpsdev" , + .owner =THIS_MODULE ,
I'm pretty sure you don't need to set .owner here. Compare with the other drivers (we had patches a while ago to remove this from most of them).
drivers/pci/host/pcie-snpsdev.c line 284
Quoted 10 lines
drivers/pci/host/pcie-snpsdev.c new file +10
-0+ .of_match_table = snpsdev_pcie_rc_of_match, + }, +}; + +static int __init snpsdev_pcie_init (void ) +{ +return platform_driver_probe (&snpsdev_pcie_rc_driver, + snpsdev_pcie_rc_probe); +} +subsys_initcall (snpsdev_pcie_init);
subsys_initall() is sort of a catch-all way to do this. Can you look at the other drivers and use the strategy they use?
Bjorn
Re: [PATCH v2 2/2] add new platform driver for PCI RC
In reply to Joao PintoQuoted 37 lines · Joao Pinto
This patch adds a new driver that will be the reference platform driver for all PCI RC IP Protoyping Kits based on ARC SDP. This patch is composed by:
-Changes to pcie-designware driver add a function that enables the feature of starting the LTSSM (Link Train Status State) used by the new driver
(quoted diff) +0
-2-MAINTAINERS file was updated to include the new driver -Documentation/devicetree/bindings/pci was updated to include the new driverdocumentation
-New driver called pcie-snpsdevSigned-off-by Joao Pinto <[email protected]>---
Changes v1 -> v2 (Bjorn Helgaas):
- Fixupssnpsdev_pcie_fixup_bridge()andsnpsdev_pcie_fixup_res()were removed from the driver (these functions were for specific tests only and not usefull in mainline)
- Driver' comments were reviewed (fix Typos and excessive comments removal)
- Removed unnecessary definitions in the driver source (PCIE_PHY_CTRLandPCIE_PHY_STAT).../devicetree/bindings/pci/pcie-snpsdev.txt | 28 ++ MAINTAINERS | 7 + drivers/pci/host/Kconfig | 5 + drivers/pci/host/Makefile | 1 + drivers/pci/host/pcie-designware.c | 15 ++ drivers/pci/host/pcie-designware.h | 1 + drivers/pci/host/pcie-snpsdev.c | 288 +++++++++++++++++++++ 7 files changed, 345 insertions(+) create mode 100644 Documentation/devicetree/bindings/pci/pcie-snpsdev.txt create mode 100644 drivers/pci/host/pcie-snpsdev.cDocumentation/devicetree/bindings/pci/pcie-snpsdev.txt new file +0
-0
Documentation/devicetree/bindings/pci/pcie-snpsdev.txt line 8
Quoted 8 lines
Documentation/devicetree/bindings/pci/pcie-snpsdev.txt new file +8
-0@@ -0,0 +1,28 @@ +Synopsys PCI RC IP Prototyping Kit +---------------------------------- + +This is the reference platform driver to be used in the Synopsys PCI RC IP +Prototyping Kits. + +Required properties: +- compatible: "snps,pcie-snpsdev";
Is there not a momre specific name for this RC IP?
Documentation/devicetree/bindings/pci/pcie-snpsdev.txt line 9
Quoted 1 line
Documentation/devicetree/bindings/pci/pcie-snpsdev.txt new file +1
-0+- reg: A list of physical regions to access the device.
How many, in which order?
Documentation/devicetree/bindings/pci/pcie-snpsdev.txt line 10
Quoted 1 line
Documentation/devicetree/bindings/pci/pcie-snpsdev.txt new file +1
-0+- interrupts: interrupt for the device.
How many, in which order?
Documentation/devicetree/bindings/pci/pcie-snpsdev.txt line 26
Quoted 13 lines
Documentation/devicetree/bindings/pci/pcie-snpsdev.txt new file +13
-0+Example configuration: + + pcie: pcie@0xdffff000 { + #interrupt-cells = <1>; + compatible = "snps,pcie-snpsdev"; + reg = <0xdffff000 0x1000>; + interrupts = <25>, <24>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + ranges = <0x00000800 0 0xd0000000 0xd0000000 0 0x00002000 + 0x81000000 0 0x00000000 0xde000000 0 0x00010000 + 0x82000000 0 0xd0400000 0xd0400000 0 0x0d000000>;
Nit: please bracket list entries individually.
Documentation/devicetree/bindings/pci/pcie-snpsdev.txt line 28
Quoted 2 lines
Documentation/devicetree/bindings/pci/pcie-snpsdev.txt new file +2
-0+ num-lanes = <1>; + };
Please refer to more generic bindings for properties you have not defined here (e.g. device_type, ranges, num-lanes).
[...]
Documentation/devicetree/bindings/pci/pcie-snpsdev.txt line 26
Quoted 1 line
Documentation/devicetree/bindings/pci/pcie-snpsdev.txt new file +1
-0+#define SIZE_1GB 0x40000000
Use SZ_1G from linux/sizes.h.
Thanks,
Mark.