2015-12-21 15:44:26

by Joao Pinto

[permalink] [raw]
Subject: [PATCH v3 0/2] 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 | 33 +++
MAINTAINERS | 7 +
arch/arc/Kconfig | 23 ++
arch/arc/include/asm/dma.h | 5 +
arch/arc/include/asm/io.h | 10 +
arch/arc/include/asm/pci.h | 43 ++++
arch/arc/kernel/Makefile | 1 +
arch/arc/kernel/pcibios.c | 55 ++++
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 | 11 +
drivers/pci/host/pcie-designware.h | 1 +
drivers/pci/host/pcie-snpsdev.c | 286 +++++++++++++++++++++
16 files changed, 492 insertions(+), 1 deletion(-)
create mode 100644 Documentation/devicetree/bindings/pci/pcie-snpsdev.txt
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

--
1.8.1.5


2015-12-21 15:44:31

by Joao Pinto

[permalink] [raw]
Subject: [PATCH v3 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.

Signed-off-by: Joao Pinto <[email protected]>
---
Change v2 -> v3 (Bjorn Helgaas):
- arch/arc/kernel/pcibios.c unused functions were removed and also the
arch/arc/include/asm/mach/pci.h was removed because was no longer necessary

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 to
pcibios.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/pci.h | 43 ++++++++++++++++++++++++++++++++++
arch/arc/kernel/Makefile | 1 +
arch/arc/kernel/pcibios.c | 55 ++++++++++++++++++++++++++++++++++++++++++++
arch/arc/mm/ioremap.c | 10 +++++++-
arch/arc/plat-axs10x/Kconfig | 1 +
drivers/pci/Makefile | 1 +
9 files changed, 148 insertions(+), 1 deletion(-)
create mode 100644 arch/arc/include/asm/pci.h
create mode 100644 arch/arc/kernel/pcibios.c

diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 2c2ac3f..98b32c1 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -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"
diff --git a/arch/arc/include/asm/dma.h b/arch/arc/include/asm/dma.h
index ca7c451..37942fa 100644
--- a/arch/arc/include/asm/dma.h
+++ b/arch/arc/include/asm/dma.h
@@ -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
diff --git a/arch/arc/include/asm/io.h b/arch/arc/include/asm/io.h
index 694ece8..2ec3cf4 100644
--- a/arch/arc/include/asm/io.h
+++ b/arch/arc/include/asm/io.h
@@ -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)
diff --git a/arch/arc/include/asm/pci.h b/arch/arc/include/asm/pci.h
new file mode 100644
index 0000000..a0a0fa5
--- /dev/null
+++ b/arch/arc/include/asm/pci.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2015-2016 Synopsys, Inc. (http://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 <linux/ioport.h>
+
+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)
+
+/*
+ * 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 /* __KERNEL__ */
+
+#endif /* _ASM_ARC_PCI_H */
+
diff --git a/arch/arc/kernel/Makefile b/arch/arc/kernel/Makefile
index e7f3625..1bc2036 100644
--- a/arch/arc/kernel/Makefile
+++ b/arch/arc/kernel/Makefile
@@ -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
diff --git a/arch/arc/kernel/pcibios.c b/arch/arc/kernel/pcibios.c
new file mode 100644
index 0000000..99ee329
--- /dev/null
+++ b/arch/arc/kernel/pcibios.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2014-2015 Synopsys, Inc. (http://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>
+
+unsigned long pcibios_min_io = 0x100;
+EXPORT_SYMBOL(pcibios_min_io);
+
+unsigned long pcibios_min_mem = 0x100000;
+EXPORT_SYMBOL(pcibios_min_mem);
+
+/*
+ * 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;
+}
+
+/*
+ * 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));
+
+}
+
+void pcibios_fixup_bus(struct pci_bus *bus)
+{
+}
+EXPORT_SYMBOL(pcibios_fixup_bus);
diff --git a/arch/arc/mm/ioremap.c b/arch/arc/mm/ioremap.c
index 739e65f..fe807b0 100644
--- a/arch/arc/mm/ioremap.c
+++ b/arch/arc/mm/ioremap.c
@@ -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
diff --git a/arch/arc/plat-axs10x/Kconfig b/arch/arc/plat-axs10x/Kconfig
index d475f9d..426ac4b 100644
--- a/arch/arc/plat-axs10x/Kconfig
+++ b/arch/arc/plat-axs10x/Kconfig
@@ -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
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index be3f631..2154092 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -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
--
1.8.1.5

2015-12-21 15:44:37

by Joao Pinto

[permalink] [raw]
Subject: [PATCH v3 2/2] add new platform driver for PCI RC

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
-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

Signed-off-by: Joao Pinto <[email protected]>
---
Changes v2 -> v3:
- link init stuff was moved to a snpsdev_pcie_establish_link() function in
pcie-snpsdev (Bjorn Helgaas)
- pcie-snpsdev driver declaration was changed to be more
standard (Bjorn Helgaas)
- pcie-designware' dw_pcie_link_retrain() now use standard registers from
pci-regs.h (Bjorn Helgaas)
- pcie-snpsdev.txt was complemented with more info (Mark Rutland)

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 | 33 +++
MAINTAINERS | 7 +
drivers/pci/host/Kconfig | 5 +
drivers/pci/host/Makefile | 1 +
drivers/pci/host/pcie-designware.c | 11 +
drivers/pci/host/pcie-designware.h | 1 +
drivers/pci/host/pcie-snpsdev.c | 286 +++++++++++++++++++++
7 files changed, 344 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pci/pcie-snpsdev.txt
create mode 100644 drivers/pci/host/pcie-snpsdev.c

diff --git a/Documentation/devicetree/bindings/pci/pcie-snpsdev.txt b/Documentation/devicetree/bindings/pci/pcie-snpsdev.txt
new file mode 100644
index 0000000..cae548b
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/pcie-snpsdev.txt
@@ -0,0 +1,33 @@
+Synopsys PCI RC IP Prototyping Kit
+----------------------------------
+
+This is the reference platform driver to be used in the Synopsys PCI Root
+Complex IP Prototyping Kit.
+
+Required properties:
+- compatible: set to "snps,pcie-snpsdev";
+- reg: base address and length of the pcie controller registers.
+- #address-cells: set to <3>
+- #size-cells: set to <2>
+- device_type: set to "pci"
+- ranges: ranges for the PCI memory and I/O regions.
+- interrupts: one interrupt source for MSI interrupts, followed by interrupt
+ source for hardware related interrupts.
+- #interrupt-cells: set to <1>
+- num-lanes: set to <1>;
+
+Example configuration:
+
+ pcie: pcie@0xdffff000 {
+ compatible = "snps,pcie-snpsdev";
+ reg = <0xdffff000 0x1000>;
+ #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>;
+ interrupts = <25>, <24>;
+ #interrupt-cells = <1>;
+ num-lanes = <1>;
+ };
diff --git a/MAINTAINERS b/MAINTAINERS
index e9caa4b..d2e4506 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -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]
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index f131ba9..a874b1e 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -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
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 9d4d3c6..e422f65 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -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
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
index 540f077..99fad62 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -22,6 +22,8 @@
#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"

@@ -706,6 +708,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, PCI_EXP_LNKCTL+0x70, &val);
+ val = val | PCI_EXP_LNKCTL_RL;
+ dw_pcie_writel_rc(pp, val, PCI_EXP_LNKCTL+0x70);
+}
+
void dw_pcie_setup_rc(struct pcie_port *pp)
{
u32 val;
diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h
index 2356d29..249b631 100644
--- a/drivers/pci/host/pcie-designware.h
+++ b/drivers/pci/host/pcie-designware.h
@@ -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 */
diff --git a/drivers/pci/host/pcie-snpsdev.c b/drivers/pci/host/pcie-snpsdev.c
new file mode 100644
index 0000000..4ca7ec5
--- /dev/null
+++ b/drivers/pci/host/pcie-snpsdev.c
@@ -0,0 +1,286 @@
+/*
+ * PCIe RC driver for Synopsys Designware Core
+ *
+ * Copyright (C) 2015-2016 Synopsys, Inc. (http://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 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;
+}
+
+static void snpsdev_pcie_establish_link(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);
+
+ while (!dw_pcie_link_up(pp)) {
+ usleep_range(1000, 1100);
+ 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;
+ }
+ }
+}
+
+/*
+ * 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)
+{
+ /* Establish link */
+ snpsdev_pcie_establish_link(pp);
+
+ 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 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 snpsdev_pcie_rc_remove(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static const struct of_device_id snpsdev_pcie_rc_of_match[] = {
+ { .compatible = "snps,pcie-snpsdev", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, snpsdev_pcie_rc_of_match);
+
+static struct platform_driver snpsdev_pcie_rc_driver = {
+ .driver = {
+ .name = "pcie-snpsdev",
+ .of_match_table = snpsdev_pcie_rc_of_match,
+ },
+ .probe = snpsdev_pcie_rc_probe,
+};
+
+module_platform_driver(snpsdev_pcie_rc_driver);
+
+MODULE_AUTHOR("Manjunath Bettegowda <[email protected]>");
+MODULE_DESCRIPTION("Platform Driver for Synopsys Device");
+MODULE_LICENSE("GPL v2");
--
1.8.1.5

2015-12-21 19:46:25

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v3 2/2] add new platform driver for PCI RC

Hi Joao,

[auto build test ERROR on arc/for-next]
[also build test ERROR on v4.4-rc6 next-20151221]

url: https://github.com/0day-ci/linux/commits/Joao-Pinto/adding-PCI-support-to-AXS10x/20151221-234734
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:556: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:556:20: error: 'PCI_PROBE_ONLY' undeclared (first use in this function)
if (!pci_has_flag(PCI_PROBE_ONLY)) {
^
drivers/pci/host/pcie-designware.c:556: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 +556 drivers/pci/host/pcie-designware.c

cbce7900 Zhou Wang 2015-10-29 550
cbce7900 Zhou Wang 2015-10-29 551 #ifdef CONFIG_ARM
cbce7900 Zhou Wang 2015-10-29 552 /* support old dtbs that incorrectly describe IRQs */
cbce7900 Zhou Wang 2015-10-29 553 pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
0815f957 Yijing Wang 2014-11-11 554 #endif
0815f957 Yijing Wang 2014-11-11 555
cbce7900 Zhou Wang 2015-10-29 @556 if (!pci_has_flag(PCI_PROBE_ONLY)) {
cbce7900 Zhou Wang 2015-10-29 557 pci_bus_size_bridges(bus);
cbce7900 Zhou Wang 2015-10-29 558 pci_bus_assign_resources(bus);
4b1ced84 Jingoo Han 2013-07-31 559

:::::: The code at line 556 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


Attachments:
(No filename) (2.13 kB)
.config.gz (51.35 kB)
Download all attachments