summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2024-07-19 10:10:30 -0500
committerBjorn Helgaas <bhelgaas@google.com>2024-07-19 10:10:30 -0500
commit325b9a3e4e6bcaa04495ebc54e24203e00151bc0 (patch)
tree61dd3347d8af0f1c4f672fc34bcc464b01c4dc45
parent145eec91b38a56a619fb1edc867f09fecc8dc44f (diff)
parent39b91eb40c6aa3063a36d189a7c04a1467447425 (diff)
downloadlinux-325b9a3e4e6bcaa04495ebc54e24203e00151bc0.tar.gz
linux-325b9a3e4e6bcaa04495ebc54e24203e00151bc0.tar.bz2
linux-325b9a3e4e6bcaa04495ebc54e24203e00151bc0.zip
Merge branch 'pci/controller/microchip'
- Move PLDA XpressRICH generic DT binding properties to plda,xpressrich3-axi-common.yaml where they can be shared across PLDA-based drivers (Minda Chen) - Create a drivers/pci/controller/plda/ directory for PLDA-based drivers and move pcie-microchip-host.c there (Minda Chen) - Move PLDA generic macros to pcie-plda.h where they can be shared across drivers (Minda Chen) - Extract PLDA generic structures from pcie-microchip-host.c, rename them to be generic, and move them to pcie-plda-host.c where they can be shared across drivers (Minda Chen) - Add a .request_event_irq() callback for requesting device-specific interrupts in addition to PLDA-generic interrupts (Minda Chen) - Add DT binding and driver for the StarFive JH7110 SoC, based on PLDA IP (Minda Chen) * pci/controller/microchip: PCI: starfive: Add JH7110 PCIe controller dt-bindings: PCI: Add StarFive JH7110 PCIe controller PCI: Add PCIE_RESET_CONFIG_DEVICE_WAIT_MS waiting time value PCI: plda: Pass pci_host_bridge to plda_pcie_setup_iomems() PCI: plda: Add host init/deinit and map bus functions PCI: plda: Add event bitmap field to struct plda_pcie_rp PCI: microchip: Move IRQ functions to pcie-plda-host.c PCI: microchip: Add event irqchip field to host port and add PLDA irqchip PCI: microchip: Add get_events() callback and PLDA get_event() PCI: microchip: Add INTx and MSI event num to struct plda_event PCI: microchip: Add request_event_irq() callback function PCI: microchip: Add num_events field to struct plda_pcie_rp PCI: microchip: Rename interrupt related functions PCI: microchip: Move PLDA functions to pcie-plda-host.c PCI: microchip: Rename PLDA functions to be generic PCI: microchip: Move PLDA structures to plda-pcie.h PCI: microchip: Rename PLDA structures to be generic PCI: microchip: Add bridge_addr field to struct mc_pcie PCI: microchip: Move PLDA IP register macros to pcie-plda.h PCI: microchip: Move pcie-microchip-host.c to PLDA directory dt-bindings: PCI: Add PLDA XpressRICH PCIe host common properties # Conflicts: # drivers/pci/pci.h
-rw-r--r--Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml55
-rw-r--r--Documentation/devicetree/bindings/pci/plda,xpressrich3-axi-common.yaml75
-rw-r--r--Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml120
-rw-r--r--MAINTAINERS19
-rw-r--r--drivers/pci/controller/Kconfig9
-rw-r--r--drivers/pci/controller/Makefile2
-rw-r--r--drivers/pci/controller/plda/Kconfig30
-rw-r--r--drivers/pci/controller/plda/Makefile4
-rw-r--r--drivers/pci/controller/plda/pcie-microchip-host.c (renamed from drivers/pci/controller/pcie-microchip-host.c)615
-rw-r--r--drivers/pci/controller/plda/pcie-plda-host.c651
-rw-r--r--drivers/pci/controller/plda/pcie-plda.h273
-rw-r--r--drivers/pci/controller/plda/pcie-starfive.c488
-rw-r--r--drivers/pci/pci.h15
13 files changed, 1740 insertions, 616 deletions
diff --git a/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml b/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml
index 5d7aec5f54e7..612633ba59e2 100644
--- a/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml
+++ b/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml
@@ -10,21 +10,13 @@ maintainers:
- Daire McNamara <daire.mcnamara@microchip.com>
allOf:
- - $ref: /schemas/pci/pci-host-bridge.yaml#
+ - $ref: plda,xpressrich3-axi-common.yaml#
- $ref: /schemas/interrupt-controller/msi-controller.yaml#
properties:
compatible:
const: microchip,pcie-host-1.0 # PolarFire
- reg:
- maxItems: 2
-
- reg-names:
- items:
- - const: cfg
- - const: apb
-
clocks:
description:
Fabric Interface Controllers, FICs, are the interface between the FPGA
@@ -52,18 +44,6 @@ properties:
items:
pattern: '^fic[0-3]$'
- interrupts:
- minItems: 1
- items:
- - description: PCIe host controller
- - description: builtin MSI controller
-
- interrupt-names:
- minItems: 1
- items:
- - const: pcie
- - const: msi
-
ranges:
minItems: 1
maxItems: 3
@@ -72,39 +52,6 @@ properties:
minItems: 1
maxItems: 6
- msi-controller:
- description: Identifies the node as an MSI controller.
-
- msi-parent:
- description: MSI controller the device is capable of using.
-
- interrupt-controller:
- type: object
- properties:
- '#address-cells':
- const: 0
-
- '#interrupt-cells':
- const: 1
-
- interrupt-controller: true
-
- required:
- - '#address-cells'
- - '#interrupt-cells'
- - interrupt-controller
-
- additionalProperties: false
-
-required:
- - reg
- - reg-names
- - "#interrupt-cells"
- - interrupts
- - interrupt-map-mask
- - interrupt-map
- - msi-controller
-
unevaluatedProperties: false
examples:
diff --git a/Documentation/devicetree/bindings/pci/plda,xpressrich3-axi-common.yaml b/Documentation/devicetree/bindings/pci/plda,xpressrich3-axi-common.yaml
new file mode 100644
index 000000000000..7a57a80052a0
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/plda,xpressrich3-axi-common.yaml
@@ -0,0 +1,75 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/plda,xpressrich3-axi-common.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: PLDA XpressRICH PCIe host common properties
+
+maintainers:
+ - Daire McNamara <daire.mcnamara@microchip.com>
+ - Kevin Xie <kevin.xie@starfivetech.com>
+
+description:
+ Generic PLDA XpressRICH PCIe host common properties.
+
+allOf:
+ - $ref: /schemas/pci/pci-host-bridge.yaml#
+
+properties:
+ reg:
+ maxItems: 2
+
+ reg-names:
+ items:
+ - const: cfg
+ - const: apb
+
+ interrupts:
+ minItems: 1
+ items:
+ - description: PCIe host controller
+ - description: builtin MSI controller
+
+ interrupt-names:
+ minItems: 1
+ items:
+ - const: pcie
+ - const: msi
+
+ msi-controller:
+ description: Identifies the node as an MSI controller.
+
+ msi-parent:
+ description: MSI controller the device is capable of using.
+
+ interrupt-controller:
+ type: object
+ properties:
+ '#address-cells':
+ const: 0
+
+ '#interrupt-cells':
+ const: 1
+
+ interrupt-controller: true
+
+ required:
+ - '#address-cells'
+ - '#interrupt-cells'
+ - interrupt-controller
+
+ additionalProperties: false
+
+required:
+ - reg
+ - reg-names
+ - interrupts
+ - msi-controller
+ - "#interrupt-cells"
+ - interrupt-map-mask
+ - interrupt-map
+
+additionalProperties: true
+
+...
diff --git a/Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml b/Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml
new file mode 100644
index 000000000000..67151aaa3948
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml
@@ -0,0 +1,120 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/starfive,jh7110-pcie.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: StarFive JH7110 PCIe host controller
+
+maintainers:
+ - Kevin Xie <kevin.xie@starfivetech.com>
+
+allOf:
+ - $ref: plda,xpressrich3-axi-common.yaml#
+
+properties:
+ compatible:
+ const: starfive,jh7110-pcie
+
+ clocks:
+ items:
+ - description: NOC bus clock
+ - description: Transport layer clock
+ - description: AXI MST0 clock
+ - description: APB clock
+
+ clock-names:
+ items:
+ - const: noc
+ - const: tl
+ - const: axi_mst0
+ - const: apb
+
+ resets:
+ items:
+ - description: AXI MST0 reset
+ - description: AXI SLAVE0 reset
+ - description: AXI SLAVE reset
+ - description: PCIE BRIDGE reset
+ - description: PCIE CORE reset
+ - description: PCIE APB reset
+
+ reset-names:
+ items:
+ - const: mst0
+ - const: slv0
+ - const: slv
+ - const: brg
+ - const: core
+ - const: apb
+
+ starfive,stg-syscon:
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+ description:
+ The phandle to System Register Controller syscon node.
+
+ perst-gpios:
+ description: GPIO controlled connection to PERST# signal
+ maxItems: 1
+
+ phys:
+ description:
+ Specified PHY is attached to PCIe controller.
+ maxItems: 1
+
+required:
+ - clocks
+ - resets
+ - starfive,stg-syscon
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ pcie@940000000 {
+ compatible = "starfive,jh7110-pcie";
+ reg = <0x9 0x40000000 0x0 0x10000000>,
+ <0x0 0x2b000000 0x0 0x1000000>;
+ reg-names = "cfg", "apb";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ device_type = "pci";
+ ranges = <0x82000000 0x0 0x30000000 0x0 0x30000000 0x0 0x08000000>,
+ <0xc3000000 0x9 0x00000000 0x9 0x00000000 0x0 0x40000000>;
+ starfive,stg-syscon = <&stg_syscon>;
+ bus-range = <0x0 0xff>;
+ interrupt-parent = <&plic>;
+ interrupts = <56>;
+ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+ interrupt-map = <0x0 0x0 0x0 0x1 &pcie_intc0 0x1>,
+ <0x0 0x0 0x0 0x2 &pcie_intc0 0x2>,
+ <0x0 0x0 0x0 0x3 &pcie_intc0 0x3>,
+ <0x0 0x0 0x0 0x4 &pcie_intc0 0x4>;
+ msi-controller;
+ clocks = <&syscrg 86>,
+ <&stgcrg 10>,
+ <&stgcrg 8>,
+ <&stgcrg 9>;
+ clock-names = "noc", "tl", "axi_mst0", "apb";
+ resets = <&stgcrg 11>,
+ <&stgcrg 12>,
+ <&stgcrg 13>,
+ <&stgcrg 14>,
+ <&stgcrg 15>,
+ <&stgcrg 16>;
+ perst-gpios = <&gpios 26 GPIO_ACTIVE_LOW>;
+ phys = <&pciephy0>;
+
+ pcie_intc0: interrupt-controller {
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ };
+ };
+ };
diff --git a/MAINTAINERS b/MAINTAINERS
index d6c90161c7bf..823387766a0c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17219,6 +17219,14 @@ S: Maintained
F: Documentation/devicetree/bindings/pci/layerscape-pcie-gen4.txt
F: drivers/pci/controller/mobiveil/pcie-layerscape-gen4.c
+PCI DRIVER FOR PLDA PCIE IP
+M: Daire McNamara <daire.mcnamara@microchip.com>
+L: linux-pci@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/pci/plda,xpressrich3-axi-common.yaml
+F: drivers/pci/controller/plda/pcie-plda-host.c
+F: drivers/pci/controller/plda/pcie-plda.h
+
PCI DRIVER FOR RENESAS R-CAR
M: Marek Vasut <marek.vasut+renesas@gmail.com>
M: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
@@ -17449,7 +17457,7 @@ M: Daire McNamara <daire.mcnamara@microchip.com>
L: linux-pci@vger.kernel.org
S: Supported
F: Documentation/devicetree/bindings/pci/microchip*
-F: drivers/pci/controller/*microchip*
+F: drivers/pci/controller/plda/*microchip*
PCIE DRIVER FOR QUALCOMM MSM
M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
@@ -17479,6 +17487,13 @@ L: linux-pci@vger.kernel.org
S: Maintained
F: drivers/pci/controller/dwc/*spear*
+PCIE DRIVER FOR STARFIVE JH71x0
+M: Kevin Xie <kevin.xie@starfivetech.com>
+L: linux-pci@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml
+F: drivers/pci/controller/plda/pcie-starfive.c
+
PCIE ENDPOINT DRIVER FOR QUALCOMM
M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
L: linux-pci@vger.kernel.org
@@ -19285,7 +19300,7 @@ F: drivers/clk/microchip/clk-mpfs*.c
F: drivers/firmware/microchip/mpfs-auto-update.c
F: drivers/i2c/busses/i2c-microchip-corei2c.c
F: drivers/mailbox/mailbox-mpfs.c
-F: drivers/pci/controller/pcie-microchip-host.c
+F: drivers/pci/controller/plda/pcie-microchip-host.c
F: drivers/pwm/pwm-microchip-core.c
F: drivers/reset/reset-mpfs.c
F: drivers/rtc/rtc-mpfs.c
diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index e534c02ee34f..4d2c188f5835 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -215,14 +215,6 @@ config PCIE_MT7621
help
This selects a driver for the MediaTek MT7621 PCIe Controller.
-config PCIE_MICROCHIP_HOST
- tristate "Microchip AXI PCIe controller"
- depends on PCI_MSI && OF
- select PCI_HOST_COMMON
- help
- Say Y here if you want kernel to support the Microchip AXI PCIe
- Host Bridge driver.
-
config PCI_HYPERV_INTERFACE
tristate "Microsoft Hyper-V PCI Interface"
depends on ((X86 && X86_64) || ARM64) && HYPERV && PCI_MSI
@@ -356,4 +348,5 @@ config PCIE_XILINX_CPM
source "drivers/pci/controller/cadence/Kconfig"
source "drivers/pci/controller/dwc/Kconfig"
source "drivers/pci/controller/mobiveil/Kconfig"
+source "drivers/pci/controller/plda/Kconfig"
endmenu
diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
index f2b19e6174af..038ccbd9e3ba 100644
--- a/drivers/pci/controller/Makefile
+++ b/drivers/pci/controller/Makefile
@@ -33,7 +33,6 @@ obj-$(CONFIG_PCIE_ROCKCHIP_EP) += pcie-rockchip-ep.o
obj-$(CONFIG_PCIE_ROCKCHIP_HOST) += pcie-rockchip-host.o
obj-$(CONFIG_PCIE_MEDIATEK) += pcie-mediatek.o
obj-$(CONFIG_PCIE_MEDIATEK_GEN3) += pcie-mediatek-gen3.o
-obj-$(CONFIG_PCIE_MICROCHIP_HOST) += pcie-microchip-host.o
obj-$(CONFIG_VMD) += vmd.o
obj-$(CONFIG_PCIE_BRCMSTB) += pcie-brcmstb.o
obj-$(CONFIG_PCI_LOONGSON) += pci-loongson.o
@@ -44,6 +43,7 @@ obj-$(CONFIG_PCIE_MT7621) += pcie-mt7621.o
# pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW
obj-y += dwc/
obj-y += mobiveil/
+obj-y += plda/
# The following drivers are for devices that use the generic ACPI
diff --git a/drivers/pci/controller/plda/Kconfig b/drivers/pci/controller/plda/Kconfig
new file mode 100644
index 000000000000..c0e14146d7e4
--- /dev/null
+++ b/drivers/pci/controller/plda/Kconfig
@@ -0,0 +1,30 @@
+# SPDX-License-Identifier: GPL-2.0
+
+menu "PLDA-based PCIe controllers"
+ depends on PCI
+
+config PCIE_PLDA_HOST
+ bool
+
+config PCIE_MICROCHIP_HOST
+ tristate "Microchip AXI PCIe controller"
+ depends on PCI_MSI && OF
+ select PCI_HOST_COMMON
+ select PCIE_PLDA_HOST
+ help
+ Say Y here if you want kernel to support the Microchip AXI PCIe
+ Host Bridge driver.
+
+config PCIE_STARFIVE_HOST
+ tristate "StarFive PCIe host controller"
+ depends on PCI_MSI && OF
+ depends on ARCH_STARFIVE || COMPILE_TEST
+ select PCIE_PLDA_HOST
+ help
+ Say Y here if you want to support the StarFive PCIe controller in
+ host mode. StarFive PCIe controller uses PLDA PCIe core.
+
+ If you choose to build this driver as module it will be dynamically
+ linked and module will be called pcie-starfive.ko.
+
+endmenu
diff --git a/drivers/pci/controller/plda/Makefile b/drivers/pci/controller/plda/Makefile
new file mode 100644
index 000000000000..0ac6851bed48
--- /dev/null
+++ b/drivers/pci/controller/plda/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_PCIE_PLDA_HOST) += pcie-plda-host.o
+obj-$(CONFIG_PCIE_MICROCHIP_HOST) += pcie-microchip-host.o
+obj-$(CONFIG_PCIE_STARFIVE_HOST) += pcie-starfive.o
diff --git a/drivers/pci/controller/pcie-microchip-host.c b/drivers/pci/controller/plda/pcie-microchip-host.c
index 137fb8570ba2..48f60a04b740 100644
--- a/drivers/pci/controller/pcie-microchip-host.c
+++ b/drivers/pci/controller/plda/pcie-microchip-host.c
@@ -18,10 +18,8 @@
#include <linux/pci-ecam.h>
#include <linux/platform_device.h>
-#include "../pci.h"
-
-/* Number of MSI IRQs */
-#define MC_MAX_NUM_MSI_IRQS 32
+#include "../../pci.h"
+#include "pcie-plda.h"
/* PCIe Bridge Phy and Controller Phy offsets */
#define MC_PCIE1_BRIDGE_ADDR 0x00008000u
@@ -30,84 +28,6 @@
#define MC_PCIE_BRIDGE_ADDR (MC_PCIE1_BRIDGE_ADDR)
#define MC_PCIE_CTRL_ADDR (MC_PCIE1_CTRL_ADDR)
-/* PCIe Bridge Phy Regs */
-#define PCIE_PCI_IRQ_DW0 0xa8
-#define MSIX_CAP_MASK BIT(31)
-#define NUM_MSI_MSGS_MASK GENMASK(6, 4)
-#define NUM_MSI_MSGS_SHIFT 4
-
-#define IMASK_LOCAL 0x180
-#define DMA_END_ENGINE_0_MASK 0x00000000u
-#define DMA_END_ENGINE_0_SHIFT 0
-#define DMA_END_ENGINE_1_MASK 0x00000000u
-#define DMA_END_ENGINE_1_SHIFT 1
-#define DMA_ERROR_ENGINE_0_MASK 0x00000100u
-#define DMA_ERROR_ENGINE_0_SHIFT 8
-#define DMA_ERROR_ENGINE_1_MASK 0x00000200u
-#define DMA_ERROR_ENGINE_1_SHIFT 9
-#define A_ATR_EVT_POST_ERR_MASK 0x00010000u
-#define A_ATR_EVT_POST_ERR_SHIFT 16
-#define A_ATR_EVT_FETCH_ERR_MASK 0x00020000u
-#define A_ATR_EVT_FETCH_ERR_SHIFT 17
-#define A_ATR_EVT_DISCARD_ERR_MASK 0x00040000u
-#define A_ATR_EVT_DISCARD_ERR_SHIFT 18
-#define A_ATR_EVT_DOORBELL_MASK 0x00000000u
-#define A_ATR_EVT_DOORBELL_SHIFT 19
-#define P_ATR_EVT_POST_ERR_MASK 0x00100000u
-#define P_ATR_EVT_POST_ERR_SHIFT 20
-#define P_ATR_EVT_FETCH_ERR_MASK 0x00200000u
-#define P_ATR_EVT_FETCH_ERR_SHIFT 21
-#define P_ATR_EVT_DISCARD_ERR_MASK 0x00400000u
-#define P_ATR_EVT_DISCARD_ERR_SHIFT 22
-#define P_ATR_EVT_DOORBELL_MASK 0x00000000u
-#define P_ATR_EVT_DOORBELL_SHIFT 23
-#define PM_MSI_INT_INTA_MASK 0x01000000u
-#define PM_MSI_INT_INTA_SHIFT 24
-#define PM_MSI_INT_INTB_MASK 0x02000000u
-#define PM_MSI_INT_INTB_SHIFT 25
-#define PM_MSI_INT_INTC_MASK 0x04000000u
-#define PM_MSI_INT_INTC_SHIFT 26
-#define PM_MSI_INT_INTD_MASK 0x08000000u
-#define PM_MSI_INT_INTD_SHIFT 27
-#define PM_MSI_INT_INTX_MASK 0x0f000000u
-#define PM_MSI_INT_INTX_SHIFT 24
-#define PM_MSI_INT_MSI_MASK 0x10000000u
-#define PM_MSI_INT_MSI_SHIFT 28
-#define PM_MSI_INT_AER_EVT_MASK 0x20000000u
-#define PM_MSI_INT_AER_EVT_SHIFT 29
-#define PM_MSI_INT_EVENTS_MASK 0x40000000u
-#define PM_MSI_INT_EVENTS_SHIFT 30
-#define PM_MSI_INT_SYS_ERR_MASK 0x80000000u
-#define PM_MSI_INT_SYS_ERR_SHIFT 31
-#define NUM_LOCAL_EVENTS 15
-#define ISTATUS_LOCAL 0x184
-#define IMASK_HOST 0x188
-#define ISTATUS_HOST 0x18c
-#define IMSI_ADDR 0x190
-#define ISTATUS_MSI 0x194
-
-/* PCIe Master table init defines */
-#define ATR0_PCIE_WIN0_SRCADDR_PARAM 0x600u
-#define ATR0_PCIE_ATR_SIZE 0x25
-#define ATR0_PCIE_ATR_SIZE_SHIFT 1
-#define ATR0_PCIE_WIN0_SRC_ADDR 0x604u
-#define ATR0_PCIE_WIN0_TRSL_ADDR_LSB 0x608u
-#define ATR0_PCIE_WIN0_TRSL_ADDR_UDW 0x60cu
-#define ATR0_PCIE_WIN0_TRSL_PARAM 0x610u
-
-/* PCIe AXI slave table init defines */
-#define ATR0_AXI4_SLV0_SRCADDR_PARAM 0x800u
-#define ATR_SIZE_SHIFT 1
-#define ATR_IMPL_ENABLE 1
-#define ATR0_AXI4_SLV0_SRC_ADDR 0x804u
-#define ATR0_AXI4_SLV0_TRSL_ADDR_LSB 0x808u
-#define ATR0_AXI4_SLV0_TRSL_ADDR_UDW 0x80cu
-#define ATR0_AXI4_SLV0_TRSL_PARAM 0x810u
-#define PCIE_TX_RX_INTERFACE 0x00000000u
-#define PCIE_CONFIG_INTERFACE 0x00000001u
-
-#define ATR_ENTRY_SIZE 32
-
/* PCIe Controller Phy Regs */
#define SEC_ERROR_EVENT_CNT 0x20
#define DED_ERROR_EVENT_CNT 0x24
@@ -179,20 +99,21 @@
#define EVENT_LOCAL_DMA_END_ENGINE_1 12
#define EVENT_LOCAL_DMA_ERROR_ENGINE_0 13
#define EVENT_LOCAL_DMA_ERROR_ENGINE_1 14
-#define EVENT_LOCAL_A_ATR_EVT_POST_ERR 15
-#define EVENT_LOCAL_A_ATR_EVT_FETCH_ERR 16
-#define EVENT_LOCAL_A_ATR_EVT_DISCARD_ERR 17
-#define EVENT_LOCAL_A_ATR_EVT_DOORBELL 18
-#define EVENT_LOCAL_P_ATR_EVT_POST_ERR 19
-#define EVENT_LOCAL_P_ATR_EVT_FETCH_ERR 20
-#define EVENT_LOCAL_P_ATR_EVT_DISCARD_ERR 21
-#define EVENT_LOCAL_P_ATR_EVT_DOORBELL 22
-#define EVENT_LOCAL_PM_MSI_INT_INTX 23
-#define EVENT_LOCAL_PM_MSI_INT_MSI 24
-#define EVENT_LOCAL_PM_MSI_INT_AER_EVT 25
-#define EVENT_LOCAL_PM_MSI_INT_EVENTS 26
-#define EVENT_LOCAL_PM_MSI_INT_SYS_ERR 27
-#define NUM_EVENTS 28
+#define NUM_MC_EVENTS 15
+#define EVENT_LOCAL_A_ATR_EVT_POST_ERR (NUM_MC_EVENTS + PLDA_AXI_POST_ERR)
+#define EVENT_LOCAL_A_ATR_EVT_FETCH_ERR (NUM_MC_EVENTS + PLDA_AXI_FETCH_ERR)
+#define EVENT_LOCAL_A_ATR_EVT_DISCARD_ERR (NUM_MC_EVENTS + PLDA_AXI_DISCARD_ERR)
+#define EVENT_LOCAL_A_ATR_EVT_DOORBELL (NUM_MC_EVENTS + PLDA_AXI_DOORBELL)
+#define EVENT_LOCAL_P_ATR_EVT_POST_ERR (NUM_MC_EVENTS + PLDA_PCIE_POST_ERR)
+#define EVENT_LOCAL_P_ATR_EVT_FETCH_ERR (NUM_MC_EVENTS + PLDA_PCIE_FETCH_ERR)
+#define EVENT_LOCAL_P_ATR_EVT_DISCARD_ERR (NUM_MC_EVENTS + PLDA_PCIE_DISCARD_ERR)
+#define EVENT_LOCAL_P_ATR_EVT_DOORBELL (NUM_MC_EVENTS + PLDA_PCIE_DOORBELL)
+#define EVENT_LOCAL_PM_MSI_INT_INTX (NUM_MC_EVENTS + PLDA_INTX)
+#define EVENT_LOCAL_PM_MSI_INT_MSI (NUM_MC_EVENTS + PLDA_MSI)
+#define EVENT_LOCAL_PM_MSI_INT_AER_EVT (NUM_MC_EVENTS + PLDA_AER_EVENT)
+#define EVENT_LOCAL_PM_MSI_INT_EVENTS (NUM_MC_EVENTS + PLDA_MISC_EVENTS)
+#define EVENT_LOCAL_PM_MSI_INT_SYS_ERR (NUM_MC_EVENTS + PLDA_SYS_ERR)
+#define NUM_EVENTS (NUM_MC_EVENTS + PLDA_INT_EVENT_NUM)
#define PCIE_EVENT_CAUSE(x, s) \
[EVENT_PCIE_ ## x] = { __stringify(x), s }
@@ -255,22 +176,10 @@ struct event_map {
u32 event_bit;
};
-struct mc_msi {
- struct mutex lock; /* Protect used bitmap */
- struct irq_domain *msi_domain;
- struct irq_domain *dev_domain;
- u32 num_vectors;
- u64 vector_phy;
- DECLARE_BITMAP(used, MC_MAX_NUM_MSI_IRQS);
-};
struct mc_pcie {
+ struct plda_pcie_rp plda;
void __iomem *axi_base_addr;
- struct device *dev;
- struct irq_domain *intx_domain;
- struct irq_domain *event_domain;
- raw_spinlock_t lock;
- struct mc_msi msi;
};
struct cause {
@@ -388,7 +297,7 @@ static struct mc_pcie *port;
static void mc_pcie_enable_msi(struct mc_pcie *port, void __iomem *ecam)
{
- struct mc_msi *msi = &port->msi;
+ struct plda_msi *msi = &port->plda.msi;
u16 reg;
u8 queue_size;
@@ -409,246 +318,6 @@ static void mc_pcie_enable_msi(struct mc_pcie *port, void __iomem *ecam)
ecam + MC_MSI_CAP_CTRL_OFFSET + PCI_MSI_ADDRESS_HI);
}
-static void mc_handle_msi(struct irq_desc *desc)
-{
- struct mc_pcie *port = irq_desc_get_handler_data(desc);
- struct irq_chip *chip = irq_desc_get_chip(desc);
- struct device *dev = port->dev;
- struct mc_msi *msi = &port->msi;
- void __iomem *bridge_base_addr =
- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
- unsigned long status;
- u32 bit;
- int ret;
-
- chained_irq_enter(chip, desc);
-
- status = readl_relaxed(bridge_base_addr + ISTATUS_LOCAL);
- if (status & PM_MSI_INT_MSI_MASK) {
- writel_relaxed(status & PM_MSI_INT_MSI_MASK, bridge_base_addr + ISTATUS_LOCAL);
- status = readl_relaxed(bridge_base_addr + ISTATUS_MSI);
- for_each_set_bit(bit, &status, msi->num_vectors) {
- ret = generic_handle_domain_irq(msi->dev_domain, bit);
- if (ret)
- dev_err_ratelimited(dev, "bad MSI IRQ %d\n",
- bit);
- }
- }
-
- chained_irq_exit(chip, desc);
-}
-
-static void mc_msi_bottom_irq_ack(struct irq_data *data)
-{
- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
- void __iomem *bridge_base_addr =
- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
- u32 bitpos = data->hwirq;
-
- writel_relaxed(BIT(bitpos), bridge_base_addr + ISTATUS_MSI);
-}
-
-static void mc_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
-{
- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
- phys_addr_t addr = port->msi.vector_phy;
-
- msg->address_lo = lower_32_bits(addr);
- msg->address_hi = upper_32_bits(addr);
- msg->data = data->hwirq;
-
- dev_dbg(port->dev, "msi#%x address_hi %#x address_lo %#x\n",
- (int)data->hwirq, msg->address_hi, msg->address_lo);
-}
-
-static int mc_msi_set_affinity(struct irq_data *irq_data,
- const struct cpumask *mask, bool force)
-{
- return -EINVAL;
-}
-
-static struct irq_chip mc_msi_bottom_irq_chip = {
- .name = "Microchip MSI",
- .irq_ack = mc_msi_bottom_irq_ack,
- .irq_compose_msi_msg = mc_compose_msi_msg,
- .irq_set_affinity = mc_msi_set_affinity,
-};
-
-static int mc_irq_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
- unsigned int nr_irqs, void *args)
-{
- struct mc_pcie *port = domain->host_data;
- struct mc_msi *msi = &port->msi;
- unsigned long bit;
-
- mutex_lock(&msi->lock);
- bit = find_first_zero_bit(msi->used, msi->num_vectors);
- if (bit >= msi->num_vectors) {
- mutex_unlock(&msi->lock);
- return -ENOSPC;
- }
-
- set_bit(bit, msi->used);
-
- irq_domain_set_info(domain, virq, bit, &mc_msi_bottom_irq_chip,
- domain->host_data, handle_edge_irq, NULL, NULL);
-
- mutex_unlock(&msi->lock);
-
- return 0;
-}
-
-static void mc_irq_msi_domain_free(struct irq_domain *domain, unsigned int virq,
- unsigned int nr_irqs)
-{
- struct irq_data *d = irq_domain_get_irq_data(domain, virq);
- struct mc_pcie *port = irq_data_get_irq_chip_data(d);
- struct mc_msi *msi = &port->msi;
-
- mutex_lock(&msi->lock);
-
- if (test_bit(d->hwirq, msi->used))
- __clear_bit(d->hwirq, msi->used);
- else
- dev_err(port->dev, "trying to free unused MSI%lu\n", d->hwirq);
-
- mutex_unlock(&msi->lock);
-}
-
-static const struct irq_domain_ops msi_domain_ops = {
- .alloc = mc_irq_msi_domain_alloc,
- .free = mc_irq_msi_domain_free,
-};
-
-static struct irq_chip mc_msi_irq_chip = {
- .name = "Microchip PCIe MSI",
- .irq_ack = irq_chip_ack_parent,
- .irq_mask = pci_msi_mask_irq,
- .irq_unmask = pci_msi_unmask_irq,
-};
-
-static struct msi_domain_info mc_msi_domain_info = {
- .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
- MSI_FLAG_PCI_MSIX),
- .chip = &mc_msi_irq_chip,
-};
-
-static int mc_allocate_msi_domains(struct mc_pcie *port)
-{
- struct device *dev = port->dev;
- struct fwnode_handle *fwnode = of_node_to_fwnode(dev->of_node);
- struct mc_msi *msi = &port->msi;
-
- mutex_init(&port->msi.lock);
-
- msi->dev_domain = irq_domain_add_linear(NULL, msi->num_vectors,
- &msi_domain_ops, port);
- if (!msi->dev_domain) {
- dev_err(dev, "failed to create IRQ domain\n");
- return -ENOMEM;
- }
-
- msi->msi_domain = pci_msi_create_irq_domain(fwnode, &mc_msi_domain_info,
- msi->dev_domain);
- if (!msi->msi_domain) {
- dev_err(dev, "failed to create MSI domain\n");
- irq_domain_remove(msi->dev_domain);
- return -ENOMEM;
- }
-
- return 0;
-}
-
-static void mc_handle_intx(struct irq_desc *desc)
-{
- struct mc_pcie *port = irq_desc_get_handler_data(desc);
- struct irq_chip *chip = irq_desc_get_chip(desc);
- struct device *dev = port->dev;
- void __iomem *bridge_base_addr =
- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
- unsigned long status;
- u32 bit;
- int ret;
-
- chained_irq_enter(chip, desc);
-
- status = readl_relaxed(bridge_base_addr + ISTATUS_LOCAL);
- if (status & PM_MSI_INT_INTX_MASK) {
- status &= PM_MSI_INT_INTX_MASK;
- status >>= PM_MSI_INT_INTX_SHIFT;
- for_each_set_bit(bit, &status, PCI_NUM_INTX) {
- ret = generic_handle_domain_irq(port->intx_domain, bit);
- if (ret)
- dev_err_ratelimited(dev, "bad INTx IRQ %d\n",
- bit);
- }
- }
-
- chained_irq_exit(chip, desc);
-}
-
-static void mc_ack_intx_irq(struct irq_data *data)
-{
- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
- void __iomem *bridge_base_addr =
- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
- u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
-
- writel_relaxed(mask, bridge_base_addr + ISTATUS_LOCAL);
-}
-
-static void mc_mask_intx_irq(struct irq_data *data)
-{
- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
- void __iomem *bridge_base_addr =
- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
- unsigned long flags;
- u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
- u32 val;
-
- raw_spin_lock_irqsave(&port->lock, flags);
- val = readl_relaxed(bridge_base_addr + IMASK_LOCAL);
- val &= ~mask;
- writel_relaxed(val, bridge_base_addr + IMASK_LOCAL);
- raw_spin_unlock_irqrestore(&port->lock, flags);
-}
-
-static void mc_unmask_intx_irq(struct irq_data *data)
-{
- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
- void __iomem *bridge_base_addr =
- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
- unsigned long flags;
- u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
- u32 val;
-
- raw_spin_lock_irqsave(&port->lock, flags);
- val = readl_relaxed(bridge_base_addr + IMASK_LOCAL);
- val |= mask;
- writel_relaxed(val, bridge_base_addr + IMASK_LOCAL);
- raw_spin_unlock_irqrestore(&port->lock, flags);
-}
-
-static struct irq_chip mc_intx_irq_chip = {
- .name = "Microchip PCIe INTx",
- .irq_ack = mc_ack_intx_irq,
- .irq_mask = mc_mask_intx_irq,
- .irq_unmask = mc_unmask_intx_irq,
-};
-
-static int mc_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
- irq_hw_number_t hwirq)
-{
- irq_set_chip_and_handler(irq, &mc_intx_irq_chip, handle_level_irq);
- irq_set_chip_data(irq, domain->host_data);
-
- return 0;
-}
-
-static const struct irq_domain_ops intx_domain_ops = {
- .map = mc_pcie_intx_map,
-};
-
static inline u32 reg_to_event(u32 reg, struct event_map field)
{
return (reg & field.reg_mask) ? BIT(field.event_bit) : 0;
@@ -706,21 +375,22 @@ static u32 local_events(struct mc_pcie *port)
return val;
}
-static u32 get_events(struct mc_pcie *port)
+static u32 mc_get_events(struct plda_pcie_rp *port)
{
+ struct mc_pcie *mc_port = container_of(port, struct mc_pcie, plda);
u32 events = 0;
- events |= pcie_events(port);
- events |= sec_errors(port);
- events |= ded_errors(port);
- events |= local_events(port);
+ events |= pcie_events(mc_port);
+ events |= sec_errors(mc_port);
+ events |= ded_errors(mc_port);
+ events |= local_events(mc_port);
return events;
}
static irqreturn_t mc_event_handler(int irq, void *dev_id)
{
- struct mc_pcie *port = dev_id;
+ struct plda_pcie_rp *port = dev_id;
struct device *dev = port->dev;
struct irq_data *data;
@@ -734,31 +404,15 @@ static irqreturn_t mc_event_handler(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static void mc_handle_event(struct irq_desc *desc)
-{
- struct mc_pcie *port = irq_desc_get_handler_data(desc);
- unsigned long events;
- u32 bit;
- struct irq_chip *chip = irq_desc_get_chip(desc);
-
- chained_irq_enter(chip, desc);
-
- events = get_events(port);
-
- for_each_set_bit(bit, &events, NUM_EVENTS)
- generic_handle_domain_irq(port->event_domain, bit);
-
- chained_irq_exit(chip, desc);
-}
-
static void mc_ack_event_irq(struct irq_data *data)
{
- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
+ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
+ struct mc_pcie *mc_port = container_of(port, struct mc_pcie, plda);
u32 event = data->hwirq;
void __iomem *addr;
u32 mask;
- addr = port->axi_base_addr + event_descs[event].base +
+ addr = mc_port->axi_base_addr + event_descs[event].base +
event_descs[event].offset;
mask = event_descs[event].mask;
mask |= event_descs[event].enb_mask;
@@ -768,13 +422,14 @@ static void mc_ack_event_irq(struct irq_data *data)