bcm53xx: update iProc patches (V5 accepted in helgaas/pci.git next)

Signed-off-by: Rafał Miłecki <zajec5@gmail.com>

SVN-Revision: 48375
This commit is contained in:
Rafał Miłecki 2016-01-19 21:53:23 +00:00
parent 76b903a415
commit b9fb3d4524
12 changed files with 341 additions and 190 deletions

View file

@ -0,0 +1,42 @@
From c1b98e41b356a1807d7083d958790da2027c0d9d Mon Sep 17 00:00:00 2001
From: Arnd Bergmann <arnd@arndb.de>
Date: Tue, 24 Nov 2015 15:28:48 -0600
Subject: [PATCH] PCI: iproc: Hide CONFIG_PCIE_IPROC
PCIE_IPROC_BCMA does not require CONFIG_OF in Kconfig, but
CONFIG_PCIE_IPROC does, so we can get a warning when building for an ARM
platform without DT support:
warning: (PCIE_IPROC_PLATFORM && PCIE_IPROC_BCMA) selects PCIE_IPROC which has unmet direct dependencies (PCI && OF && (ARM || ARM64))
It turns out that CONFIG_PCIE_IPROC never needs to be enabled by a user
anyway, we can simply rely on it being selected implictly through either
PCIE_IPROC_PLATFORM or PCIE_IPROC_BCMA.
Fixes: 4785ffbdc9b5 ("PCI: iproc: Add BCMA PCIe driver")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Hauke Mehrtens <hauke@hauke-m.de>
---
drivers/pci/host/Kconfig | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -107,13 +107,11 @@ config PCI_VERSATILE
depends on ARCH_VERSATILE
config PCIE_IPROC
- tristate "Broadcom iProc PCIe controller"
- depends on OF && (ARM || ARM64)
- default n
+ tristate
help
This enables the iProc PCIe core controller support for Broadcom's
- iProc family of SoCs. An appropriate bus interface driver also needs
- to be enabled
+ iProc family of SoCs. An appropriate bus interface driver needs
+ to be enabled to select this.
config PCIE_IPROC_PLATFORM
tristate "Broadcom iProc PCIe platform bus driver"

View file

@ -0,0 +1,27 @@
From 57303e92f48a0e307fd86977ec9be5aa6a7ea681 Mon Sep 17 00:00:00 2001
From: "Dmitry V. Krivenok" <krivenok.dmitry@gmail.com>
Date: Mon, 30 Nov 2015 23:45:49 +0300
Subject: [PATCH] PCI: iproc: Do not use 0x in front of %pap
The "%pap" format adds a "0x" prefix, so using "0x%pap" results in output
of "0x0x...". Drop the "0x" prefix in the format string.
[bhelgaas: changelog]
Signed-off-by: Dmitry V. Krivenok <krivenok.dmitry@gmail.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Ray Jui <rjui@broadcom.com>
---
drivers/pci/host/pcie-iproc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/pci/host/pcie-iproc.c
+++ b/drivers/pci/host/pcie-iproc.c
@@ -245,7 +245,7 @@ static int iproc_pcie_setup_ob(struct ip
if (size > max_size) {
dev_err(pcie->dev,
- "res size 0x%pap exceeds max supported size 0x%llx\n",
+ "res size %pap exceeds max supported size 0x%llx\n",
&size, max_size);
return -EINVAL;
}

View file

@ -1,13 +1,14 @@
From d85a955118c8d8679d4f746fe2189c172d7c365f Mon Sep 17 00:00:00 2001
From e8b8318de645c04f8600cb5af6f6773a1878ee9d Mon Sep 17 00:00:00 2001
From: Ray Jui <rjui@broadcom.com>
Date: Mon, 16 Nov 2015 17:18:05 -0800
Subject: [PATCH 150/154] PCI: iproc: Update iProc PCIe device tree binding
Date: Fri, 4 Dec 2015 09:34:58 -0800
Subject: [PATCH 1/5] PCI: iproc: Update iProc PCIe device tree binding
Add a new compatible string "brcm,iproc-pcie-paxc", for PAXC based iProc
PCIe root complex. A PAXC based PCIe root complex is connected to
emulated endpoint devices internal to the ASIC
Add a new compatible string "brcm,iproc-pcie-paxc", for PAXC-based iProc
PCIe root complex. A PAXC-based PCIe root complex is connected to emulated
endpoint devices internal to the ASIC.
Signed-off-by: Ray Jui <rjui@broadcom.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Scott Branden <sbranden@broadcom.com>
---
Documentation/devicetree/bindings/pci/brcm,iproc-pcie.txt | 5 ++++-
@ -21,8 +22,8 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
Required properties:
-- compatible: Must be "brcm,iproc-pcie"
+- compatible: Must be "brcm,iproc-pcie" for PAXB, or "brcm,iproc-pcie-paxc"
+ for PAXC. PAXB based root complex is used for external endpoint devices.
+ PAXC based root complex is connected to emulated endpoint devices
+ for PAXC. PAXB-based root complex is used for external endpoint devices.
+ PAXC-based root complex is connected to emulated endpoint devices
+ internal to the ASIC
- reg: base address and length of the PCIe controller I/O register space
- #interrupt-cells: set to <1>

View file

@ -1,20 +1,21 @@
From a13fc4733b25d6dad6ec1826f09225c69ee21e3a Mon Sep 17 00:00:00 2001
From 943ebae781f519ecfecbfa1b997f15f59116e41d Mon Sep 17 00:00:00 2001
From: Ray Jui <rjui@broadcom.com>
Date: Mon, 16 Nov 2015 17:41:43 -0800
Subject: [PATCH 151/154] PCI: iproc: Add PAXC interface support
Date: Fri, 4 Dec 2015 09:34:59 -0800
Subject: [PATCH 2/5] PCI: iproc: Add PAXC interface support
Traditionally, all iProc PCIe root complexes use PAXB based wrapper,
with an integrated on-chip Serdes to support external endpoint devices.
On newer iProc platforms, a PAXC based wrapper is introduced, for
connection with internally emulated PCIe endpoint devices in the ASIC
Traditionally, all iProc PCIe root complexes use PAXB-based wrapper, with
an integrated on-chip Serdes to support external endpoint devices. On
newer iProc platforms, a PAXC-based wrapper is introduced, for connection
with internally emulated PCIe endpoint devices in the ASIC.
This patch adds support for PAXC based iProc PCIe root complex in the
iProc PCIe core driver. This change fators out common logic between
PAXB and PAXC, and use tables to store register offsets that are
different between PAXB and PAXC. This allows the driver to be scaled to
support subsequent PAXC revisions in the future
Add support for PAXC-based iProc PCIe root complex in the iProc PCIe core
driver. This change factors out common logic between PAXB and PAXC, and
uses tables to store register offsets that are different between PAXB and
PAXC. This allows the driver to be scaled to support subsequent PAXC
revisions in the future.
Signed-off-by: Ray Jui <rjui@broadcom.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Scott Branden <sbranden@broadcom.com>
---
drivers/pci/host/pcie-iproc-platform.c | 24 +++-
@ -324,7 +325,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
- val = readl(pcie->base + PCIE_LINK_STATUS_OFFSET);
+ /*
+ * PAXC connects to emulated endpoint devices directly and does not
+ * have a Serdes. Therefore skip the link detection logic here
+ * have a Serdes. Therefore skip the link detection logic here.
+ */
+ if (pcie->type == IPROC_PCIE_PAXC)
+ return 0;
@ -392,10 +393,10 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
+ * iProc PCIe interface type
+ *
+ * PAXB is the wrapper used in root complex that can be connected to an
+ * external endpoint device
+ * external endpoint device.
+ *
+ * PAXC is the wrapper used in root complex dedicated for internal emulated
+ * endpoint devices
+ * endpoint devices.
+ */
+enum iproc_pcie_type {
+ IPROC_PCIE_PAXB = 0,

View file

@ -1,12 +1,13 @@
From 96b40de5e36ec479dabb88500f1830a87818a809 Mon Sep 17 00:00:00 2001
From c7bd48195377435ecaf38869b936be8e7abe3489 Mon Sep 17 00:00:00 2001
From: Ray Jui <rjui@broadcom.com>
Date: Mon, 16 Nov 2015 17:57:33 -0800
Subject: [PATCH 152/154] PCI: iproc: Add iProc PCIe MSI device tree binding
Date: Fri, 4 Dec 2015 09:35:00 -0800
Subject: [PATCH 3/5] PCI: iproc: Add iProc PCIe MSI device tree binding
This patch updates the iProc PCIe device tree bindings with added
binding information for MSI
Update the iProc PCIe device tree bindings with added binding information
for MSI.
Signed-off-by: Ray Jui <rjui@broadcom.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Anup Patel <anup.patel@broadcom.com>
Reviewed-by: Vikram Prakash <vikramp@broadcom.com>
Reviewed-by: Scott Branden <sbranden@broadcom.com>
@ -29,7 +30,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
+- msi-parent: Link to the device node of the MSI controller. On newer iProc
+platforms, the MSI controller may be gicv2m or gicv3-its. On older iProc
+platforms without MSI support in its interrupt controller, one may use the
+event queue based MSI support integrated within the iProc PCIe core
+event queue based MSI support integrated within the iProc PCIe core.
+
+When the iProc event queue based MSI is used, one needs to define the
+following properties in the MSI device node:

View file

@ -1,73 +1,76 @@
From c81922174d61127ff5baad6059ae148794c72276 Mon Sep 17 00:00:00 2001
From 3bc2b2348835f6edd33c383a2fbcf15fe3dac3b2 Mon Sep 17 00:00:00 2001
From: Ray Jui <rjui@broadcom.com>
Date: Tue, 17 Nov 2015 13:14:37 -0800
Subject: [PATCH 153/154] PCI: iproc: Add iProc PCIe MSI support
Date: Wed, 6 Jan 2016 18:04:35 -0600
Subject: [PATCH 4/5] PCI: iproc: Add iProc PCIe MSI support
This patch adds PCIe MSI support for both PAXB and PAXC interfaces on
all iProc based platforms
Add PCIe MSI support for both PAXB and PAXC interfaces on all iProc-based
platforms.
The iProc PCIe MSI support deploys an event queue based implementation.
The iProc PCIe MSI support deploys an event queue-based implementation.
Each event queue is serviced by a GIC interrupt and can support up to 64
MSI vectors. Host memory is allocated for the event queues, and each event
queue consists of 64 word-sized entries. MSI data is written to the
lower 16-bit of each entry, whereas the upper 16-bit of the entry is
reserved for the controller for internal processing
queue consists of 64 word-sized entries. MSI data is written to the lower
16-bit of each entry, whereas the upper 16-bit of the entry is reserved for
the controller for internal processing.
Each event queue is tracked by a head pointer and tail pointer. Head
pointer indicates the next entry in the event queue to be processed by
the driver and is updated by the driver after processing is done.
The controller uses the tail pointer as the next MSI data insertion
point. The controller ensures MSI data is flushed to host memory before
updating the tail pointer and then triggering the interrupt
updating the tail pointer and then triggering the interrupt.
MSI IRQ affinity is supported by evenly distributing the interrupts to
each CPU core. MSI vector is moved from one GIC interrupt to another in
order to steer to the target CPU
MSI IRQ affinity is supported by evenly distributing the interrupts to each
CPU core. MSI vector is moved from one GIC interrupt to another in order
to steer to the target CPU.
Therefore, the actual number of supported MSI vectors is:
M * 64 / N
where M denotes the number of GIC interrupts (event queues), and N
denotes the number of CPU cores
where M denotes the number of GIC interrupts (event queues), and N denotes
the number of CPU cores.
This iProc event queue based MSI support should not be used with newer
This iProc event queue-based MSI support should not be used with newer
platforms with integrated MSI support in the GIC (e.g., giv2m or
gicv3-its)
gicv3-its).
[bhelgaas: fold in Kconfig fixes from Arnd Bergmann <arnd@arndb.de>]
Signed-off-by: Ray Jui <rjui@broadcom.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Anup Patel <anup.patel@broadcom.com>
Reviewed-by: Vikram Prakash <vikramp@broadcom.com>
Reviewed-by: Scott Branden <sbranden@broadcom.com>
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
---
drivers/pci/host/Kconfig | 9 +
drivers/pci/host/Kconfig | 10 +
drivers/pci/host/Makefile | 1 +
drivers/pci/host/pcie-iproc-bcma.c | 1 +
drivers/pci/host/pcie-iproc-msi.c | 675 +++++++++++++++++++++++++++++++++
drivers/pci/host/pcie-iproc-platform.c | 1 +
drivers/pci/host/pcie-iproc.c | 26 ++
drivers/pci/host/pcie-iproc.h | 23 +-
7 files changed, 734 insertions(+), 2 deletions(-)
7 files changed, 735 insertions(+), 2 deletions(-)
create mode 100644 drivers/pci/host/pcie-iproc-msi.c
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -115,6 +115,15 @@ config PCIE_IPROC
iProc family of SoCs. An appropriate bus interface driver also needs
to be enabled
@@ -133,5 +133,15 @@ config PCIE_IPROC_BCMA
help
Say Y here if you want to use the Broadcom iProc PCIe controller
through the BCMA bus interface
+
+config PCIE_IPROC_MSI
+ bool "Broadcom iProc PCIe MSI support"
+ depends on ARCH_BCM_IPROC && PCI_MSI
+ depends on PCIE_IPROC_PLATFORM || PCIE_IPROC_BCMA
+ depends on PCI_MSI
+ select PCI_MSI_IRQ_DOMAIN
+ default ARCH_BCM_IPROC
+ help
+ Say Y here if you want to enable MSI support for Broadcom's iProc
+ PCIe controller
+
config PCIE_IPROC_PLATFORM
tristate "Broadcom iProc PCIe platform bus driver"
depends on ARCH_BCM_IPROC || (ARM && COMPILE_TEST)
endmenu
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -14,5 +14,6 @@ obj-$(CONFIG_PCI_XGENE) += pci-xgene.o
@ -122,16 +125,16 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
+
+#define IPROC_MSI_EQ_MASK 0x3f
+
+/* max number of GIC interrupts */
+/* Max number of GIC interrupts */
+#define NR_HW_IRQS 6
+
+/* number of entries in each event queue */
+/* Number of entries in each event queue */
+#define EQ_LEN 64
+
+/* size of each event queue memory region */
+/* Size of each event queue memory region */
+#define EQ_MEM_REGION_SIZE SZ_4K
+
+/* size of each MSI address region */
+/* Size of each MSI address region */
+#define MSI_MEM_REGION_SIZE SZ_4K
+
+enum iproc_msi_reg {
@ -152,7 +155,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
+ * iProc MSI group
+ *
+ * One MSI group is allocated per GIC interrupt, serviced by one iProc MSI
+ * event queue
+ * event queue.
+ *
+ * @msi: pointer to iProc MSI data
+ * @gic_irq: GIC interrupt
@ -168,7 +171,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
+ * iProc event queue based MSI
+ *
+ * Only meant to be used on platforms without MSI support integrated into the
+ * GIC
+ * GIC.
+ *
+ * @pcie: pointer to iProc PCIe data
+ * @reg_offsets: MSI register offsets
@ -277,12 +280,12 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
+
+/*
+ * In iProc PCIe core, each MSI group is serviced by a GIC interrupt and a
+ * dedicated event queue. Each MSI group can support up to 64 MSI vectors
+ * dedicated event queue. Each MSI group can support up to 64 MSI vectors.
+ *
+ * The number of MSI groups varies between different iProc SoCs. The total
+ * number of CPU cores also varies. To support MSI IRQ affinity, we
+ * distribute GIC interrupts across all available CPUs. MSI vector is moved
+ * from one GIC interrupt to another to steer to the target CPU
+ * from one GIC interrupt to another to steer to the target CPU.
+ *
+ * Assuming:
+ * - the number of MSI groups is M
@ -347,7 +350,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
+
+ mutex_lock(&msi->bitmap_lock);
+
+ /* allocate 'nr_cpus' number of MSI vectors each time */
+ /* Allocate 'nr_cpus' number of MSI vectors each time */
+ hwirq = bitmap_find_next_zero_area(msi->bitmap, msi->nr_msi_vecs, 0,
+ msi->nr_cpus, 0);
+ if (hwirq < msi->nr_msi_vecs) {
@ -399,7 +402,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
+ /*
+ * Since we have multiple hwirq mapped to a single MSI vector,
+ * now we need to derive the hwirq at CPU0. It can then be used to
+ * mapped back to virq
+ * mapped back to virq.
+ */
+ return hwirq_to_canonical_hwirq(msi, hwirq);
+}
@ -425,11 +428,11 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
+ * iProc MSI event queue is tracked by head and tail pointers. Head
+ * pointer indicates the next entry (MSI data) to be consumed by SW in
+ * the queue and needs to be updated by SW. iProc MSI core uses the
+ * tail pointer as the next data insertion point
+ * tail pointer as the next data insertion point.
+ *
+ * Entries between head and tail pointers contain valid MSI data. MSI
+ * data is guaranteed to be in the event queue memory before the tail
+ * pointer is updated by the iProc MSI core
+ * pointer is updated by the iProc MSI core.
+ */
+ head = iproc_msi_read_reg(msi, IPROC_MSI_EQ_HEAD,
+ eq) & IPROC_MSI_EQ_MASK;
@ -439,7 +442,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
+
+ /*
+ * Figure out total number of events (MSI data) to be
+ * processed
+ * processed.
+ */
+ nr_events = (tail < head) ?
+ (EQ_LEN - (head - tail)) : (tail - head);
@ -458,13 +461,13 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
+
+ /*
+ * Now all outstanding events have been processed. Update the
+ * head pointer
+ * head pointer.
+ */
+ iproc_msi_write_reg(msi, IPROC_MSI_EQ_HEAD, eq, head);
+
+ /*
+ * Now go read the tail pointer again to see if there are new
+ * oustanding events that came in during the above window
+ * oustanding events that came in during the above window.
+ */
+ } while (true);
+
@ -476,7 +479,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
+ int i, eq;
+ u32 val;
+
+ /* program memory region for each event queue */
+ /* Program memory region for each event queue */
+ for (i = 0; i < msi->nr_eq_region; i++) {
+ dma_addr_t addr = msi->eq_dma + (i * EQ_MEM_REGION_SIZE);
+
@ -486,7 +489,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
+ upper_32_bits(addr));
+ }
+
+ /* program address region for MSI posted writes */
+ /* Program address region for MSI posted writes */
+ for (i = 0; i < msi->nr_msi_region; i++) {
+ phys_addr_t addr = msi->msi_addr + (i * MSI_MEM_REGION_SIZE);
+
@ -497,14 +500,14 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
+ }
+
+ for (eq = 0; eq < msi->nr_irqs; eq++) {
+ /* enable MSI event queue */
+ /* Enable MSI event queue */
+ val = IPROC_MSI_INTR_EN | IPROC_MSI_INT_N_EVENT |
+ IPROC_MSI_EQ_EN;
+ iproc_msi_write_reg(msi, IPROC_MSI_CTRL, eq, val);
+
+ /*
+ * Some legacy platforms require the MSI interrupt enable
+ * register to be set explicitly
+ * register to be set explicitly.
+ */
+ if (msi->has_inten_reg) {
+ val = iproc_msi_read_reg(msi, IPROC_MSI_INTS_EN, eq);
@ -580,7 +583,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
+ irq_set_chained_handler_and_data(msi->grps[i].gic_irq,
+ iproc_msi_handler,
+ &msi->grps[i]);
+ /* dedicate GIC interrupt to each CPU core */
+ /* Dedicate GIC interrupt to each CPU core */
+ if (alloc_cpumask_var(&mask, GFP_KERNEL)) {
+ cpumask_clear(mask);
+ cpumask_set_cpu(cpu, mask);
@ -596,7 +599,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
+ }
+
+ if (ret) {
+ /* free all configured/unconfigured irqs */
+ /* Free all configured/unconfigured IRQs */
+ iproc_msi_irq_free(msi, cpu);
+ return ret;
+ }
@ -697,7 +700,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
+ msi->grps[i].eq = i;
+ }
+
+ /* reserve memory for event queue and make sure memories are zeroed */
+ /* Reserve memory for event queue and make sure memories are zeroed */
+ msi->eq_cpu = dma_zalloc_coherent(pcie->dev,
+ msi->nr_eq_region * EQ_MEM_REGION_SIZE,
+ &msi->eq_dma, GFP_KERNEL);
@ -869,7 +872,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res);
int iproc_pcie_remove(struct iproc_pcie *pcie);
+#ifdef CONFIG_PCI_MSI
+#ifdef CONFIG_PCIE_IPROC_MSI
+int iproc_msi_init(struct iproc_pcie *pcie, struct device_node *node);
+void iproc_msi_exit(struct iproc_pcie *pcie);
+#else
@ -878,7 +881,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
+{
+ return -ENODEV;
+}
+static void iproc_msi_exit(struct iproc_pcie *pcie)
+static inline void iproc_msi_exit(struct iproc_pcie *pcie)
+{
+}
+#endif

View file

@ -0,0 +1,42 @@
From c1b98e41b356a1807d7083d958790da2027c0d9d Mon Sep 17 00:00:00 2001
From: Arnd Bergmann <arnd@arndb.de>
Date: Tue, 24 Nov 2015 15:28:48 -0600
Subject: [PATCH] PCI: iproc: Hide CONFIG_PCIE_IPROC
PCIE_IPROC_BCMA does not require CONFIG_OF in Kconfig, but
CONFIG_PCIE_IPROC does, so we can get a warning when building for an ARM
platform without DT support:
warning: (PCIE_IPROC_PLATFORM && PCIE_IPROC_BCMA) selects PCIE_IPROC which has unmet direct dependencies (PCI && OF && (ARM || ARM64))
It turns out that CONFIG_PCIE_IPROC never needs to be enabled by a user
anyway, we can simply rely on it being selected implictly through either
PCIE_IPROC_PLATFORM or PCIE_IPROC_BCMA.
Fixes: 4785ffbdc9b5 ("PCI: iproc: Add BCMA PCIe driver")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Hauke Mehrtens <hauke@hauke-m.de>
---
drivers/pci/host/Kconfig | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -119,13 +119,11 @@ config PCI_VERSATILE
depends on ARCH_VERSATILE
config PCIE_IPROC
- tristate "Broadcom iProc PCIe controller"
- depends on OF && (ARM || ARM64)
- default n
+ tristate
help
This enables the iProc PCIe core controller support for Broadcom's
- iProc family of SoCs. An appropriate bus interface driver also needs
- to be enabled
+ iProc family of SoCs. An appropriate bus interface driver needs
+ to be enabled to select this.
config PCIE_IPROC_PLATFORM
tristate "Broadcom iProc PCIe platform bus driver"

View file

@ -0,0 +1,27 @@
From 57303e92f48a0e307fd86977ec9be5aa6a7ea681 Mon Sep 17 00:00:00 2001
From: "Dmitry V. Krivenok" <krivenok.dmitry@gmail.com>
Date: Mon, 30 Nov 2015 23:45:49 +0300
Subject: [PATCH] PCI: iproc: Do not use 0x in front of %pap
The "%pap" format adds a "0x" prefix, so using "0x%pap" results in output
of "0x0x...". Drop the "0x" prefix in the format string.
[bhelgaas: changelog]
Signed-off-by: Dmitry V. Krivenok <krivenok.dmitry@gmail.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Ray Jui <rjui@broadcom.com>
---
drivers/pci/host/pcie-iproc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/pci/host/pcie-iproc.c
+++ b/drivers/pci/host/pcie-iproc.c
@@ -245,7 +245,7 @@ static int iproc_pcie_setup_ob(struct ip
if (size > max_size) {
dev_err(pcie->dev,
- "res size 0x%pap exceeds max supported size 0x%llx\n",
+ "res size %pap exceeds max supported size 0x%llx\n",
&size, max_size);
return -EINVAL;
}

View file

@ -1,13 +1,14 @@
From d85a955118c8d8679d4f746fe2189c172d7c365f Mon Sep 17 00:00:00 2001
From e8b8318de645c04f8600cb5af6f6773a1878ee9d Mon Sep 17 00:00:00 2001
From: Ray Jui <rjui@broadcom.com>
Date: Mon, 16 Nov 2015 17:18:05 -0800
Subject: [PATCH 150/154] PCI: iproc: Update iProc PCIe device tree binding
Date: Fri, 4 Dec 2015 09:34:58 -0800
Subject: [PATCH 1/5] PCI: iproc: Update iProc PCIe device tree binding
Add a new compatible string "brcm,iproc-pcie-paxc", for PAXC based iProc
PCIe root complex. A PAXC based PCIe root complex is connected to
emulated endpoint devices internal to the ASIC
Add a new compatible string "brcm,iproc-pcie-paxc", for PAXC-based iProc
PCIe root complex. A PAXC-based PCIe root complex is connected to emulated
endpoint devices internal to the ASIC.
Signed-off-by: Ray Jui <rjui@broadcom.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Scott Branden <sbranden@broadcom.com>
---
Documentation/devicetree/bindings/pci/brcm,iproc-pcie.txt | 5 ++++-
@ -21,8 +22,8 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
Required properties:
-- compatible: Must be "brcm,iproc-pcie"
+- compatible: Must be "brcm,iproc-pcie" for PAXB, or "brcm,iproc-pcie-paxc"
+ for PAXC. PAXB based root complex is used for external endpoint devices.
+ PAXC based root complex is connected to emulated endpoint devices
+ for PAXC. PAXB-based root complex is used for external endpoint devices.
+ PAXC-based root complex is connected to emulated endpoint devices
+ internal to the ASIC
- reg: base address and length of the PCIe controller I/O register space
- #interrupt-cells: set to <1>

View file

@ -1,20 +1,21 @@
From a13fc4733b25d6dad6ec1826f09225c69ee21e3a Mon Sep 17 00:00:00 2001
From 943ebae781f519ecfecbfa1b997f15f59116e41d Mon Sep 17 00:00:00 2001
From: Ray Jui <rjui@broadcom.com>
Date: Mon, 16 Nov 2015 17:41:43 -0800
Subject: [PATCH 151/154] PCI: iproc: Add PAXC interface support
Date: Fri, 4 Dec 2015 09:34:59 -0800
Subject: [PATCH 2/5] PCI: iproc: Add PAXC interface support
Traditionally, all iProc PCIe root complexes use PAXB based wrapper,
with an integrated on-chip Serdes to support external endpoint devices.
On newer iProc platforms, a PAXC based wrapper is introduced, for
connection with internally emulated PCIe endpoint devices in the ASIC
Traditionally, all iProc PCIe root complexes use PAXB-based wrapper, with
an integrated on-chip Serdes to support external endpoint devices. On
newer iProc platforms, a PAXC-based wrapper is introduced, for connection
with internally emulated PCIe endpoint devices in the ASIC.
This patch adds support for PAXC based iProc PCIe root complex in the
iProc PCIe core driver. This change fators out common logic between
PAXB and PAXC, and use tables to store register offsets that are
different between PAXB and PAXC. This allows the driver to be scaled to
support subsequent PAXC revisions in the future
Add support for PAXC-based iProc PCIe root complex in the iProc PCIe core
driver. This change factors out common logic between PAXB and PAXC, and
uses tables to store register offsets that are different between PAXB and
PAXC. This allows the driver to be scaled to support subsequent PAXC
revisions in the future.
Signed-off-by: Ray Jui <rjui@broadcom.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Scott Branden <sbranden@broadcom.com>
---
drivers/pci/host/pcie-iproc-platform.c | 24 +++-
@ -324,7 +325,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
- val = readl(pcie->base + PCIE_LINK_STATUS_OFFSET);
+ /*
+ * PAXC connects to emulated endpoint devices directly and does not
+ * have a Serdes. Therefore skip the link detection logic here
+ * have a Serdes. Therefore skip the link detection logic here.
+ */
+ if (pcie->type == IPROC_PCIE_PAXC)
+ return 0;
@ -392,10 +393,10 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
+ * iProc PCIe interface type
+ *
+ * PAXB is the wrapper used in root complex that can be connected to an
+ * external endpoint device
+ * external endpoint device.
+ *
+ * PAXC is the wrapper used in root complex dedicated for internal emulated
+ * endpoint devices
+ * endpoint devices.
+ */
+enum iproc_pcie_type {
+ IPROC_PCIE_PAXB = 0,

View file

@ -1,12 +1,13 @@
From 96b40de5e36ec479dabb88500f1830a87818a809 Mon Sep 17 00:00:00 2001
From c7bd48195377435ecaf38869b936be8e7abe3489 Mon Sep 17 00:00:00 2001
From: Ray Jui <rjui@broadcom.com>
Date: Mon, 16 Nov 2015 17:57:33 -0800
Subject: [PATCH 152/154] PCI: iproc: Add iProc PCIe MSI device tree binding
Date: Fri, 4 Dec 2015 09:35:00 -0800
Subject: [PATCH 3/5] PCI: iproc: Add iProc PCIe MSI device tree binding
This patch updates the iProc PCIe device tree bindings with added
binding information for MSI
Update the iProc PCIe device tree bindings with added binding information
for MSI.
Signed-off-by: Ray Jui <rjui@broadcom.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Anup Patel <anup.patel@broadcom.com>
Reviewed-by: Vikram Prakash <vikramp@broadcom.com>
Reviewed-by: Scott Branden <sbranden@broadcom.com>
@ -29,7 +30,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
+- msi-parent: Link to the device node of the MSI controller. On newer iProc
+platforms, the MSI controller may be gicv2m or gicv3-its. On older iProc
+platforms without MSI support in its interrupt controller, one may use the
+event queue based MSI support integrated within the iProc PCIe core
+event queue based MSI support integrated within the iProc PCIe core.
+
+When the iProc event queue based MSI is used, one needs to define the
+following properties in the MSI device node:

View file

@ -1,73 +1,77 @@
From c81922174d61127ff5baad6059ae148794c72276 Mon Sep 17 00:00:00 2001
From 3bc2b2348835f6edd33c383a2fbcf15fe3dac3b2 Mon Sep 17 00:00:00 2001
From: Ray Jui <rjui@broadcom.com>
Date: Tue, 17 Nov 2015 13:14:37 -0800
Subject: [PATCH 153/154] PCI: iproc: Add iProc PCIe MSI support
Date: Wed, 6 Jan 2016 18:04:35 -0600
Subject: [PATCH 4/5] PCI: iproc: Add iProc PCIe MSI support
This patch adds PCIe MSI support for both PAXB and PAXC interfaces on
all iProc based platforms
Add PCIe MSI support for both PAXB and PAXC interfaces on all iProc-based
platforms.
The iProc PCIe MSI support deploys an event queue based implementation.
The iProc PCIe MSI support deploys an event queue-based implementation.
Each event queue is serviced by a GIC interrupt and can support up to 64
MSI vectors. Host memory is allocated for the event queues, and each event
queue consists of 64 word-sized entries. MSI data is written to the
lower 16-bit of each entry, whereas the upper 16-bit of the entry is
reserved for the controller for internal processing
queue consists of 64 word-sized entries. MSI data is written to the lower
16-bit of each entry, whereas the upper 16-bit of the entry is reserved for
the controller for internal processing.
Each event queue is tracked by a head pointer and tail pointer. Head
pointer indicates the next entry in the event queue to be processed by
the driver and is updated by the driver after processing is done.
The controller uses the tail pointer as the next MSI data insertion
point. The controller ensures MSI data is flushed to host memory before
updating the tail pointer and then triggering the interrupt
updating the tail pointer and then triggering the interrupt.
MSI IRQ affinity is supported by evenly distributing the interrupts to
each CPU core. MSI vector is moved from one GIC interrupt to another in
order to steer to the target CPU
MSI IRQ affinity is supported by evenly distributing the interrupts to each
CPU core. MSI vector is moved from one GIC interrupt to another in order
to steer to the target CPU.
Therefore, the actual number of supported MSI vectors is:
M * 64 / N
where M denotes the number of GIC interrupts (event queues), and N
denotes the number of CPU cores
where M denotes the number of GIC interrupts (event queues), and N denotes
the number of CPU cores.
This iProc event queue based MSI support should not be used with newer
This iProc event queue-based MSI support should not be used with newer
platforms with integrated MSI support in the GIC (e.g., giv2m or
gicv3-its)
gicv3-its).
[bhelgaas: fold in Kconfig fixes from Arnd Bergmann <arnd@arndb.de>]
Signed-off-by: Ray Jui <rjui@broadcom.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Anup Patel <anup.patel@broadcom.com>
Reviewed-by: Vikram Prakash <vikramp@broadcom.com>
Reviewed-by: Scott Branden <sbranden@broadcom.com>
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
---
drivers/pci/host/Kconfig | 9 +
drivers/pci/host/Kconfig | 10 +
drivers/pci/host/Makefile | 1 +
drivers/pci/host/pcie-iproc-bcma.c | 1 +
drivers/pci/host/pcie-iproc-msi.c | 675 +++++++++++++++++++++++++++++++++
drivers/pci/host/pcie-iproc-platform.c | 1 +
drivers/pci/host/pcie-iproc.c | 26 ++
drivers/pci/host/pcie-iproc.h | 23 +-
7 files changed, 734 insertions(+), 2 deletions(-)
7 files changed, 735 insertions(+), 2 deletions(-)
create mode 100644 drivers/pci/host/pcie-iproc-msi.c
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -127,6 +127,15 @@ config PCIE_IPROC
iProc family of SoCs. An appropriate bus interface driver also needs
to be enabled
@@ -146,6 +146,16 @@ config PCIE_IPROC_BCMA
Say Y here if you want to use the Broadcom iProc PCIe controller
through the BCMA bus interface
+config PCIE_IPROC_MSI
+ bool "Broadcom iProc PCIe MSI support"
+ depends on ARCH_BCM_IPROC && PCI_MSI
+ depends on PCIE_IPROC_PLATFORM || PCIE_IPROC_BCMA
+ depends on PCI_MSI
+ select PCI_MSI_IRQ_DOMAIN
+ default ARCH_BCM_IPROC
+ help
+ Say Y here if you want to enable MSI support for Broadcom's iProc
+ PCIe controller
+
config PCIE_IPROC_PLATFORM
tristate "Broadcom iProc PCIe platform bus driver"
depends on ARCH_BCM_IPROC || (ARM && COMPILE_TEST)
config PCIE_ALTERA
bool "Altera PCIe controller"
depends on ARM || NIOS2
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_PCI_XGENE_MSI) += pci-xgene
@ -123,16 +127,16 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
+
+#define IPROC_MSI_EQ_MASK 0x3f
+
+/* max number of GIC interrupts */
+/* Max number of GIC interrupts */
+#define NR_HW_IRQS 6
+
+/* number of entries in each event queue */
+/* Number of entries in each event queue */
+#define EQ_LEN 64
+
+/* size of each event queue memory region */
+/* Size of each event queue memory region */
+#define EQ_MEM_REGION_SIZE SZ_4K
+
+/* size of each MSI address region */
+/* Size of each MSI address region */
+#define MSI_MEM_REGION_SIZE SZ_4K
+
+enum iproc_msi_reg {
@ -153,7 +157,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
+ * iProc MSI group
+ *
+ * One MSI group is allocated per GIC interrupt, serviced by one iProc MSI
+ * event queue
+ * event queue.
+ *
+ * @msi: pointer to iProc MSI data
+ * @gic_irq: GIC interrupt
@ -169,7 +173,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
+ * iProc event queue based MSI
+ *
+ * Only meant to be used on platforms without MSI support integrated into the
+ * GIC
+ * GIC.
+ *
+ * @pcie: pointer to iProc PCIe data
+ * @reg_offsets: MSI register offsets
@ -278,12 +282,12 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
+
+/*
+ * In iProc PCIe core, each MSI group is serviced by a GIC interrupt and a
+ * dedicated event queue. Each MSI group can support up to 64 MSI vectors
+ * dedicated event queue. Each MSI group can support up to 64 MSI vectors.
+ *
+ * The number of MSI groups varies between different iProc SoCs. The total
+ * number of CPU cores also varies. To support MSI IRQ affinity, we
+ * distribute GIC interrupts across all available CPUs. MSI vector is moved
+ * from one GIC interrupt to another to steer to the target CPU
+ * from one GIC interrupt to another to steer to the target CPU.
+ *
+ * Assuming:
+ * - the number of MSI groups is M
@ -348,7 +352,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
+
+ mutex_lock(&msi->bitmap_lock);
+
+ /* allocate 'nr_cpus' number of MSI vectors each time */
+ /* Allocate 'nr_cpus' number of MSI vectors each time */
+ hwirq = bitmap_find_next_zero_area(msi->bitmap, msi->nr_msi_vecs, 0,
+ msi->nr_cpus, 0);
+ if (hwirq < msi->nr_msi_vecs) {
@ -400,7 +404,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
+ /*
+ * Since we have multiple hwirq mapped to a single MSI vector,
+ * now we need to derive the hwirq at CPU0. It can then be used to
+ * mapped back to virq
+ * mapped back to virq.
+ */
+ return hwirq_to_canonical_hwirq(msi, hwirq);
+}
@ -426,11 +430,11 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
+ * iProc MSI event queue is tracked by head and tail pointers. Head
+ * pointer indicates the next entry (MSI data) to be consumed by SW in
+ * the queue and needs to be updated by SW. iProc MSI core uses the
+ * tail pointer as the next data insertion point
+ * tail pointer as the next data insertion point.
+ *
+ * Entries between head and tail pointers contain valid MSI data. MSI
+ * data is guaranteed to be in the event queue memory before the tail
+ * pointer is updated by the iProc MSI core
+ * pointer is updated by the iProc MSI core.
+ */
+ head = iproc_msi_read_reg(msi, IPROC_MSI_EQ_HEAD,
+ eq) & IPROC_MSI_EQ_MASK;
@ -440,7 +444,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
+
+ /*
+ * Figure out total number of events (MSI data) to be
+ * processed
+ * processed.
+ */
+ nr_events = (tail < head) ?
+ (EQ_LEN - (head - tail)) : (tail - head);
@ -459,13 +463,13 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
+
+ /*
+ * Now all outstanding events have been processed. Update the
+ * head pointer
+ * head pointer.
+ */
+ iproc_msi_write_reg(msi, IPROC_MSI_EQ_HEAD, eq, head);
+
+ /*
+ * Now go read the tail pointer again to see if there are new
+ * oustanding events that came in during the above window
+ * oustanding events that came in during the above window.
+ */
+ } while (true);
+
@ -477,7 +481,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
+ int i, eq;
+ u32 val;
+
+ /* program memory region for each event queue */
+ /* Program memory region for each event queue */
+ for (i = 0; i < msi->nr_eq_region; i++) {
+ dma_addr_t addr = msi->eq_dma + (i * EQ_MEM_REGION_SIZE);
+
@ -487,7 +491,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
+ upper_32_bits(addr));
+ }
+
+ /* program address region for MSI posted writes */
+ /* Program address region for MSI posted writes */
+ for (i = 0; i < msi->nr_msi_region; i++) {
+ phys_addr_t addr = msi->msi_addr + (i * MSI_MEM_REGION_SIZE);
+
@ -498,14 +502,14 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
+ }
+
+ for (eq = 0; eq < msi->nr_irqs; eq++) {
+ /* enable MSI event queue */
+ /* Enable MSI event queue */
+ val = IPROC_MSI_INTR_EN | IPROC_MSI_INT_N_EVENT |
+ IPROC_MSI_EQ_EN;
+ iproc_msi_write_reg(msi, IPROC_MSI_CTRL, eq, val);
+
+ /*
+ * Some legacy platforms require the MSI interrupt enable
+ * register to be set explicitly
+ * register to be set explicitly.
+ */
+ if (msi->has_inten_reg) {
+ val = iproc_msi_read_reg(msi, IPROC_MSI_INTS_EN, eq);
@ -581,7 +585,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
+ irq_set_chained_handler_and_data(msi->grps[i].gic_irq,
+ iproc_msi_handler,
+ &msi->grps[i]);
+ /* dedicate GIC interrupt to each CPU core */
+ /* Dedicate GIC interrupt to each CPU core */
+ if (alloc_cpumask_var(&mask, GFP_KERNEL)) {
+ cpumask_clear(mask);
+ cpumask_set_cpu(cpu, mask);
@ -597,7 +601,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
+ }
+
+ if (ret) {
+ /* free all configured/unconfigured irqs */
+ /* Free all configured/unconfigured IRQs */
+ iproc_msi_irq_free(msi, cpu);
+ return ret;
+ }
@ -698,7 +702,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
+ msi->grps[i].eq = i;
+ }
+
+ /* reserve memory for event queue and make sure memories are zeroed */
+ /* Reserve memory for event queue and make sure memories are zeroed */
+ msi->eq_cpu = dma_zalloc_coherent(pcie->dev,
+ msi->nr_eq_region * EQ_MEM_REGION_SIZE,
+ &msi->eq_dma, GFP_KERNEL);
@ -870,7 +874,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res);
int iproc_pcie_remove(struct iproc_pcie *pcie);
+#ifdef CONFIG_PCI_MSI
+#ifdef CONFIG_PCIE_IPROC_MSI
+int iproc_msi_init(struct iproc_pcie *pcie, struct device_node *node);
+void iproc_msi_exit(struct iproc_pcie *pcie);
+#else
@ -879,7 +883,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
+{
+ return -ENODEV;
+}
+static void iproc_msi_exit(struct iproc_pcie *pcie)
+static inline void iproc_msi_exit(struct iproc_pcie *pcie)
+{
+}
+#endif