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:
parent
76b903a415
commit
b9fb3d4524
12 changed files with 341 additions and 190 deletions
|
@ -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"
|
|
@ -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;
|
||||
}
|
|
@ -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>
|
|
@ -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,
|
|
@ -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:
|
|
@ -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
|
|
@ -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"
|
|
@ -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;
|
||||
}
|
|
@ -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>
|
|
@ -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,
|
|
@ -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:
|
|
@ -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
|
Loading…
Reference in a new issue