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>
|
From: Ray Jui <rjui@broadcom.com>
|
||||||
Date: Mon, 16 Nov 2015 17:18:05 -0800
|
Date: Fri, 4 Dec 2015 09:34:58 -0800
|
||||||
Subject: [PATCH 150/154] PCI: iproc: Update iProc PCIe device tree binding
|
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
|
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
|
PCIe root complex. A PAXC-based PCIe root complex is connected to emulated
|
||||||
emulated endpoint devices internal to the ASIC
|
endpoint devices internal to the ASIC.
|
||||||
|
|
||||||
Signed-off-by: Ray Jui <rjui@broadcom.com>
|
Signed-off-by: Ray Jui <rjui@broadcom.com>
|
||||||
|
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
|
||||||
Reviewed-by: Scott Branden <sbranden@broadcom.com>
|
Reviewed-by: Scott Branden <sbranden@broadcom.com>
|
||||||
---
|
---
|
||||||
Documentation/devicetree/bindings/pci/brcm,iproc-pcie.txt | 5 ++++-
|
Documentation/devicetree/bindings/pci/brcm,iproc-pcie.txt | 5 ++++-
|
||||||
|
@ -21,8 +22,8 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
|
||||||
Required properties:
|
Required properties:
|
||||||
-- compatible: Must be "brcm,iproc-pcie"
|
-- compatible: Must be "brcm,iproc-pcie"
|
||||||
+- compatible: Must be "brcm,iproc-pcie" for PAXB, or "brcm,iproc-pcie-paxc"
|
+- 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.
|
+ for PAXC. PAXB-based root complex is used for external endpoint devices.
|
||||||
+ PAXC based root complex is connected to emulated endpoint devices
|
+ PAXC-based root complex is connected to emulated endpoint devices
|
||||||
+ internal to the ASIC
|
+ internal to the ASIC
|
||||||
- reg: base address and length of the PCIe controller I/O register space
|
- reg: base address and length of the PCIe controller I/O register space
|
||||||
- #interrupt-cells: set to <1>
|
- #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>
|
From: Ray Jui <rjui@broadcom.com>
|
||||||
Date: Mon, 16 Nov 2015 17:41:43 -0800
|
Date: Fri, 4 Dec 2015 09:34:59 -0800
|
||||||
Subject: [PATCH 151/154] PCI: iproc: Add PAXC interface support
|
Subject: [PATCH 2/5] PCI: iproc: Add PAXC interface support
|
||||||
|
|
||||||
Traditionally, all iProc PCIe root complexes use PAXB based wrapper,
|
Traditionally, all iProc PCIe root complexes use PAXB-based wrapper, with
|
||||||
with an integrated on-chip Serdes to support external endpoint devices.
|
an integrated on-chip Serdes to support external endpoint devices. On
|
||||||
On newer iProc platforms, a PAXC based wrapper is introduced, for
|
newer iProc platforms, a PAXC-based wrapper is introduced, for connection
|
||||||
connection with internally emulated PCIe endpoint devices in the ASIC
|
with internally emulated PCIe endpoint devices in the ASIC.
|
||||||
|
|
||||||
This patch adds support for PAXC based iProc PCIe root complex in the
|
Add support for PAXC-based iProc PCIe root complex in the iProc PCIe core
|
||||||
iProc PCIe core driver. This change fators out common logic between
|
driver. This change factors out common logic between PAXB and PAXC, and
|
||||||
PAXB and PAXC, and use tables to store register offsets that are
|
uses tables to store register offsets that are different between PAXB and
|
||||||
different between PAXB and PAXC. This allows the driver to be scaled to
|
PAXC. This allows the driver to be scaled to support subsequent PAXC
|
||||||
support subsequent PAXC revisions in the future
|
revisions in the future.
|
||||||
|
|
||||||
Signed-off-by: Ray Jui <rjui@broadcom.com>
|
Signed-off-by: Ray Jui <rjui@broadcom.com>
|
||||||
|
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
|
||||||
Reviewed-by: Scott Branden <sbranden@broadcom.com>
|
Reviewed-by: Scott Branden <sbranden@broadcom.com>
|
||||||
---
|
---
|
||||||
drivers/pci/host/pcie-iproc-platform.c | 24 +++-
|
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);
|
- val = readl(pcie->base + PCIE_LINK_STATUS_OFFSET);
|
||||||
+ /*
|
+ /*
|
||||||
+ * PAXC connects to emulated endpoint devices directly and does not
|
+ * 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)
|
+ if (pcie->type == IPROC_PCIE_PAXC)
|
||||||
+ return 0;
|
+ return 0;
|
||||||
|
@ -392,10 +393,10 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
|
||||||
+ * iProc PCIe interface type
|
+ * iProc PCIe interface type
|
||||||
+ *
|
+ *
|
||||||
+ * PAXB is the wrapper used in root complex that can be connected to an
|
+ * 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
|
+ * PAXC is the wrapper used in root complex dedicated for internal emulated
|
||||||
+ * endpoint devices
|
+ * endpoint devices.
|
||||||
+ */
|
+ */
|
||||||
+enum iproc_pcie_type {
|
+enum iproc_pcie_type {
|
||||||
+ IPROC_PCIE_PAXB = 0,
|
+ 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>
|
From: Ray Jui <rjui@broadcom.com>
|
||||||
Date: Mon, 16 Nov 2015 17:57:33 -0800
|
Date: Fri, 4 Dec 2015 09:35:00 -0800
|
||||||
Subject: [PATCH 152/154] PCI: iproc: Add iProc PCIe MSI device tree binding
|
Subject: [PATCH 3/5] PCI: iproc: Add iProc PCIe MSI device tree binding
|
||||||
|
|
||||||
This patch updates the iProc PCIe device tree bindings with added
|
Update the iProc PCIe device tree bindings with added binding information
|
||||||
binding information for MSI
|
for MSI.
|
||||||
|
|
||||||
Signed-off-by: Ray Jui <rjui@broadcom.com>
|
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: Anup Patel <anup.patel@broadcom.com>
|
||||||
Reviewed-by: Vikram Prakash <vikramp@broadcom.com>
|
Reviewed-by: Vikram Prakash <vikramp@broadcom.com>
|
||||||
Reviewed-by: Scott Branden <sbranden@broadcom.com>
|
Reviewed-by: Scott Branden <sbranden@broadcom.com>
|
||||||
|
@ -23,13 +24,13 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
|
||||||
+MSI support (optional):
|
+MSI support (optional):
|
||||||
+
|
+
|
||||||
+For older platforms without MSI integrated in the GIC, iProc PCIe core provides
|
+For older platforms without MSI integrated in the GIC, iProc PCIe core provides
|
||||||
+an event queue based MSI support. The iProc MSI uses host memories to store
|
+an event queue based MSI support. The iProc MSI uses host memories to store
|
||||||
+MSI posted writes in the event queues
|
+MSI posted writes in the event queues
|
||||||
+
|
+
|
||||||
+- msi-parent: Link to the device node of the MSI controller. On newer iProc
|
+- 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, the MSI controller may be gicv2m or gicv3-its. On older iProc
|
||||||
+platforms without MSI support in its interrupt controller, one may use the
|
+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
|
+When the iProc event queue based MSI is used, one needs to define the
|
||||||
+following properties in the MSI device node:
|
+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>
|
From: Ray Jui <rjui@broadcom.com>
|
||||||
Date: Tue, 17 Nov 2015 13:14:37 -0800
|
Date: Wed, 6 Jan 2016 18:04:35 -0600
|
||||||
Subject: [PATCH 153/154] PCI: iproc: Add iProc PCIe MSI support
|
Subject: [PATCH 4/5] PCI: iproc: Add iProc PCIe MSI support
|
||||||
|
|
||||||
This patch adds PCIe MSI support for both PAXB and PAXC interfaces on
|
Add PCIe MSI support for both PAXB and PAXC interfaces on all iProc-based
|
||||||
all iProc based platforms
|
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
|
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
|
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
|
queue consists of 64 word-sized entries. MSI data is written to the lower
|
||||||
lower 16-bit of each entry, whereas the upper 16-bit of the entry is
|
16-bit of each entry, whereas the upper 16-bit of the entry is reserved for
|
||||||
reserved for the controller for internal processing
|
the controller for internal processing.
|
||||||
|
|
||||||
Each event queue is tracked by a head pointer and tail pointer. Head
|
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
|
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 driver and is updated by the driver after processing is done.
|
||||||
The controller uses the tail pointer as the next MSI data insertion
|
The controller uses the tail pointer as the next MSI data insertion
|
||||||
point. The controller ensures MSI data is flushed to host memory before
|
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
|
MSI IRQ affinity is supported by evenly distributing the interrupts to each
|
||||||
each CPU core. MSI vector is moved from one GIC interrupt to another in
|
CPU core. MSI vector is moved from one GIC interrupt to another in order
|
||||||
order to steer to the target CPU
|
to steer to the target CPU.
|
||||||
|
|
||||||
Therefore, the actual number of supported MSI vectors is:
|
Therefore, the actual number of supported MSI vectors is:
|
||||||
|
|
||||||
M * 64 / N
|
M * 64 / N
|
||||||
|
|
||||||
where M denotes the number of GIC interrupts (event queues), and N
|
where M denotes the number of GIC interrupts (event queues), and N denotes
|
||||||
denotes the number of CPU cores
|
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
|
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: Ray Jui <rjui@broadcom.com>
|
||||||
|
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
|
||||||
Reviewed-by: Anup Patel <anup.patel@broadcom.com>
|
Reviewed-by: Anup Patel <anup.patel@broadcom.com>
|
||||||
Reviewed-by: Vikram Prakash <vikramp@broadcom.com>
|
Reviewed-by: Vikram Prakash <vikramp@broadcom.com>
|
||||||
Reviewed-by: Scott Branden <sbranden@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/Makefile | 1 +
|
||||||
drivers/pci/host/pcie-iproc-bcma.c | 1 +
|
drivers/pci/host/pcie-iproc-bcma.c | 1 +
|
||||||
drivers/pci/host/pcie-iproc-msi.c | 675 +++++++++++++++++++++++++++++++++
|
drivers/pci/host/pcie-iproc-msi.c | 675 +++++++++++++++++++++++++++++++++
|
||||||
drivers/pci/host/pcie-iproc-platform.c | 1 +
|
drivers/pci/host/pcie-iproc-platform.c | 1 +
|
||||||
drivers/pci/host/pcie-iproc.c | 26 ++
|
drivers/pci/host/pcie-iproc.c | 26 ++
|
||||||
drivers/pci/host/pcie-iproc.h | 23 +-
|
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
|
create mode 100644 drivers/pci/host/pcie-iproc-msi.c
|
||||||
|
|
||||||
--- a/drivers/pci/host/Kconfig
|
--- a/drivers/pci/host/Kconfig
|
||||||
+++ b/drivers/pci/host/Kconfig
|
+++ b/drivers/pci/host/Kconfig
|
||||||
@@ -115,6 +115,15 @@ config PCIE_IPROC
|
@@ -133,5 +133,15 @@ config PCIE_IPROC_BCMA
|
||||||
iProc family of SoCs. An appropriate bus interface driver also needs
|
help
|
||||||
to be enabled
|
Say Y here if you want to use the Broadcom iProc PCIe controller
|
||||||
|
through the BCMA bus interface
|
||||||
|
+
|
||||||
+config PCIE_IPROC_MSI
|
+config PCIE_IPROC_MSI
|
||||||
+ bool "Broadcom iProc PCIe MSI support"
|
+ 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
|
+ select PCI_MSI_IRQ_DOMAIN
|
||||||
+ default ARCH_BCM_IPROC
|
+ default ARCH_BCM_IPROC
|
||||||
+ help
|
+ help
|
||||||
+ Say Y here if you want to enable MSI support for Broadcom's iProc
|
+ Say Y here if you want to enable MSI support for Broadcom's iProc
|
||||||
+ PCIe controller
|
+ PCIe controller
|
||||||
+
|
|
||||||
config PCIE_IPROC_PLATFORM
|
endmenu
|
||||||
tristate "Broadcom iProc PCIe platform bus driver"
|
|
||||||
depends on ARCH_BCM_IPROC || (ARM && COMPILE_TEST)
|
|
||||||
--- a/drivers/pci/host/Makefile
|
--- a/drivers/pci/host/Makefile
|
||||||
+++ b/drivers/pci/host/Makefile
|
+++ b/drivers/pci/host/Makefile
|
||||||
@@ -14,5 +14,6 @@ obj-$(CONFIG_PCI_XGENE) += pci-xgene.o
|
@@ -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
|
+#define IPROC_MSI_EQ_MASK 0x3f
|
||||||
+
|
+
|
||||||
+/* max number of GIC interrupts */
|
+/* Max number of GIC interrupts */
|
||||||
+#define NR_HW_IRQS 6
|
+#define NR_HW_IRQS 6
|
||||||
+
|
+
|
||||||
+/* number of entries in each event queue */
|
+/* Number of entries in each event queue */
|
||||||
+#define EQ_LEN 64
|
+#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
|
+#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
|
+#define MSI_MEM_REGION_SIZE SZ_4K
|
||||||
+
|
+
|
||||||
+enum iproc_msi_reg {
|
+enum iproc_msi_reg {
|
||||||
|
@ -152,7 +155,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
|
||||||
+ * iProc MSI group
|
+ * iProc MSI group
|
||||||
+ *
|
+ *
|
||||||
+ * One MSI group is allocated per GIC interrupt, serviced by one iProc MSI
|
+ * One MSI group is allocated per GIC interrupt, serviced by one iProc MSI
|
||||||
+ * event queue
|
+ * event queue.
|
||||||
+ *
|
+ *
|
||||||
+ * @msi: pointer to iProc MSI data
|
+ * @msi: pointer to iProc MSI data
|
||||||
+ * @gic_irq: GIC interrupt
|
+ * @gic_irq: GIC interrupt
|
||||||
|
@ -168,7 +171,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
|
||||||
+ * iProc event queue based MSI
|
+ * iProc event queue based MSI
|
||||||
+ *
|
+ *
|
||||||
+ * Only meant to be used on platforms without MSI support integrated into the
|
+ * Only meant to be used on platforms without MSI support integrated into the
|
||||||
+ * GIC
|
+ * GIC.
|
||||||
+ *
|
+ *
|
||||||
+ * @pcie: pointer to iProc PCIe data
|
+ * @pcie: pointer to iProc PCIe data
|
||||||
+ * @reg_offsets: MSI register offsets
|
+ * @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
|
+ * 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
|
+ * The number of MSI groups varies between different iProc SoCs. The total
|
||||||
+ * number of CPU cores also varies. To support MSI IRQ affinity, we
|
+ * number of CPU cores also varies. To support MSI IRQ affinity, we
|
||||||
+ * distribute GIC interrupts across all available CPUs. MSI vector is moved
|
+ * 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:
|
+ * Assuming:
|
||||||
+ * - the number of MSI groups is M
|
+ * - the number of MSI groups is M
|
||||||
|
@ -347,7 +350,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
|
||||||
+
|
+
|
||||||
+ mutex_lock(&msi->bitmap_lock);
|
+ 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,
|
+ hwirq = bitmap_find_next_zero_area(msi->bitmap, msi->nr_msi_vecs, 0,
|
||||||
+ msi->nr_cpus, 0);
|
+ msi->nr_cpus, 0);
|
||||||
+ if (hwirq < msi->nr_msi_vecs) {
|
+ if (hwirq < msi->nr_msi_vecs) {
|
||||||
|
@ -398,8 +401,8 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
|
||||||
+
|
+
|
||||||
+ /*
|
+ /*
|
||||||
+ * Since we have multiple hwirq mapped to a single MSI vector,
|
+ * 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
|
+ * 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);
|
+ return hwirq_to_canonical_hwirq(msi, hwirq);
|
||||||
+}
|
+}
|
||||||
|
@ -422,14 +425,14 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
|
||||||
+ eq = grp->eq;
|
+ eq = grp->eq;
|
||||||
+
|
+
|
||||||
+ /*
|
+ /*
|
||||||
+ * iProc MSI event queue is tracked by head and tail pointers. Head
|
+ * 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
|
+ * 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
|
+ * 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
|
+ * Entries between head and tail pointers contain valid MSI data. MSI
|
||||||
+ * data is guaranteed to be in the event queue memory before the tail
|
+ * 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,
|
+ head = iproc_msi_read_reg(msi, IPROC_MSI_EQ_HEAD,
|
||||||
+ eq) & IPROC_MSI_EQ_MASK;
|
+ 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
|
+ * Figure out total number of events (MSI data) to be
|
||||||
+ * processed
|
+ * processed.
|
||||||
+ */
|
+ */
|
||||||
+ nr_events = (tail < head) ?
|
+ nr_events = (tail < head) ?
|
||||||
+ (EQ_LEN - (head - tail)) : (tail - head);
|
+ (EQ_LEN - (head - tail)) : (tail - head);
|
||||||
|
@ -457,14 +460,14 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ /*
|
+ /*
|
||||||
+ * Now all outstanding events have been processed. Update the
|
+ * Now all outstanding events have been processed. Update the
|
||||||
+ * head pointer
|
+ * head pointer.
|
||||||
+ */
|
+ */
|
||||||
+ iproc_msi_write_reg(msi, IPROC_MSI_EQ_HEAD, eq, head);
|
+ iproc_msi_write_reg(msi, IPROC_MSI_EQ_HEAD, eq, head);
|
||||||
+
|
+
|
||||||
+ /*
|
+ /*
|
||||||
+ * Now go read the tail pointer again to see if there are new
|
+ * 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);
|
+ } while (true);
|
||||||
+
|
+
|
||||||
|
@ -476,7 +479,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
|
||||||
+ int i, eq;
|
+ int i, eq;
|
||||||
+ u32 val;
|
+ 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++) {
|
+ for (i = 0; i < msi->nr_eq_region; i++) {
|
||||||
+ dma_addr_t addr = msi->eq_dma + (i * EQ_MEM_REGION_SIZE);
|
+ 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));
|
+ 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++) {
|
+ for (i = 0; i < msi->nr_msi_region; i++) {
|
||||||
+ phys_addr_t addr = msi->msi_addr + (i * MSI_MEM_REGION_SIZE);
|
+ 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++) {
|
+ 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 |
|
+ val = IPROC_MSI_INTR_EN | IPROC_MSI_INT_N_EVENT |
|
||||||
+ IPROC_MSI_EQ_EN;
|
+ IPROC_MSI_EQ_EN;
|
||||||
+ iproc_msi_write_reg(msi, IPROC_MSI_CTRL, eq, val);
|
+ iproc_msi_write_reg(msi, IPROC_MSI_CTRL, eq, val);
|
||||||
+
|
+
|
||||||
+ /*
|
+ /*
|
||||||
+ * Some legacy platforms require the MSI interrupt enable
|
+ * Some legacy platforms require the MSI interrupt enable
|
||||||
+ * register to be set explicitly
|
+ * register to be set explicitly.
|
||||||
+ */
|
+ */
|
||||||
+ if (msi->has_inten_reg) {
|
+ if (msi->has_inten_reg) {
|
||||||
+ val = iproc_msi_read_reg(msi, IPROC_MSI_INTS_EN, eq);
|
+ 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,
|
+ irq_set_chained_handler_and_data(msi->grps[i].gic_irq,
|
||||||
+ iproc_msi_handler,
|
+ iproc_msi_handler,
|
||||||
+ &msi->grps[i]);
|
+ &msi->grps[i]);
|
||||||
+ /* dedicate GIC interrupt to each CPU core */
|
+ /* Dedicate GIC interrupt to each CPU core */
|
||||||
+ if (alloc_cpumask_var(&mask, GFP_KERNEL)) {
|
+ if (alloc_cpumask_var(&mask, GFP_KERNEL)) {
|
||||||
+ cpumask_clear(mask);
|
+ cpumask_clear(mask);
|
||||||
+ cpumask_set_cpu(cpu, mask);
|
+ cpumask_set_cpu(cpu, mask);
|
||||||
|
@ -596,7 +599,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ if (ret) {
|
+ if (ret) {
|
||||||
+ /* free all configured/unconfigured irqs */
|
+ /* Free all configured/unconfigured IRQs */
|
||||||
+ iproc_msi_irq_free(msi, cpu);
|
+ iproc_msi_irq_free(msi, cpu);
|
||||||
+ return ret;
|
+ return ret;
|
||||||
+ }
|
+ }
|
||||||
|
@ -697,7 +700,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
|
||||||
+ msi->grps[i].eq = i;
|
+ 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->eq_cpu = dma_zalloc_coherent(pcie->dev,
|
||||||
+ msi->nr_eq_region * EQ_MEM_REGION_SIZE,
|
+ msi->nr_eq_region * EQ_MEM_REGION_SIZE,
|
||||||
+ &msi->eq_dma, GFP_KERNEL);
|
+ &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_setup(struct iproc_pcie *pcie, struct list_head *res);
|
||||||
int iproc_pcie_remove(struct iproc_pcie *pcie);
|
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);
|
+int iproc_msi_init(struct iproc_pcie *pcie, struct device_node *node);
|
||||||
+void iproc_msi_exit(struct iproc_pcie *pcie);
|
+void iproc_msi_exit(struct iproc_pcie *pcie);
|
||||||
+#else
|
+#else
|
||||||
|
@ -878,7 +881,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
|
||||||
+{
|
+{
|
||||||
+ return -ENODEV;
|
+ return -ENODEV;
|
||||||
+}
|
+}
|
||||||
+static void iproc_msi_exit(struct iproc_pcie *pcie)
|
+static inline void iproc_msi_exit(struct iproc_pcie *pcie)
|
||||||
+{
|
+{
|
||||||
+}
|
+}
|
||||||
+#endif
|
+#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>
|
From: Ray Jui <rjui@broadcom.com>
|
||||||
Date: Mon, 16 Nov 2015 17:18:05 -0800
|
Date: Fri, 4 Dec 2015 09:34:58 -0800
|
||||||
Subject: [PATCH 150/154] PCI: iproc: Update iProc PCIe device tree binding
|
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
|
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
|
PCIe root complex. A PAXC-based PCIe root complex is connected to emulated
|
||||||
emulated endpoint devices internal to the ASIC
|
endpoint devices internal to the ASIC.
|
||||||
|
|
||||||
Signed-off-by: Ray Jui <rjui@broadcom.com>
|
Signed-off-by: Ray Jui <rjui@broadcom.com>
|
||||||
|
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
|
||||||
Reviewed-by: Scott Branden <sbranden@broadcom.com>
|
Reviewed-by: Scott Branden <sbranden@broadcom.com>
|
||||||
---
|
---
|
||||||
Documentation/devicetree/bindings/pci/brcm,iproc-pcie.txt | 5 ++++-
|
Documentation/devicetree/bindings/pci/brcm,iproc-pcie.txt | 5 ++++-
|
||||||
|
@ -21,8 +22,8 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
|
||||||
Required properties:
|
Required properties:
|
||||||
-- compatible: Must be "brcm,iproc-pcie"
|
-- compatible: Must be "brcm,iproc-pcie"
|
||||||
+- compatible: Must be "brcm,iproc-pcie" for PAXB, or "brcm,iproc-pcie-paxc"
|
+- 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.
|
+ for PAXC. PAXB-based root complex is used for external endpoint devices.
|
||||||
+ PAXC based root complex is connected to emulated endpoint devices
|
+ PAXC-based root complex is connected to emulated endpoint devices
|
||||||
+ internal to the ASIC
|
+ internal to the ASIC
|
||||||
- reg: base address and length of the PCIe controller I/O register space
|
- reg: base address and length of the PCIe controller I/O register space
|
||||||
- #interrupt-cells: set to <1>
|
- #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>
|
From: Ray Jui <rjui@broadcom.com>
|
||||||
Date: Mon, 16 Nov 2015 17:41:43 -0800
|
Date: Fri, 4 Dec 2015 09:34:59 -0800
|
||||||
Subject: [PATCH 151/154] PCI: iproc: Add PAXC interface support
|
Subject: [PATCH 2/5] PCI: iproc: Add PAXC interface support
|
||||||
|
|
||||||
Traditionally, all iProc PCIe root complexes use PAXB based wrapper,
|
Traditionally, all iProc PCIe root complexes use PAXB-based wrapper, with
|
||||||
with an integrated on-chip Serdes to support external endpoint devices.
|
an integrated on-chip Serdes to support external endpoint devices. On
|
||||||
On newer iProc platforms, a PAXC based wrapper is introduced, for
|
newer iProc platforms, a PAXC-based wrapper is introduced, for connection
|
||||||
connection with internally emulated PCIe endpoint devices in the ASIC
|
with internally emulated PCIe endpoint devices in the ASIC.
|
||||||
|
|
||||||
This patch adds support for PAXC based iProc PCIe root complex in the
|
Add support for PAXC-based iProc PCIe root complex in the iProc PCIe core
|
||||||
iProc PCIe core driver. This change fators out common logic between
|
driver. This change factors out common logic between PAXB and PAXC, and
|
||||||
PAXB and PAXC, and use tables to store register offsets that are
|
uses tables to store register offsets that are different between PAXB and
|
||||||
different between PAXB and PAXC. This allows the driver to be scaled to
|
PAXC. This allows the driver to be scaled to support subsequent PAXC
|
||||||
support subsequent PAXC revisions in the future
|
revisions in the future.
|
||||||
|
|
||||||
Signed-off-by: Ray Jui <rjui@broadcom.com>
|
Signed-off-by: Ray Jui <rjui@broadcom.com>
|
||||||
|
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
|
||||||
Reviewed-by: Scott Branden <sbranden@broadcom.com>
|
Reviewed-by: Scott Branden <sbranden@broadcom.com>
|
||||||
---
|
---
|
||||||
drivers/pci/host/pcie-iproc-platform.c | 24 +++-
|
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);
|
- val = readl(pcie->base + PCIE_LINK_STATUS_OFFSET);
|
||||||
+ /*
|
+ /*
|
||||||
+ * PAXC connects to emulated endpoint devices directly and does not
|
+ * 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)
|
+ if (pcie->type == IPROC_PCIE_PAXC)
|
||||||
+ return 0;
|
+ return 0;
|
||||||
|
@ -392,10 +393,10 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
|
||||||
+ * iProc PCIe interface type
|
+ * iProc PCIe interface type
|
||||||
+ *
|
+ *
|
||||||
+ * PAXB is the wrapper used in root complex that can be connected to an
|
+ * 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
|
+ * PAXC is the wrapper used in root complex dedicated for internal emulated
|
||||||
+ * endpoint devices
|
+ * endpoint devices.
|
||||||
+ */
|
+ */
|
||||||
+enum iproc_pcie_type {
|
+enum iproc_pcie_type {
|
||||||
+ IPROC_PCIE_PAXB = 0,
|
+ 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>
|
From: Ray Jui <rjui@broadcom.com>
|
||||||
Date: Mon, 16 Nov 2015 17:57:33 -0800
|
Date: Fri, 4 Dec 2015 09:35:00 -0800
|
||||||
Subject: [PATCH 152/154] PCI: iproc: Add iProc PCIe MSI device tree binding
|
Subject: [PATCH 3/5] PCI: iproc: Add iProc PCIe MSI device tree binding
|
||||||
|
|
||||||
This patch updates the iProc PCIe device tree bindings with added
|
Update the iProc PCIe device tree bindings with added binding information
|
||||||
binding information for MSI
|
for MSI.
|
||||||
|
|
||||||
Signed-off-by: Ray Jui <rjui@broadcom.com>
|
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: Anup Patel <anup.patel@broadcom.com>
|
||||||
Reviewed-by: Vikram Prakash <vikramp@broadcom.com>
|
Reviewed-by: Vikram Prakash <vikramp@broadcom.com>
|
||||||
Reviewed-by: Scott Branden <sbranden@broadcom.com>
|
Reviewed-by: Scott Branden <sbranden@broadcom.com>
|
||||||
|
@ -23,13 +24,13 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
|
||||||
+MSI support (optional):
|
+MSI support (optional):
|
||||||
+
|
+
|
||||||
+For older platforms without MSI integrated in the GIC, iProc PCIe core provides
|
+For older platforms without MSI integrated in the GIC, iProc PCIe core provides
|
||||||
+an event queue based MSI support. The iProc MSI uses host memories to store
|
+an event queue based MSI support. The iProc MSI uses host memories to store
|
||||||
+MSI posted writes in the event queues
|
+MSI posted writes in the event queues
|
||||||
+
|
+
|
||||||
+- msi-parent: Link to the device node of the MSI controller. On newer iProc
|
+- 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, the MSI controller may be gicv2m or gicv3-its. On older iProc
|
||||||
+platforms without MSI support in its interrupt controller, one may use the
|
+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
|
+When the iProc event queue based MSI is used, one needs to define the
|
||||||
+following properties in the MSI device node:
|
+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>
|
From: Ray Jui <rjui@broadcom.com>
|
||||||
Date: Tue, 17 Nov 2015 13:14:37 -0800
|
Date: Wed, 6 Jan 2016 18:04:35 -0600
|
||||||
Subject: [PATCH 153/154] PCI: iproc: Add iProc PCIe MSI support
|
Subject: [PATCH 4/5] PCI: iproc: Add iProc PCIe MSI support
|
||||||
|
|
||||||
This patch adds PCIe MSI support for both PAXB and PAXC interfaces on
|
Add PCIe MSI support for both PAXB and PAXC interfaces on all iProc-based
|
||||||
all iProc based platforms
|
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
|
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
|
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
|
queue consists of 64 word-sized entries. MSI data is written to the lower
|
||||||
lower 16-bit of each entry, whereas the upper 16-bit of the entry is
|
16-bit of each entry, whereas the upper 16-bit of the entry is reserved for
|
||||||
reserved for the controller for internal processing
|
the controller for internal processing.
|
||||||
|
|
||||||
Each event queue is tracked by a head pointer and tail pointer. Head
|
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
|
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 driver and is updated by the driver after processing is done.
|
||||||
The controller uses the tail pointer as the next MSI data insertion
|
The controller uses the tail pointer as the next MSI data insertion
|
||||||
point. The controller ensures MSI data is flushed to host memory before
|
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
|
MSI IRQ affinity is supported by evenly distributing the interrupts to each
|
||||||
each CPU core. MSI vector is moved from one GIC interrupt to another in
|
CPU core. MSI vector is moved from one GIC interrupt to another in order
|
||||||
order to steer to the target CPU
|
to steer to the target CPU.
|
||||||
|
|
||||||
Therefore, the actual number of supported MSI vectors is:
|
Therefore, the actual number of supported MSI vectors is:
|
||||||
|
|
||||||
M * 64 / N
|
M * 64 / N
|
||||||
|
|
||||||
where M denotes the number of GIC interrupts (event queues), and N
|
where M denotes the number of GIC interrupts (event queues), and N denotes
|
||||||
denotes the number of CPU cores
|
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
|
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: Ray Jui <rjui@broadcom.com>
|
||||||
|
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
|
||||||
Reviewed-by: Anup Patel <anup.patel@broadcom.com>
|
Reviewed-by: Anup Patel <anup.patel@broadcom.com>
|
||||||
Reviewed-by: Vikram Prakash <vikramp@broadcom.com>
|
Reviewed-by: Vikram Prakash <vikramp@broadcom.com>
|
||||||
Reviewed-by: Scott Branden <sbranden@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/Makefile | 1 +
|
||||||
drivers/pci/host/pcie-iproc-bcma.c | 1 +
|
drivers/pci/host/pcie-iproc-bcma.c | 1 +
|
||||||
drivers/pci/host/pcie-iproc-msi.c | 675 +++++++++++++++++++++++++++++++++
|
drivers/pci/host/pcie-iproc-msi.c | 675 +++++++++++++++++++++++++++++++++
|
||||||
drivers/pci/host/pcie-iproc-platform.c | 1 +
|
drivers/pci/host/pcie-iproc-platform.c | 1 +
|
||||||
drivers/pci/host/pcie-iproc.c | 26 ++
|
drivers/pci/host/pcie-iproc.c | 26 ++
|
||||||
drivers/pci/host/pcie-iproc.h | 23 +-
|
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
|
create mode 100644 drivers/pci/host/pcie-iproc-msi.c
|
||||||
|
|
||||||
--- a/drivers/pci/host/Kconfig
|
--- a/drivers/pci/host/Kconfig
|
||||||
+++ b/drivers/pci/host/Kconfig
|
+++ b/drivers/pci/host/Kconfig
|
||||||
@@ -127,6 +127,15 @@ config PCIE_IPROC
|
@@ -146,6 +146,16 @@ config PCIE_IPROC_BCMA
|
||||||
iProc family of SoCs. An appropriate bus interface driver also needs
|
Say Y here if you want to use the Broadcom iProc PCIe controller
|
||||||
to be enabled
|
through the BCMA bus interface
|
||||||
|
|
||||||
+config PCIE_IPROC_MSI
|
+config PCIE_IPROC_MSI
|
||||||
+ bool "Broadcom iProc PCIe MSI support"
|
+ 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
|
+ select PCI_MSI_IRQ_DOMAIN
|
||||||
+ default ARCH_BCM_IPROC
|
+ default ARCH_BCM_IPROC
|
||||||
+ help
|
+ help
|
||||||
+ Say Y here if you want to enable MSI support for Broadcom's iProc
|
+ Say Y here if you want to enable MSI support for Broadcom's iProc
|
||||||
+ PCIe controller
|
+ PCIe controller
|
||||||
+
|
+
|
||||||
config PCIE_IPROC_PLATFORM
|
config PCIE_ALTERA
|
||||||
tristate "Broadcom iProc PCIe platform bus driver"
|
bool "Altera PCIe controller"
|
||||||
depends on ARCH_BCM_IPROC || (ARM && COMPILE_TEST)
|
depends on ARM || NIOS2
|
||||||
--- a/drivers/pci/host/Makefile
|
--- a/drivers/pci/host/Makefile
|
||||||
+++ b/drivers/pci/host/Makefile
|
+++ b/drivers/pci/host/Makefile
|
||||||
@@ -15,6 +15,7 @@ obj-$(CONFIG_PCI_XGENE_MSI) += pci-xgene
|
@@ -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
|
+#define IPROC_MSI_EQ_MASK 0x3f
|
||||||
+
|
+
|
||||||
+/* max number of GIC interrupts */
|
+/* Max number of GIC interrupts */
|
||||||
+#define NR_HW_IRQS 6
|
+#define NR_HW_IRQS 6
|
||||||
+
|
+
|
||||||
+/* number of entries in each event queue */
|
+/* Number of entries in each event queue */
|
||||||
+#define EQ_LEN 64
|
+#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
|
+#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
|
+#define MSI_MEM_REGION_SIZE SZ_4K
|
||||||
+
|
+
|
||||||
+enum iproc_msi_reg {
|
+enum iproc_msi_reg {
|
||||||
|
@ -153,7 +157,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
|
||||||
+ * iProc MSI group
|
+ * iProc MSI group
|
||||||
+ *
|
+ *
|
||||||
+ * One MSI group is allocated per GIC interrupt, serviced by one iProc MSI
|
+ * One MSI group is allocated per GIC interrupt, serviced by one iProc MSI
|
||||||
+ * event queue
|
+ * event queue.
|
||||||
+ *
|
+ *
|
||||||
+ * @msi: pointer to iProc MSI data
|
+ * @msi: pointer to iProc MSI data
|
||||||
+ * @gic_irq: GIC interrupt
|
+ * @gic_irq: GIC interrupt
|
||||||
|
@ -169,7 +173,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
|
||||||
+ * iProc event queue based MSI
|
+ * iProc event queue based MSI
|
||||||
+ *
|
+ *
|
||||||
+ * Only meant to be used on platforms without MSI support integrated into the
|
+ * Only meant to be used on platforms without MSI support integrated into the
|
||||||
+ * GIC
|
+ * GIC.
|
||||||
+ *
|
+ *
|
||||||
+ * @pcie: pointer to iProc PCIe data
|
+ * @pcie: pointer to iProc PCIe data
|
||||||
+ * @reg_offsets: MSI register offsets
|
+ * @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
|
+ * 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
|
+ * The number of MSI groups varies between different iProc SoCs. The total
|
||||||
+ * number of CPU cores also varies. To support MSI IRQ affinity, we
|
+ * number of CPU cores also varies. To support MSI IRQ affinity, we
|
||||||
+ * distribute GIC interrupts across all available CPUs. MSI vector is moved
|
+ * 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:
|
+ * Assuming:
|
||||||
+ * - the number of MSI groups is M
|
+ * - the number of MSI groups is M
|
||||||
|
@ -348,7 +352,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
|
||||||
+
|
+
|
||||||
+ mutex_lock(&msi->bitmap_lock);
|
+ 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,
|
+ hwirq = bitmap_find_next_zero_area(msi->bitmap, msi->nr_msi_vecs, 0,
|
||||||
+ msi->nr_cpus, 0);
|
+ msi->nr_cpus, 0);
|
||||||
+ if (hwirq < msi->nr_msi_vecs) {
|
+ if (hwirq < msi->nr_msi_vecs) {
|
||||||
|
@ -399,8 +403,8 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
|
||||||
+
|
+
|
||||||
+ /*
|
+ /*
|
||||||
+ * Since we have multiple hwirq mapped to a single MSI vector,
|
+ * 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
|
+ * 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);
|
+ return hwirq_to_canonical_hwirq(msi, hwirq);
|
||||||
+}
|
+}
|
||||||
|
@ -423,14 +427,14 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
|
||||||
+ eq = grp->eq;
|
+ eq = grp->eq;
|
||||||
+
|
+
|
||||||
+ /*
|
+ /*
|
||||||
+ * iProc MSI event queue is tracked by head and tail pointers. Head
|
+ * 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
|
+ * 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
|
+ * 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
|
+ * Entries between head and tail pointers contain valid MSI data. MSI
|
||||||
+ * data is guaranteed to be in the event queue memory before the tail
|
+ * 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,
|
+ head = iproc_msi_read_reg(msi, IPROC_MSI_EQ_HEAD,
|
||||||
+ eq) & IPROC_MSI_EQ_MASK;
|
+ 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
|
+ * Figure out total number of events (MSI data) to be
|
||||||
+ * processed
|
+ * processed.
|
||||||
+ */
|
+ */
|
||||||
+ nr_events = (tail < head) ?
|
+ nr_events = (tail < head) ?
|
||||||
+ (EQ_LEN - (head - tail)) : (tail - head);
|
+ (EQ_LEN - (head - tail)) : (tail - head);
|
||||||
|
@ -458,14 +462,14 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ /*
|
+ /*
|
||||||
+ * Now all outstanding events have been processed. Update the
|
+ * Now all outstanding events have been processed. Update the
|
||||||
+ * head pointer
|
+ * head pointer.
|
||||||
+ */
|
+ */
|
||||||
+ iproc_msi_write_reg(msi, IPROC_MSI_EQ_HEAD, eq, head);
|
+ iproc_msi_write_reg(msi, IPROC_MSI_EQ_HEAD, eq, head);
|
||||||
+
|
+
|
||||||
+ /*
|
+ /*
|
||||||
+ * Now go read the tail pointer again to see if there are new
|
+ * 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);
|
+ } while (true);
|
||||||
+
|
+
|
||||||
|
@ -477,7 +481,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
|
||||||
+ int i, eq;
|
+ int i, eq;
|
||||||
+ u32 val;
|
+ 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++) {
|
+ for (i = 0; i < msi->nr_eq_region; i++) {
|
||||||
+ dma_addr_t addr = msi->eq_dma + (i * EQ_MEM_REGION_SIZE);
|
+ 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));
|
+ 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++) {
|
+ for (i = 0; i < msi->nr_msi_region; i++) {
|
||||||
+ phys_addr_t addr = msi->msi_addr + (i * MSI_MEM_REGION_SIZE);
|
+ 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++) {
|
+ 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 |
|
+ val = IPROC_MSI_INTR_EN | IPROC_MSI_INT_N_EVENT |
|
||||||
+ IPROC_MSI_EQ_EN;
|
+ IPROC_MSI_EQ_EN;
|
||||||
+ iproc_msi_write_reg(msi, IPROC_MSI_CTRL, eq, val);
|
+ iproc_msi_write_reg(msi, IPROC_MSI_CTRL, eq, val);
|
||||||
+
|
+
|
||||||
+ /*
|
+ /*
|
||||||
+ * Some legacy platforms require the MSI interrupt enable
|
+ * Some legacy platforms require the MSI interrupt enable
|
||||||
+ * register to be set explicitly
|
+ * register to be set explicitly.
|
||||||
+ */
|
+ */
|
||||||
+ if (msi->has_inten_reg) {
|
+ if (msi->has_inten_reg) {
|
||||||
+ val = iproc_msi_read_reg(msi, IPROC_MSI_INTS_EN, eq);
|
+ 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,
|
+ irq_set_chained_handler_and_data(msi->grps[i].gic_irq,
|
||||||
+ iproc_msi_handler,
|
+ iproc_msi_handler,
|
||||||
+ &msi->grps[i]);
|
+ &msi->grps[i]);
|
||||||
+ /* dedicate GIC interrupt to each CPU core */
|
+ /* Dedicate GIC interrupt to each CPU core */
|
||||||
+ if (alloc_cpumask_var(&mask, GFP_KERNEL)) {
|
+ if (alloc_cpumask_var(&mask, GFP_KERNEL)) {
|
||||||
+ cpumask_clear(mask);
|
+ cpumask_clear(mask);
|
||||||
+ cpumask_set_cpu(cpu, mask);
|
+ cpumask_set_cpu(cpu, mask);
|
||||||
|
@ -597,7 +601,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ if (ret) {
|
+ if (ret) {
|
||||||
+ /* free all configured/unconfigured irqs */
|
+ /* Free all configured/unconfigured IRQs */
|
||||||
+ iproc_msi_irq_free(msi, cpu);
|
+ iproc_msi_irq_free(msi, cpu);
|
||||||
+ return ret;
|
+ return ret;
|
||||||
+ }
|
+ }
|
||||||
|
@ -698,7 +702,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
|
||||||
+ msi->grps[i].eq = i;
|
+ 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->eq_cpu = dma_zalloc_coherent(pcie->dev,
|
||||||
+ msi->nr_eq_region * EQ_MEM_REGION_SIZE,
|
+ msi->nr_eq_region * EQ_MEM_REGION_SIZE,
|
||||||
+ &msi->eq_dma, GFP_KERNEL);
|
+ &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_setup(struct iproc_pcie *pcie, struct list_head *res);
|
||||||
int iproc_pcie_remove(struct iproc_pcie *pcie);
|
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);
|
+int iproc_msi_init(struct iproc_pcie *pcie, struct device_node *node);
|
||||||
+void iproc_msi_exit(struct iproc_pcie *pcie);
|
+void iproc_msi_exit(struct iproc_pcie *pcie);
|
||||||
+#else
|
+#else
|
||||||
|
@ -879,7 +883,7 @@ Reviewed-by: Scott Branden <sbranden@broadcom.com>
|
||||||
+{
|
+{
|
||||||
+ return -ENODEV;
|
+ return -ENODEV;
|
||||||
+}
|
+}
|
||||||
+static void iproc_msi_exit(struct iproc_pcie *pcie)
|
+static inline void iproc_msi_exit(struct iproc_pcie *pcie)
|
||||||
+{
|
+{
|
||||||
+}
|
+}
|
||||||
+#endif
|
+#endif
|
Loading…
Reference in a new issue