Refactoring Microchip PCIe driver and add StarFive PCIe
Subsystems (9)
v16 cover Refactoring Microchip PCIe driver and add StarFive PCIe
This patchset final purpose is add PCIe driver for StarFive JH7110 SoC. JH7110 using PLDA XpressRICH PCIe IP. Microchip PolarFire Using the same IP and have commit their codes, which are mixed with PLDA controller codes and Microchip platform codes.
For re-use the PLDA controller codes, I request refactoring microchip codes, move PLDA common codes to PLDA files.
Desigware and Cadence is good example for refactoring codes.
----------------------------------------------------------
The refactoring patches total number is 16,(patch 1-16) which do NOT contain changing logic of codes.
These patches just contain three type basic operations.
(rename, modify codes to support starfive platform, and moving to common file) If these patched are all be reviewed. They can be accepted first.
Refactoring patches can be devided to different groups
1. (patch 1- 3 is the prepare work of refactoring)
patch1 is move PLDA XpressRICH PCIe host common properties dt-binding
docs from microchip,pcie-host.yaml
patch2 is move PolarFire codes to PLDA directory.
patch3 is move PLDA IP register macros to plda-pcie.h
2. (patch4 - 6 is processing and re-use PCIe host instance) patch4 is add bridge_addr field to PCIe host instance. patch5 is rename data structure in microchip codes. patch6 is moving two data structures to head file
3. (patch 7 - 9 are for re-use two PCIe setup function) patch7 is rename two setup functions in microchip codes, prepare to move to common file.
patch8 is change the arguments of plda_pcie_setup_iomems() patch9 is move the two setup functions to common file pcie-plda-host.c
4.(patch 10 - 16 are for re-use interupt processing codes)
patch10 is rename the IRQ related functions, prepare to move to pcie-plda-host.c
patch 11 - 15 is modify the interrupt event codes, preparing for support starfive and microchip two platforms.
patch16 is move IRQ related functions to pcie-plda-host.c
------------------------------------------------------------
The remainder patches (patch 17 -22) are not refactoring patch. They are for adding StarFive codes and dont modify the microchip's codes.
patch17 is Add event bitmap for mask unused/unimpementes interrupts patch18 is Add host init/deinit functions.
patch19 is add StarFive JH7110 PCIe dt-binding doc. patch20 is Add a PCIe delay time macro
patch21 is add StarFive JH7110 Soc PCIe driver code. qurik).
patch22 is Starfive dts config
This patchset is base on v6.9-rc1
previous version:
v10:https://patchwork.kernel.org/project/linux-pci/cover/[email protected]/ v11:https://patchwork.kernel.org/project/linux-pci/cover/[email protected]/ v12:https://patchwork.kernel.org/project/linux-pci/cover/[email protected]/ v13:https://patchwork.kernel.org/project/linux-pci/cover/[email protected]/ v14:https://patchwork.kernel.org/project/linux-pci/cover/[email protected]/ v15:https://patchwork.kernel.org/project/linux-pci/cover/[email protected]/
change:
v16:
modify the patch 3 - 9 commit message. (follow Lorrenzo's review comments) Update the MAINTAINER in correct patch.
Add more comments in Starfive pcie driver to explain the pcie setting.(patch 21) Remove v15 patch 22. We will get the delay time errdata or find a correct fix method.
v15:
resend: rebase on v6.8-rc6
Add new patch 22.(A workaround to JH7110 PCIe quirk).
v14:
resend: correct some commit messages. base on v6.8-rc1
Add a new patch 17. Add interrupt eventmap to mask non-implemented or unused interrupt.
patch3: rename the PLDA interrupts macro name.
patch9: remove the redundant head file.
patch10,11: modify the commit message suggested by Lorrenzo.
patch12: modify the commit message.
patch14, 15: PLDA codes will handle DMA interrupts. Modify the commit message. patch18 remove plda default events. This is implemented by vendor. patch21 Add plda_event instance stf_pcie_event.
v13:
patch14: 1. Add plda_get_event() function. This can be compare with mc_get_event() easily and
track the codes changes in case in the future..
2. The host event_ops is directly set to plda host port.
3. Setting default host event_ops instead of checking event ops.
patch15:1. Add PLDA event irq_chip instead of event_domain_ops, The
event_domain_ops can be re-used.
2. The host event irq_chip is directly set to plda host port.
3. Add PLDA event irqchip ops codes.
4. Remove Conor's review tag due to whole patch have been changed.
patch16: Also move the new added PLDA event codes.
patch18: Add plda host init and deinit function only.
v12:
patch18: modify the commit message and add starfive review tag. Add PCIE_RESET_CONFIG_DEVICE_WAIT_MS to patch 19.
patch21: Add disable runtime pm function in starfive_pcie_remove()
Add "depens on ARCH_STARFIVE || COMPILE_TEST" in Starfive PCie Kconfig
v11:
check and modify some commit messages again.
All the codes are the same with v10.
v10:
All the commit message set to fit in 75 columns.
All the codes fit in less than 80 colunms.
patch 14:
Commit message changes suggested by Conor.
patch 21:
Add 100 ms delay macro to pci.h
generic phy pointer related codes moving to pcie-starfive.c This patch Change pcie-starfive only, bus_ops move to patch 16. Some Codes changes suggested by Bjorn.
Kevin Xie (1):
PCI: Add PCIE_RESET_CONFIG_DEVICE_WAIT_MS waiting time value
Minda Chen (21):
dt-bindings: PCI: Add PLDA XpressRICH PCIe host common properties
PCI: microchip: Move pcie-microchip-host.c to plda directory
PCI: microchip: Move PLDA IP register macros to pcie-plda.h
PCI: microchip: Add bridge_addr field to struct mc_pcie
PCI: microchip: Rename two PCIe data structures
PCI: microchip: Move PCIe host data structures to plda-pcie.h
PCI: microchip: Rename two setup functions
PCI: microchip: Change the argument of plda_pcie_setup_iomems()
PCI: microchip: Move setup functions to pcie-plda-host.c
PCI: microchip: Rename interrupt related functions
PCI: microchip: Add num_events field to struct plda_pcie_rp
PCI: microchip: Add request_event_irq() callback function
PCI: microchip: Add INTx and MSI event num to struct plda_event
PCI: microchip: Add get_events() callback and add PLDA get_event()
PCI: microchip: Add event irqchip field to host port and add PLDA
irqchip
PCI: microchip: Move IRQ functions to pcie-plda-host.c
PCI: plda: Add event bitmap field to struct plda_pcie_rp
PCI: plda: Add host init/deinit and map bus functions
dt-bindings: PCI: Add StarFive JH7110 PCIe controller
PCI: starfive: Add JH7110 PCIe controller
riscv: dts: starfive: add PCIe dts configuration for JH7110
.../bindings/pci/microchip,pcie-host.yaml | 55 +-
.../pci/plda,xpressrich3-axi-common.yaml | 75 ++
.../bindings/pci/starfive,jh7110-pcie.yaml | 120 ++++
MAINTAINERS | 19 +-
.../jh7110-starfive-visionfive-2.dtsi | 64 ++
arch/riscv/boot/dts/starfive/jh7110.dtsi | 86 +++
drivers/pci/controller/Kconfig | 9 +-
drivers/pci/controller/Makefile | 2 +-
drivers/pci/controller/plda/Kconfig | 30 +
drivers/pci/controller/plda/Makefile | 4 +
.../{ => plda}/pcie-microchip-host.c | 615 ++---------------
drivers/pci/controller/plda/pcie-plda-host.c | 651 ++++++++++++++++++
drivers/pci/controller/plda/pcie-plda.h | 273 ++++++++
drivers/pci/controller/plda/pcie-starfive.c | 488 +++++++++++++
drivers/pci/pci.h | 16 +
15 files changed, 1891 insertions(+), 616 deletions(-)
create mode 100644 Documentation/devicetree/bindings/pci/plda,xpressrich3-axi-common.yaml
create mode 100644 Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml
create mode 100644 drivers/pci/controller/plda/Kconfig
create mode 100644 drivers/pci/controller/plda/Makefile
rename drivers/pci/controller/{ => plda}/pcie-microchip-host.c (54%)
create mode 100644 drivers/pci/controller/plda/pcie-plda-host.c
create mode 100644 drivers/pci/controller/plda/pcie-plda.h
create mode 100644 drivers/pci/controller/plda/pcie-starfive.cbase-commit: 4cece764965020c22cff7665b18a012006359095
Signature · 1 line
2.17.1
PATCH v16 1/22 dt-bindings: PCI: Add PLDA XpressRICH PCIe host common properties
Add PLDA XpressRICH PCIe host common properties dt-binding doc. PolarFire PCIe host using PLDA IP. Move common properties from Microchip PolarFire PCIe host to PLDA files.
--- .../bindings/pci/microchip,pcie-host.yaml | 55 +------------- .../pci/plda,xpressrich3-axi-common.yaml | 75 +++++++++++++++++++ MAINTAINERS | 6 ++ 3 files changed, 82 insertions(+), 54 deletions(-) create mode 100644 Documentation/devicetree/bindings/pci/plda,xpressrich3-axi-common.yaml
Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml +1 -54
@@ -10,21 +10,13 @@ maintainers: - Daire McNamara <[email protected]> allOf: - - $ref: /schemas/pci/pci-bus.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: maxItems: 1
@@ -71,39 +51,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:
Documentation/devicetree/bindings/pci/plda,xpressrich3-axi-common.yaml new file +75 -0
75 lines not on this page · raw message
MAINTAINERS +6 -0
@@ -16946,6 +16946,12 @@ 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 <[email protected]> +L: [email protected] +S: Maintained +F: Documentation/devicetree/bindings/pci/plda,xpressrich3-axi-common.yaml + PCI DRIVER FOR RENESAS R-CAR M: Marek Vasut <[email protected]> M: Yoshihiro Shimoda <[email protected]>
Signature · 1 line
2.17.1
PATCH v16 2/22 PCI: microchip: Move pcie-microchip-host.c to plda directory
In reply to Minda ChenSince Microchip Polarfire PCIe host is PLDA XpressRich IP, move to PLDA directory. Prepare for refactoring the codes.
---
MAINTAINERS | 4 ++--
drivers/pci/controller/Kconfig | 9 +--------
drivers/pci/controller/Makefile | 2 +-
drivers/pci/controller/plda/Kconfig | 14 ++++++++++++++
drivers/pci/controller/plda/Makefile | 2 ++
.../controller/{ => plda}/pcie-microchip-host.c | 2 +-
6 files changed, 21 insertions(+), 12 deletions(-)
create mode 100644 drivers/pci/controller/plda/Kconfig
create mode 100644 drivers/pci/controller/plda/Makefile
rename drivers/pci/controller/{ => plda}/pcie-microchip-host.c (99%)MAINTAINERS +2 -2
@@ -17183,7 +17183,7 @@ M: Daire McNamara <[email protected]> L: [email protected] 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 <[email protected]>
@@ -18963,7 +18963,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
drivers/pci/controller/Kconfig +1 -8
@@ -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
drivers/pci/controller/Makefile +1 -1
@@ -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
drivers/pci/controller/plda/Kconfig new file +14 -0
@@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0 + +menu "PLDA-based PCIe controllers" + depends on PCI + +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. + +endmenu
drivers/pci/controller/plda/Makefile new file +2 -0
@@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_PCIE_MICROCHIP_HOST) += pcie-microchip-host.o
drivers/pci/controller/plda/pcie-microchip-host.c renamed from drivers/pci/controller/pcie-microchip-host.c +1 -1
@@ -18,7 +18,7 @@#include <linux/pci-ecam.h> #include <linux/platform_device.h> -#include "../pci.h" +#include "../../pci.h" /* Number of MSI IRQs */ #define MC_MAX_NUM_MSI_IRQS 32
Signature · 1 line
2.17.1
PATCH v16 3/22 PCI: microchip: Move PLDA IP register macros to pcie-plda.h
In reply to Minda ChenMove PLDA PCIe host controller IP registers macros to pcie-plda.h, including bridge registers and PLDA IRQ event number.
--- MAINTAINERS | 1 + .../pci/controller/plda/pcie-microchip-host.c | 108 +++--------------- drivers/pci/controller/plda/pcie-plda.h | 108 ++++++++++++++++++ 3 files changed, 125 insertions(+), 92 deletions(-) create mode 100644 drivers/pci/controller/plda/pcie-plda.h
MAINTAINERS +1 -0
@@ -16951,6 +16951,7 @@ M: Daire McNamara <[email protected]> L: [email protected] S: Maintained F: Documentation/devicetree/bindings/pci/plda,xpressrich3-axi-common.yaml +F: drivers/pci/controller/plda/pcie-plda.h PCI DRIVER FOR RENESAS R-CAR M: Marek Vasut <[email protected]>
drivers/pci/controller/plda/pcie-microchip-host.c +16 -92
126 lines not on this page · raw message
drivers/pci/controller/plda/pcie-plda.h new file +108 -0
108 lines not on this page · raw message
Signature · 1 line
2.17.1
PATCH v16 4/22 PCI: microchip: Add bridge_addr field to struct mc_pcie
In reply to Minda ChenBridge address base is common PLDA field, add this to struct mc_pcie first.
INTx and MSI interrupt code will be changed to common code, so get the bridge base address from port->bridge_addr instead of axi_base_addr. axi_base_addr is Microchip its own data.
--- .../pci/controller/plda/pcie-microchip-host.c | 23 ++++++++----------- 1 file changed, 9 insertions(+), 14 deletions(-)
drivers/pci/controller/plda/pcie-microchip-host.c +9 -14
@@ -195,6 +195,7 @@ struct mc_pcie {struct irq_domain *event_domain;raw_spinlock_t lock;struct mc_msi msi; +void __iomem *bridge_addr; };struct cause {
@@ -339,8 +340,7 @@ static void mc_handle_msi(struct irq_desc *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 ; +void __iomem *bridge_base_addr = port->bridge_addr;unsigned long status;u32 bit;int ret;
@@ -365,8 +365,7 @@ static void mc_handle_msi(struct irq_desc *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 ; +void __iomem *bridge_base_addr = port->bridge_addr;u32 bitpos = data->hwirq;writel_relaxed (BIT (bitpos), bridge_base_addr +ISTATUS_MSI );
@@ -488,8 +487,7 @@ 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 ; +void __iomem *bridge_base_addr = port->bridge_addr;unsigned long status;u32 bit;int ret;
@@ -514,8 +512,7 @@ static void mc_handle_intx(struct irq_desc *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 ; +void __iomem *bridge_base_addr = port->bridge_addr;u32 mask =BIT (data->hwirq +PM_MSI_INT_INTX_SHIFT );writel_relaxed (mask, bridge_base_addr +ISTATUS_LOCAL );
@@ -524,8 +521,7 @@ static void mc_ack_intx_irq(struct irq_data *data)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 ; +void __iomem *bridge_base_addr = port->bridge_addr;unsigned long flags;u32 mask =BIT (data->hwirq +PM_MSI_INT_INTX_SHIFT );u32 val;
@@ -540,8 +536,7 @@ static void mc_mask_intx_irq(struct irq_data *data)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 ; +void __iomem *bridge_base_addr = port->bridge_addr;unsigned long flags;u32 mask =BIT (data->hwirq +PM_MSI_INT_INTX_SHIFT );u32 val;
@@ -896,8 +891,7 @@ static void mc_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,static int mc_pcie_setup_windows (struct platform_device *pdev,struct mc_pcie *port) { -void __iomem *bridge_base_addr = - port->axi_base_addr +MC_PCIE_BRIDGE_ADDR ; +void __iomem *bridge_base_addr = port->bridge_addr;struct pci_host_bridge *bridge =platform_get_drvdata (pdev);struct resource_entry *entry;u64 pci_addr;
@@ -1081,6 +1075,7 @@ static int mc_host_probe(struct platform_device *pdev)mc_disable_interrupts (port); bridge_base_addr = port->axi_base_addr +MC_PCIE_BRIDGE_ADDR ; + port->bridge_addr = bridge_base_addr;/* Allow enabling MSI by disabling MSI-X */ val =readl (bridge_base_addr +PCIE_PCI_IRQ_DW0 );
Signature · 7 lines
2.17.1 _______________________________________________ linux-riscv mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-riscv
PATCH v16 5/22 PCI: microchip: Rename two PCIe data structures
In reply to Minda ChenAdd PLDA PCIe related data structures by rename data structure name from mc_* to plda_*.
axi_base_addr is stayed in struct mc_pcie since it's microchip its own data.
The event interrupt code is still using struct mc_pcie because the event interrupt code can not be re-used.
--- .../pci/controller/plda/pcie-microchip-host.c | 96 ++++++++++--------- 1 file changed, 53 insertions(+), 43 deletions(-)
drivers/pci/controller/plda/pcie-microchip-host.c +53 -43
@@ -22,7 +22,7 @@#include "pcie-plda.h" /* Number of MSI IRQs */ -#define MC_MAX_NUM_MSI_IRQS 32 +#define PLDA_MAX_NUM_MSI_IRQS 32/* PCIe Bridge Phy and Controller Phy offsets */ #define MC_PCIE1_BRIDGE_ADDR 0x00008000u
@@ -179,25 +179,29 @@ struct event_map {u32 event_bit; }; -struct mc_msi { +struct plda_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); + DECLARE_BITMAP(used, PLDA_MAX_NUM_MSI_IRQS); }; -struct mc_pcie { -void __iomem *axi_base_addr; +struct plda_pcie_rp {struct device *dev;struct irq_domain *intx_domain;struct irq_domain *event_domain;raw_spinlock_t lock; -struct mc_msi msi; +struct plda_msi msi;void __iomem *bridge_addr; }; +struct mc_pcie { +struct plda_pcie_rp plda; +void __iomem *axi_base_addr; +}; +struct cause {const char *sym;const char *str;
@@ -313,7 +317,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;
@@ -336,10 +340,10 @@ static void mc_pcie_enable_msi(struct mc_pcie *port, void __iomem *ecam)static void mc_handle_msi (struct irq_desc *desc) { -struct mc_pcie *port =irq_desc_get_handler_data (desc); +struct plda_pcie_rp *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; +struct plda_msi *msi = &port->msi;void __iomem *bridge_base_addr = port->bridge_addr;unsigned long status;u32 bit;
@@ -364,7 +368,7 @@ static void mc_handle_msi(struct irq_desc *desc)static void mc_msi_bottom_irq_ack (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);void __iomem *bridge_base_addr = port->bridge_addr;u32 bitpos = data->hwirq;
@@ -373,7 +377,7 @@ static void mc_msi_bottom_irq_ack(struct irq_data *data)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); +struct plda_pcie_rp *port =irq_data_get_irq_chip_data (data);phys_addr_t addr = port->msi.vector_phy; msg->address_lo =lower_32_bits (addr);
@@ -400,8 +404,8 @@ static struct irq_chip mc_msi_bottom_irq_chip = {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; +struct plda_pcie_rp *port = domain->host_data; +struct plda_msi *msi = &port->msi;unsigned long bit;mutex_lock (&msi->lock);
@@ -425,8 +429,8 @@ 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; +struct plda_pcie_rp *port =irq_data_get_irq_chip_data (d); +struct plda_msi *msi = &port->msi;mutex_lock (&msi->lock);
@@ -456,11 +460,11 @@ static struct msi_domain_info mc_msi_domain_info = { .chip = &mc_msi_irq_chip, }; -static int mc_allocate_msi_domains (struct mc_pcie *port) +static int mc_allocate_msi_domains (struct plda_pcie_rp *port) {struct device *dev = port->dev;struct fwnode_handle *fwnode =of_node_to_fwnode (dev->of_node); -struct mc_msi *msi = &port->msi; +struct plda_msi *msi = &port->msi;mutex_init (&port->msi.lock);
@@ -484,7 +488,7 @@ static int mc_allocate_msi_domains(struct mc_pcie *port)static void mc_handle_intx (struct irq_desc *desc) { -struct mc_pcie *port =irq_desc_get_handler_data (desc); +struct plda_pcie_rp *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->bridge_addr;
@@ -511,7 +515,7 @@ static void mc_handle_intx(struct irq_desc *desc)static void mc_ack_intx_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);void __iomem *bridge_base_addr = port->bridge_addr;u32 mask =BIT (data->hwirq +PM_MSI_INT_INTX_SHIFT );
@@ -520,7 +524,7 @@ static void mc_ack_intx_irq(struct irq_data *data)static void mc_mask_intx_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);void __iomem *bridge_base_addr = port->bridge_addr;unsigned long flags;u32 mask =BIT (data->hwirq +PM_MSI_INT_INTX_SHIFT );
@@ -535,7 +539,7 @@ static void mc_mask_intx_irq(struct irq_data *data)static void mc_unmask_intx_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);void __iomem *bridge_base_addr = port->bridge_addr;unsigned long flags;u32 mask =BIT (data->hwirq +PM_MSI_INT_INTX_SHIFT );
@@ -625,21 +629,22 @@ static u32 local_events(struct mc_pcie *port)return val; } -static u32 get_events (struct mc_pcie *port) +static u32 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;
@@ -655,7 +660,7 @@ static irqreturn_t mc_event_handler(int irq, void *dev_id)static void mc_handle_event (struct irq_desc *desc) { -struct mc_pcie *port =irq_desc_get_handler_data (desc); +struct plda_pcie_rp *port =irq_desc_get_handler_data (desc);unsigned long events;u32 bit;struct irq_chip *chip =irq_desc_get_chip (desc);
@@ -672,12 +677,13 @@ static void mc_handle_event(struct irq_desc *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;
@@ -687,13 +693,14 @@ static void mc_ack_event_irq(struct irq_data *data)static void mc_mask_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;u32 val; - addr = port->axi_base_addr + event_descs[event].base + + addr = mc_port->axi_base_addr + event_descs[event].base + event_descs[event].mask_offset; mask = event_descs[event].mask;if (event_descs[event].enb_mask) {
@@ -717,13 +724,14 @@ static void mc_mask_event_irq(struct irq_data *data)static void mc_unmask_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;u32 val; - addr = port->axi_base_addr + event_descs[event].base + + addr = mc_port->axi_base_addr + event_descs[event].base + event_descs[event].mask_offset; mask = event_descs[event].mask;
@@ -811,7 +819,7 @@ static int mc_pcie_init_clks(struct device *dev)return 0 ; } -static int mc_pcie_init_irq_domains (struct mc_pcie *port) +static int mc_pcie_init_irq_domains (struct plda_pcie_rp *port) {struct device *dev = port->dev;struct device_node *node = dev->of_node;
@@ -889,7 +897,7 @@ static void mc_pcie_setup_window(void __iomem *bridge_base_addr, u32 index, }static int mc_pcie_setup_windows (struct platform_device *pdev, -struct mc_pcie *port) +struct plda_pcie_rp *port) {void __iomem *bridge_base_addr = port->bridge_addr;struct pci_host_bridge *bridge =platform_get_drvdata (pdev);
@@ -970,7 +978,7 @@ static void mc_disable_interrupts(struct mc_pcie *port)writel_relaxed (GENMASK (31 ,0 ), bridge_base_addr +ISTATUS_HOST ); } -static int mc_init_interrupts (struct platform_device *pdev,struct mc_pcie *port) +static int mc_init_interrupts (struct platform_device *pdev,struct plda_pcie_rp *port) {struct device *dev = &pdev->dev;int irq;
@@ -1043,12 +1051,12 @@ static int mc_platform_init(struct pci_config_window *cfg)mc_pcie_enable_msi (port, cfg->win);/* Configure non-config space outbound ranges */ - ret =mc_pcie_setup_windows (pdev, port); + ret =mc_pcie_setup_windows (pdev, &port->plda);if (ret)return ret;/* Address translation is up; safe to enable interrupts */ - ret =mc_init_interrupts (pdev, port); + ret =mc_init_interrupts (pdev, &port->plda);if (ret)return ret;
@@ -1059,6 +1067,7 @@ static int mc_host_probe(struct platform_device *pdev) {struct device *dev = &pdev->dev;void __iomem *bridge_base_addr; +struct plda_pcie_rp *plda;int ret;u32 val;
@@ -1066,7 +1075,8 @@ static int mc_host_probe(struct platform_device *pdev)if (!port)return -ENOMEM ; - port->dev = dev; + plda = &port->plda; + plda->dev = dev; port->axi_base_addr =devm_platform_ioremap_resource (pdev,1 );if (IS_ERR (port->axi_base_addr))
@@ -1075,7 +1085,7 @@ static int mc_host_probe(struct platform_device *pdev)mc_disable_interrupts (port); bridge_base_addr = port->axi_base_addr +MC_PCIE_BRIDGE_ADDR ; - port->bridge_addr = bridge_base_addr; + plda->bridge_addr = bridge_base_addr;/* Allow enabling MSI by disabling MSI-X */ val =readl (bridge_base_addr +PCIE_PCI_IRQ_DW0 );
@@ -1087,10 +1097,10 @@ static int mc_host_probe(struct platform_device *pdev) val &=NUM_MSI_MSGS_MASK ; val >>=NUM_MSI_MSGS_SHIFT ; - port->msi.num_vectors =1 << val; + plda->msi.num_vectors =1 << val;/* Pick vector address from design */ - port->msi.vector_phy =readl_relaxed (bridge_base_addr +IMSI_ADDR ); + plda->msi.vector_phy =readl_relaxed (bridge_base_addr +IMSI_ADDR ); ret =mc_pcie_init_clks (dev);if (ret) {
Signature · 1 line
2.17.1
PATCH v16 6/22 PCI: microchip: Move PCIe host data structures to plda-pcie.h
In reply to Minda ChenMove the common data structures definition to head file becauce these two data structures can be re-used.
--- .../pci/controller/plda/pcie-microchip-host.c | 20 ------------------ drivers/pci/controller/plda/pcie-plda.h | 21 +++++++++++++++++++ 2 files changed, 21 insertions(+), 20 deletions(-)
drivers/pci/controller/plda/pcie-microchip-host.c +0 -20
@@ -21,9 +21,6 @@#include "../../pci.h" #include "pcie-plda.h" -/* Number of MSI IRQs */ -#define PLDA_MAX_NUM_MSI_IRQS 32 -/* PCIe Bridge Phy and Controller Phy offsets */ #define MC_PCIE1_BRIDGE_ADDR 0x00008000u#define MC_PCIE1_CTRL_ADDR 0x0000a000u
@@ -179,23 +176,6 @@ struct event_map {u32 event_bit; }; -struct plda_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, PLDA_MAX_NUM_MSI_IRQS); -}; - -struct plda_pcie_rp { -struct device *dev; -struct irq_domain *intx_domain; -struct irq_domain *event_domain; -raw_spinlock_t lock; -struct plda_msi msi; -void __iomem *bridge_addr; -};struct mc_pcie {struct plda_pcie_rp plda;
drivers/pci/controller/plda/pcie-plda.h +21 -0
@@ -6,6 +6,9 @@#ifndef _PCIE_PLDA_H#define _PCIE_PLDA_H +/* Number of MSI IRQs */ +#define PLDA_MAX_NUM_MSI_IRQS 32 +/* PCIe Bridge Phy Regs */ #define PCIE_PCI_IRQ_DW0 0xa8#define MSIX_CAP_MASK BIT(31)
@@ -105,4 +108,22 @@ enum plda_int_event {#define PLDA_MAX_EVENT_NUM (PLDA_NUM_DMA_EVENTS + PLDA_INT_EVENT_NUM) +struct plda_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, PLDA_MAX_NUM_MSI_IRQS); +}; + +struct plda_pcie_rp { +struct device *dev; +struct irq_domain *intx_domain; +struct irq_domain *event_domain; +raw_spinlock_t lock; +struct plda_msi msi; +void __iomem *bridge_addr; +}; +#endif
Signature · 1 line
2.17.1
PATCH v16 7/22 PCI: microchip: Rename two setup functions
In reply to Minda ChenRename two setup functions to plda prefix. Prepare to re-use these two setup functions.
Since two setup functions names are similar, rename mc_pcie_setup_windows() to plda_pcie_setup_iomems().
--- .../pci/controller/plda/pcie-microchip-host.c | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-)
drivers/pci/controller/plda/pcie-microchip-host.c +12 -12
@@ -838,9 +838,9 @@ static int mc_pcie_init_irq_domains(struct plda_pcie_rp *port)return mc_allocate_msi_domains (port); } -static void mc_pcie_setup_window (void __iomem *bridge_base_addr,u32 index, -phys_addr_t axi_addr,phys_addr_t pci_addr, -size_t size) +static void plda_pcie_setup_window (void __iomem *bridge_base_addr,u32 index, +phys_addr_t axi_addr,phys_addr_t pci_addr, +size_t size) {u32 atr_sz =ilog2 (size) -1 ;u32 val;
@@ -876,8 +876,8 @@ static void mc_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,writel (0 , bridge_base_addr +ATR0_PCIE_WIN0_SRC_ADDR ); } -static int mc_pcie_setup_windows (struct platform_device *pdev, -struct plda_pcie_rp *port) +static int plda_pcie_setup_iomems (struct platform_device *pdev, +struct plda_pcie_rp *port) {void __iomem *bridge_base_addr = port->bridge_addr;struct pci_host_bridge *bridge =platform_get_drvdata (pdev);
@@ -888,9 +888,9 @@ static int mc_pcie_setup_windows(struct platform_device *pdev,resource_list_for_each_entry (entry, &bridge->windows) {if (resource_type (entry->res) ==IORESOURCE_MEM ) { pci_addr = entry->res->start - entry->offset; -mc_pcie_setup_window (bridge_base_addr, index, - entry->res->start, pci_addr, -resource_size (entry->res)); +plda_pcie_setup_window (bridge_base_addr, index, + entry->res->start, pci_addr, +resource_size (entry->res)); index++; } }
@@ -1023,15 +1023,15 @@ static int mc_platform_init(struct pci_config_window *cfg)int ret;/* Configure address translation table 0 for PCIe config space */ -mc_pcie_setup_window (bridge_base_addr,0 , cfg->res.start, - cfg->res.start, -resource_size (&cfg->res)); +plda_pcie_setup_window (bridge_base_addr,0 , cfg->res.start, + cfg->res.start, +resource_size (&cfg->res));/* Need some fixups in config space */ mc_pcie_enable_msi (port, cfg->win);/* Configure non-config space outbound ranges */ - ret =mc_pcie_setup_windows (pdev, &port->plda); + ret =plda_pcie_setup_iomems (pdev, &port->plda);if (ret)return ret;
Signature · 1 line
2.17.1
PATCH v16 8/22 PCI: microchip: Change the argument of plda_pcie_setup_iomems()
In reply to Minda ChenIf other vendor do not select PCI_HOST_COMMON, the driver data is not struct pci_host_bridge.
Move calling platform_get_drvdata() to mc_platform_init().
--- drivers/pci/controller/plda/pcie-microchip-host.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/pci/controller/plda/pcie-microchip-host.c +3 -3
@@ -876,11 +876,10 @@ static void plda_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,writel (0 , bridge_base_addr +ATR0_PCIE_WIN0_SRC_ADDR ); } -static int plda_pcie_setup_iomems (struct platform_device *pdev, +static int plda_pcie_setup_iomems (struct pci_host_bridge *bridge,struct plda_pcie_rp *port) {void __iomem *bridge_base_addr = port->bridge_addr; -struct pci_host_bridge *bridge =platform_get_drvdata (pdev);struct resource_entry *entry;u64 pci_addr;u32 index =1 ;
@@ -1018,6 +1017,7 @@ static int mc_platform_init(struct pci_config_window *cfg) {struct device *dev = cfg->parent;struct platform_device *pdev =to_platform_device (dev); +struct pci_host_bridge *bridge =platform_get_drvdata (pdev);void __iomem *bridge_base_addr = port->axi_base_addr +MC_PCIE_BRIDGE_ADDR ;int ret;
@@ -1031,7 +1031,7 @@ static int mc_platform_init(struct pci_config_window *cfg)mc_pcie_enable_msi (port, cfg->win);/* Configure non-config space outbound ranges */ - ret =plda_pcie_setup_iomems (pdev, &port->plda); + ret =plda_pcie_setup_iomems (bridge, &port->plda);if (ret)return ret;
Signature · 1 line
2.17.1
Re: [PATCH v16 08/22] PCI: microchip: Change the argument of plda_pcie_setup_iomems()
The patch is OK, but the subject line is not very informative. It should be useful all by itself even without the commit log. "Change the argument of X" doesn't say anything about why we would want to do that.
Quoted 2 lines · Minda Chen
If other vendor do not select
PCI_HOST_COMMON, the driver data is not structpci_host_bridge.
Also, I don't think this is the real problem. Your PCIE_MICROCHIP_HOST Kconfig selects PCI_HOST_COMMON, and the driver calls pci_host_common_probe(), so the driver wouldn't even build without PCI_HOST_COMMON.
This patch is already applied and ready to go, but if you can tell us what's really going on here, I'd like to update the commit log.
Quoted 45 lines
Move calling
platform_get_drvdata()tomc_platform_init().Signed-off-by Minda Chen <[email protected]>Reviewed-by Conor Dooley <[email protected]>--- drivers/pci/controller/plda/pcie-microchip-host.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)drivers/pci/controller/plda/pcie-microchip-host.c +3
-3@@ -876,11 +876,10 @@ static void plda_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,writel (0 , bridge_base_addr +ATR0_PCIE_WIN0_SRC_ADDR ); } -static int plda_pcie_setup_iomems (struct platform_device *pdev, +static int plda_pcie_setup_iomems (struct pci_host_bridge *bridge,struct plda_pcie_rp *port) {void __iomem *bridge_base_addr = port->bridge_addr; -struct pci_host_bridge *bridge =platform_get_drvdata (pdev);struct resource_entry *entry;u64 pci_addr;u32 index =1 ;@@ -1018,6 +1017,7 @@ static int mc_platform_init(struct pci_config_window *cfg) {struct device *dev = cfg->parent;struct platform_device *pdev =to_platform_device (dev); +struct pci_host_bridge *bridge =platform_get_drvdata (pdev);void __iomem *bridge_base_addr = port->axi_base_addr +MC_PCIE_BRIDGE_ADDR ;int ret;@@ -1031,7 +1031,7 @@ static int mc_platform_init(struct pci_config_window *cfg)mc_pcie_enable_msi (port, cfg->win);/* Configure non-config space outbound ranges */ - ret =plda_pcie_setup_iomems (pdev, &port->plda); + ret =plda_pcie_setup_iomems (bridge, &port->plda);if (ret)return ret;Signature · 1 line
2.17.1
回复: [PATCH v16 08/22] PCI: microchip: Change the argument of plda_pcie_setup_iomems()
Quoted 11 lines
The patch is OK, but the subject line is not very informative. It should be useful all by itself even without the commit log. "Change the argument of X" doesn't say anything about why we would want to do that.
Quoted 2 lines · Minda Chen
If other vendor do not select
PCI_HOST_COMMON, the driver data is not structpci_host_bridge.
Quoted 8 lines
Also, I don't think this is the real problem. Your
PCIE_MICROCHIP_HOSTKconfigselectsPCI_HOST_COMMON, and the driver callspci_host_common_probe(), so the driver wouldn't even build withoutPCI_HOST_COMMON.This patch is already applied and ready to go, but if you can tell us what's really going on here, I'd like to update the commit log.
It is modified for Starfive code. Starfive JH7110 PCIe do not select PCI_HOST_COMMONplda_pcie_setup_iomems() will be changed to common plda code.
I think I can modify the title and commit log like this.
Title:
PCI: microchip: Get struct pci_host_bridge pointer from platform code
Since plda_pcie_setup_iomems() will be a common PLDA core driver function, but the argument0 is a struct platform_device pointer. plda_pcie_setup_iomems() actually using struct pci_host_bridge pointer other than platform_device pointer. Further more if a new PLDA core PCIe driver do not select PCI_HOST_COMMON, the platform driver data is not struct pci_host_bridge pointer. So get struct pci_host_bridge pointer from platform code function mc_platform_init() and make it to be an argument of plda_pcie_setup_iomems().
Quoted 47 lines
drivers/pci/controller/plda/pcie-microchip-host.c static void plda_pcie_setup_window(void __iomem
Quoted 14 lines
Move calling
platform_get_drvdata()tomc_platform_init().Signed-off-by Minda Chen <[email protected]>Reviewed-by Conor Dooley <[email protected]>--- drivers/pci/controller/plda/pcie-microchip-host.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)drivers/pci/controller/plda/pcie-microchip-host.c +0
-0@@ -876,11 +876,10 @@ static void plda_pcie_setup_window(void __iomem
*bridge_base_addr, u32 index,drivers/pci/controller/plda/pcie-microchip-host.c static int mc_platform_init(struct
Quoted 20 lines
drivers/pci/controller/plda/pcie-microchip-host.c +2
-2writel (0 , bridge_base_addr +ATR0_PCIE_WIN0_SRC_ADDR ); } -static int plda_pcie_setup_iomems (struct platform_device *pdev, +static int plda_pcie_setup_iomems (struct pci_host_bridge *bridge,struct plda_pcie_rp *port) {void __iomem *bridge_base_addr = port->bridge_addr; -struct pci_host_bridge *bridge =platform_get_drvdata (pdev);struct resource_entry *entry;u64 pci_addr;u32 index =1 ;@@ -1018,6 +1017,7 @@ static int mc_platform_init(struct pci_config_window *cfg) {struct device *dev = cfg->parent;struct platform_device *pdev =to_platform_device (dev); +struct pci_host_bridge *bridge =platform_get_drvdata (pdev);void __iomem *bridge_base_addr = port->axi_base_addr +MC_PCIE_BRIDGE_ADDR ;int ret;@@ -1031,7 +1031,7 @@ static int mc_platform_init(struct
pci_config_window*cfg)Quoted 11 lines
drivers/pci/controller/plda/pcie-microchip-host.c +1
-2mc_pcie_enable_msi (port, cfg->win);/* Configure non-config space outbound ranges */ - ret =plda_pcie_setup_iomems (pdev, &port->plda); + ret =plda_pcie_setup_iomems (bridge, &port->plda);if (ret)return ret; --2.17.1
Re: 回复: [PATCH v16 08/22] PCI: microchip: Change the argument of plda_pcie_setup_iomems()
Quoted 26 lines · Minda Chen
Quoted 9 lines
The patch is OK, but the subject line is not very informative. It should be useful all by itself even without the commit log. "Change the argument of X" doesn't say anything about why we would want to do that.
Quoted 2 lines · Minda Chen
If other vendor do not select
PCI_HOST_COMMON, the driver data is not structpci_host_bridge.Quoted 8 lines
Also, I don't think this is the real problem. Your
PCIE_MICROCHIP_HOSTKconfigselectsPCI_HOST_COMMON, and the driver callspci_host_common_probe(), so the driver wouldn't even build withoutPCI_HOST_COMMON.This patch is already applied and ready to go, but if you can tell us what's really going on here, I'd like to update the commit log.
It is modified for Starfive code. Starfive JH7110 PCIe do not select
PCI_HOST_COMMONplda_pcie_setup_iomems()will be changed to common plda code.I think I can modify the title and commit log like this.
Title:
PCI: microchip: Get structpci_host_bridgepointer from platform code
Quoted 9 lines
Since
plda_pcie_setup_iomems()will be a common PLDA core driver function, but the argument0 is a structplatform_devicepointer.plda_pcie_setup_iomems()actually using structpci_host_bridgepointer other thanplatform_devicepointer. Further more if a new PLDA core PCIe driver do not selectPCI_HOST_COMMON, the platform driver data is not structpci_host_bridgepointer. So get structpci_host_bridgepointer from platform code functionmc_platform_init()and make it to be an argument ofplda_pcie_setup_iomems().
OK, I see what you're doing. This actually has nothing to do with whether PCI_HOST_COMMON is *enabled*. It has to do with whether drivers use pci_host_common_probe(). Here's what I propose:
PCI: plda: Pass pci_host_bridge to plda_pcie_setup_iomems()
plda_pcie_setup_iomems() needs the bridge->windows list from struct pci_host_bridge and is currently used only by pcie-microchip-host.c. This driver uses pci_host_common_probe(), which sets a pci_host_bridge as the drvdata, so plda_pcie_setup_iomems() used platform_get_drvdata() to find the pci_host_bridge.
But we also want to use plda_pcie_setup_iomems() in the new pcie-starfive.c driver, which does not use pci_host_common_probe() and will have struct starfive_jh7110_pcie as its drvdata, so pass the pci_host_bridge directly to plda_pcie_setup_iomems() so it doesn't need platform_get_drvdata() to find it.
Quoted 47 lines
Quoted 47 lines
drivers/pci/controller/plda/pcie-microchip-host.c static void plda_pcie_setup_window(void __iomem
Quoted 14 lines
Move calling
platform_get_drvdata()tomc_platform_init().Signed-off-by Minda Chen <[email protected]>Reviewed-by Conor Dooley <[email protected]>--- drivers/pci/controller/plda/pcie-microchip-host.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)drivers/pci/controller/plda/pcie-microchip-host.c +0
-0@@ -876,11 +876,10 @@ static void plda_pcie_setup_window(void __iomem
*bridge_base_addr, u32 index,drivers/pci/controller/plda/pcie-microchip-host.c static int mc_platform_init(struct
Quoted 20 lines
drivers/pci/controller/plda/pcie-microchip-host.c +2
-2writel (0 , bridge_base_addr +ATR0_PCIE_WIN0_SRC_ADDR ); } -static int plda_pcie_setup_iomems (struct platform_device *pdev, +static int plda_pcie_setup_iomems (struct pci_host_bridge *bridge,struct plda_pcie_rp *port) {void __iomem *bridge_base_addr = port->bridge_addr; -struct pci_host_bridge *bridge =platform_get_drvdata (pdev);struct resource_entry *entry;u64 pci_addr;u32 index =1 ;@@ -1018,6 +1017,7 @@ static int mc_platform_init(struct pci_config_window *cfg) {struct device *dev = cfg->parent;struct platform_device *pdev =to_platform_device (dev); +struct pci_host_bridge *bridge =platform_get_drvdata (pdev);void __iomem *bridge_base_addr = port->axi_base_addr +MC_PCIE_BRIDGE_ADDR ;int ret;@@ -1031,7 +1031,7 @@ static int mc_platform_init(struct
pci_config_window*cfg)Quoted 11 lines
drivers/pci/controller/plda/pcie-microchip-host.c +1
-2mc_pcie_enable_msi (port, cfg->win);/* Configure non-config space outbound ranges */ - ret =plda_pcie_setup_iomems (pdev, &port->plda); + ret =plda_pcie_setup_iomems (bridge, &port->plda);if (ret)return ret; --2.17.1
Re: [PATCH v16 08/22] PCI: microchip: Change the argument of plda_pcie_setup_iomems()
Quoted 53 lines · Minda Chen
Quoted 11 lines
Quoted 11 lines
The patch is OK, but the subject line is not very informative. It should be useful all by itself even without the commit log. "Change the argument of X" doesn't say anything about why we would want to do that.
Quoted 2 lines · Minda Chen
If other vendor do not select
PCI_HOST_COMMON, the driver data is not structpci_host_bridge.Also, I don't think this is the real problem. Your
PCIE_MICROCHIP_HOSTKconfigselectsPCI_HOST_COMMON, and thedriver
Quoted 15 lines
Quoted 6 lines
calls
pci_host_common_probe(), so the driver wouldn't even build withoutPCI_HOST_COMMON.This patch is already applied and ready to go, but if you can tell us what's really going on here, I'd like to update the commit log.
It is modified for Starfive code. Starfive JH7110 PCIe do not select
PCI_HOST_COMMONplda_pcie_setup_iomems()will be changed to common plda code.I think I can modify the title and commit log like this.
Title:
PCI: microchip: Get structpci_host_bridgepointer from platform codeQuoted 9 lines
Since
plda_pcie_setup_iomems()will be a common PLDA core driver function, but the argument0 is a structplatform_devicepointer.plda_pcie_setup_iomems()actually using structpci_host_bridgepointer other thanplatform_devicepointer. Further more if a new PLDA core PCIe driver do not selectPCI_HOST_COMMON, the platform driver data is not structpci_host_bridgepointer. So get structpci_host_bridgepointer from platform code functionmc_platform_init()and make it to be an argument ofplda_pcie_setup_iomems().OK, I see what you're doing. This actually has nothing to do with whether
PCI_HOST_COMMONis *enabled*. It has to do with whether drivers usepci_host_common_probe(). Here's what I propose:PCI: plda: Pass
pci_host_bridgetoplda_pcie_setup_iomems()
plda_pcie_setup_iomems()needs thebridge->windowslist from structpci_host_bridgeand is currently used only bypcie-microchip-host.c. This driver usespci_host_common_probe(), which sets apci_host_bridgeas the drvdata, soplda_pcie_setup_iomems()usedplatform_get_drvdata()to find thepci_host_bridge.
Quoted 6 lines
But we also want to use
plda_pcie_setup_iomems()in the newpcie-starfive.cdriver, which does not usepci_host_common_probe()and will have structstarfive_jh7110_pcieas its drvdata, so pass thepci_host_bridgedirectly toplda_pcie_setup_iomems()so it doesn't needplatform_get_drvdata()to find it.
OK, Thanks.
I see PCIe 6.10 changed have been merged to main line. Should I resend this patch set base on 6.10-rc1?
Quoted 48 lines
Quoted 48 lines
Quoted 48 lines
Quoted 14 lines
Move calling
platform_get_drvdata()tomc_platform_init().Signed-off-by Minda Chen <[email protected]>Reviewed-by Conor Dooley <[email protected]>--- drivers/pci/controller/plda/pcie-microchip-host.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)drivers/pci/controller/plda/pcie-microchip-host.c +0
-0@@ -876,11 +876,10 @@ static void plda_pcie_setup_window(voidQuoted 1 line
__iomem
*bridge_base_addr, u32 index,drivers/pci/controller/plda/pcie-microchip-host.c static int mc_platform_init(struct
Quoted 20 lines
drivers/pci/controller/plda/pcie-microchip-host.c +2
-2writel (0 , bridge_base_addr +ATR0_PCIE_WIN0_SRC_ADDR ); } -static int plda_pcie_setup_iomems (struct platform_device *pdev, +static int plda_pcie_setup_iomems (struct pci_host_bridge *bridge,struct plda_pcie_rp *port) {void __iomem *bridge_base_addr = port->bridge_addr; -struct pci_host_bridge *bridge =platform_get_drvdata (pdev);struct resource_entry *entry;u64 pci_addr;u32 index =1 ;@@ -1018,6 +1017,7 @@ static int mc_platform_init(struct pci_config_window *cfg) {struct device *dev = cfg->parent;struct platform_device *pdev =to_platform_device (dev); +struct pci_host_bridge *bridge =platform_get_drvdata (pdev);void __iomem *bridge_base_addr = port->axi_base_addr +MC_PCIE_BRIDGE_ADDR ;int ret;@@ -1031,7 +1031,7 @@ static int mc_platform_init(struct
pci_config_window*cfg)Quoted 11 lines
drivers/pci/controller/plda/pcie-microchip-host.c +1
-2mc_pcie_enable_msi (port, cfg->win);/* Configure non-config space outbound ranges */ - ret =plda_pcie_setup_iomems (pdev, &port->plda); + ret =plda_pcie_setup_iomems (bridge, &port->plda);if (ret)return ret; --2.17.1
Re: [PATCH v16 08/22] PCI: microchip: Change the argument of plda_pcie_setup_iomems()
Quoted 56 lines · Minda Chen
Quoted 50 lines · Minda Chen
Quoted 11 lines
Quoted 11 lines
The patch is OK, but the subject line is not very informative. It should be useful all by itself even without the commit log. "Change the argument of X" doesn't say anything about why we would want to do that.
Quoted 2 lines · Minda Chen
If other vendor do not select
PCI_HOST_COMMON, the driver data is not structpci_host_bridge.Also, I don't think this is the real problem. Your
PCIE_MICROCHIP_HOSTKconfigselectsPCI_HOST_COMMON, and thedriver
Quoted 15 lines
Quoted 6 lines
calls
pci_host_common_probe(), so the driver wouldn't even build withoutPCI_HOST_COMMON.This patch is already applied and ready to go, but if you can tell us what's really going on here, I'd like to update the commit log.
It is modified for Starfive code. Starfive JH7110 PCIe do not select
PCI_HOST_COMMONplda_pcie_setup_iomems()will be changed to common plda code.I think I can modify the title and commit log like this.
Title:
PCI: microchip: Get structpci_host_bridgepointer from platform codeQuoted 9 lines
Since
plda_pcie_setup_iomems()will be a common PLDA core driver function, but the argument0 is a structplatform_devicepointer.plda_pcie_setup_iomems()actually using structpci_host_bridgepointer other thanplatform_devicepointer. Further more if a new PLDA core PCIe driver do not selectPCI_HOST_COMMON, the platform driver data is not structpci_host_bridgepointer. So get structpci_host_bridgepointer from platform code functionmc_platform_init()and make it to be an argument ofplda_pcie_setup_iomems().OK, I see what you're doing. This actually has nothing to do with whether
PCI_HOST_COMMONis *enabled*. It has to do with whether drivers usepci_host_common_probe(). Here's what I propose:PCI: plda: Pass
pci_host_bridgetoplda_pcie_setup_iomems()
plda_pcie_setup_iomems()needs thebridge->windowslist from structpci_host_bridgeand is currently used only bypcie-microchip-host.c. This driver usespci_host_common_probe(), which sets apci_host_bridgeas the drvdata, soplda_pcie_setup_iomems()usedplatform_get_drvdata()to find thepci_host_bridge.Quoted 6 lines
But we also want to use
plda_pcie_setup_iomems()in the newpcie-starfive.cdriver, which does not usepci_host_common_probe()and will have structstarfive_jh7110_pcieas its drvdata, so pass thepci_host_bridgedirectly toplda_pcie_setup_iomems()so it doesn't needplatform_get_drvdata()to find it.
Quoted 4 lines
OK, Thanks.
I see PCIe 6.10 changed have been merged to main line. Should I resend this patch set base on 6.10-rc1?
No need, I rebased it to f0bae243b2bc ("Merge tag 'pci-v6.10-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci") already and it will be a trivial rebase to v6.10-rc1 next week.
The current pci/controller/microchip branch is at:
https://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git/log/?h=ed261441e224
Let me know if anything is missing from there. I can't merge it into linux-next until v6.10-rc1 is tagged, but as soon as it is, I'll put it in linux-next.
Quoted 48 lines
Quoted 48 lines
Quoted 48 lines
Quoted 48 lines
Quoted 14 lines
Move calling
platform_get_drvdata()tomc_platform_init().Signed-off-by Minda Chen <[email protected]>Reviewed-by Conor Dooley <[email protected]>--- drivers/pci/controller/plda/pcie-microchip-host.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)drivers/pci/controller/plda/pcie-microchip-host.c +0
-0@@ -876,11 +876,10 @@ static void plda_pcie_setup_window(voidQuoted 1 line
__iomem
*bridge_base_addr, u32 index,drivers/pci/controller/plda/pcie-microchip-host.c static int mc_platform_init(struct
Quoted 20 lines
drivers/pci/controller/plda/pcie-microchip-host.c +2
-2writel (0 , bridge_base_addr +ATR0_PCIE_WIN0_SRC_ADDR ); } -static int plda_pcie_setup_iomems (struct platform_device *pdev, +static int plda_pcie_setup_iomems (struct pci_host_bridge *bridge,struct plda_pcie_rp *port) {void __iomem *bridge_base_addr = port->bridge_addr; -struct pci_host_bridge *bridge =platform_get_drvdata (pdev);struct resource_entry *entry;u64 pci_addr;u32 index =1 ;@@ -1018,6 +1017,7 @@ static int mc_platform_init(struct pci_config_window *cfg) {struct device *dev = cfg->parent;struct platform_device *pdev =to_platform_device (dev); +struct pci_host_bridge *bridge =platform_get_drvdata (pdev);void __iomem *bridge_base_addr = port->axi_base_addr +MC_PCIE_BRIDGE_ADDR ;int ret;@@ -1031,7 +1031,7 @@ static int mc_platform_init(struct
pci_config_window*cfg)Quoted 11 lines
drivers/pci/controller/plda/pcie-microchip-host.c +1
-2mc_pcie_enable_msi (port, cfg->win);/* Configure non-config space outbound ranges */ - ret =plda_pcie_setup_iomems (pdev, &port->plda); + ret =plda_pcie_setup_iomems (bridge, &port->plda);if (ret)return ret; --2.17.1
Re: [PATCH v16 08/22] PCI: microchip: Change the argument of plda_pcie_setup_iomems()
Quoted 75 lines · Minda Chen
Quoted 39 lines
Quoted 39 lines · Minda Chen
Quoted 11 lines
Quoted 11 lines
The patch is OK, but the subject line is not very informative. It should be useful all by itself even without the commit log. "Change the argument of X" doesn't say anything about why we would want to do that.
Quoted 2 lines · Minda Chen
If other vendor do not select
PCI_HOST_COMMON, the driver data is not structpci_host_bridge.Also, I don't think this is the real problem. Your
PCIE_MICROCHIP_HOSTKconfigselectsPCI_HOST_COMMON, and thedriver
Quoted 25 lines
Quoted 6 lines
calls
pci_host_common_probe(), so the driver wouldn't even build withoutPCI_HOST_COMMON.This patch is already applied and ready to go, but if you can tell us what's really going on here, I'd like to update the commit log.
It is modified for Starfive code. Starfive JH7110 PCIe do not select
PCI_HOST_COMMONplda_pcie_setup_iomems()will be changed to common plda code.I think I can modify the title and commit log like this.
Title:
PCI: microchip: Get structpci_host_bridgepointer from platform codeSince
plda_pcie_setup_iomems()will be a common PLDA core driver function, but the argument0 is a structplatform_devicepointer.plda_pcie_setup_iomems()actually using structpci_host_bridgepointer other thanplatform_devicepointer. Further more if a new PLDA core PCIe driver do not selectPCI_HOST_COMMON, the platform driver data is not structpci_host_bridgepointer. So get structpci_host_bridgepointer from platform code functionmc_platform_init()and make it to be an argument ofplda_pcie_setup_iomems().Quoted 8 lines
Quoted 8 lines
OK, I see what you're doing. This actually has nothing to do with whether
PCI_HOST_COMMONis *enabled*. It has to do with whether drivers usepci_host_common_probe(). Here's what I propose:PCI: plda: Pass
pci_host_bridgetoplda_pcie_setup_iomems()
plda_pcie_setup_iomems()needs thebridge->windowslist from structpci_host_bridgeand is currently used only bypcie-microchip-host.c.This
Quoted 1 line
Quoted 1 line
driver uses
pci_host_common_probe(), which sets apci_host_bridgeasthe
Quoted 1 line
Quoted 1 line
drvdata, so
plda_pcie_setup_iomems()usedplatform_get_drvdata()tofind
Quoted 3 lines
Quoted 3 lines
the
pci_host_bridge.But we also want to use
plda_pcie_setup_iomems()in the new
pcie-starfive.cQuoted 3 lines
Quoted 3 lines
driver, which does not use
pci_host_common_probe()and will have structstarfive_jh7110_pcieas its drvdata, so pass thepci_host_bridgedirectly toplda_pcie_setup_iomems()so it doesn't needplatform_get_drvdata()to
Quoted 6 lines
Quoted 2 lines
find it.
OK, Thanks.
I see PCIe 6.10 changed have been merged to main line. Should I resend this patch set base on 6.10-rc1?
No need, I rebased it to
f0bae243b2bc("Merge tag 'pci-v6.10-changes' ofgit://git.kernel.org/pub/scm/linux/kernel/git/pci/pci") already and it will be a trivial rebase to v6.10-rc1 next week.
Quoted 6 lines
The current pci/controller/microchip branch is at:
https://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git/log/?h=ed261441e22
4
Let me know if anything is missing from there. I can't merge it into linux-next until v6.10-rc1 is tagged, but as soon as it is, I'll put it in linux-next.
I have checked the code and tested it with Starfive VisionFive v2 board, PCIe can work. All are Okay. Thanks for correct the commit message. It is more elegant.
This is precious experience of developing refactor code. Thank all!
Hi Conor
Thanks for help us for this patch set !
I see mars dts have been merged to mainline, this version dts patch can not be merged I will resend the dts patch on v6.10-rc1.
_______________________________________________
linux-riscv mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-riscv
Conor Dooley
maintainerRe: [PATCH v16 08/22] PCI: microchip: Change the argument of plda_pcie_setup_iomems()
Quoted 4 lines · Minda Chen
Hi Conor
Thanks for help us for this patch set !
I see mars dts have been merged to mainline, this version dts patch can not be merged I will resend the dts patch on v6.10-rc1.
No worries, the dts patches in this series are long gone out of patchwork anyway so I wouldn't have even tried to apply them ;)
Cheers,
Conor.
PATCH v16 9/22 PCI: microchip: Move setup functions to pcie-plda-host.c
In reply to Minda ChenMove setup functions to common pcie-plda-host.c. So these two functions can be re-used.
--- MAINTAINERS | 1 + drivers/pci/controller/plda/Kconfig | 4 + drivers/pci/controller/plda/Makefile | 1 + .../pci/controller/plda/pcie-microchip-host.c | 59 --------------- drivers/pci/controller/plda/pcie-plda-host.c | 73 +++++++++++++++++++ drivers/pci/controller/plda/pcie-plda.h | 5 ++ 6 files changed, 84 insertions(+), 59 deletions(-) create mode 100644 drivers/pci/controller/plda/pcie-plda-host.c
MAINTAINERS +1 -0
@@ -16951,6 +16951,7 @@ M: Daire McNamara <[email protected]> L: [email protected] 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
drivers/pci/controller/plda/Kconfig +4 -0
@@ -3,10 +3,14 @@ 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.
drivers/pci/controller/plda/Makefile +1 -0
@@ -1,2 +1,3 @@ # SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_PCIE_PLDA_HOST) += pcie-plda-host.o obj-$(CONFIG_PCIE_MICROCHIP_HOST) += pcie-microchip-host.o
drivers/pci/controller/plda/pcie-microchip-host.c +0 -59
65 lines not on this page · raw message
drivers/pci/controller/plda/pcie-plda-host.c new file +73 -0
73 lines not on this page · raw message
drivers/pci/controller/plda/pcie-plda.h +5 -0
@@ -126,4 +126,9 @@ struct plda_pcie_rp { void __iomem *bridge_addr; }; +void plda_pcie_setup_window (void __iomem *bridge_base_addr,u32 index, +phys_addr_t axi_addr,phys_addr_t pci_addr, +size_t size); +int plda_pcie_setup_iomems (struct pci_host_bridge *bridge, +struct plda_pcie_rp *port);#endif
Signature · 1 line
2.17.1
PATCH v16 10/22 PCI: microchip: Rename interrupt related functions
In reply to Minda ChenRename mc_* to plda_* for IRQ functions and related IRQ domain ops data instances.
MSI, INTx interrupt code and IRQ init code are all can be re-used.
--- .../pci/controller/plda/pcie-microchip-host.c | 109 +++++++++--------- 1 file changed, 57 insertions(+), 52 deletions(-)
drivers/pci/controller/plda/pcie-microchip-host.c +57 -52
@@ -318,7 +318,7 @@ 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) +static void plda_handle_msi (struct irq_desc *desc) {struct plda_pcie_rp *port =irq_desc_get_handler_data (desc);struct irq_chip *chip =irq_desc_get_chip (desc);
@@ -346,7 +346,7 @@ static void mc_handle_msi(struct irq_desc *desc)chained_irq_exit (chip, desc); } -static void mc_msi_bottom_irq_ack (struct irq_data *data) +static void plda_msi_bottom_irq_ack (struct irq_data *data) {struct plda_pcie_rp *port =irq_data_get_irq_chip_data (data);void __iomem *bridge_base_addr = port->bridge_addr;
@@ -355,7 +355,7 @@ static void mc_msi_bottom_irq_ack(struct irq_data *data)writel_relaxed (BIT (bitpos), bridge_base_addr +ISTATUS_MSI ); } -static void mc_compose_msi_msg (struct irq_data *data,struct msi_msg *msg) +static void plda_compose_msi_msg (struct irq_data *data,struct msi_msg *msg) {struct plda_pcie_rp *port =irq_data_get_irq_chip_data (data);phys_addr_t addr = port->msi.vector_phy;
@@ -368,21 +368,23 @@ static void mc_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) (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) +static int plda_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 struct irq_chip plda_msi_bottom_irq_chip = { + .name ="PLDA MSI" , + .irq_ack = plda_msi_bottom_irq_ack, + .irq_compose_msi_msg = plda_compose_msi_msg, + .irq_set_affinity = plda_msi_set_affinity, }; -static int mc_irq_msi_domain_alloc (struct irq_domain *domain,unsigned int virq, -unsigned int nr_irqs,void *args) +static int plda_irq_msi_domain_alloc (struct irq_domain *domain, +unsigned int virq, +unsigned int nr_irqs, +void *args) {struct plda_pcie_rp *port = domain->host_data;struct plda_msi *msi = &port->msi;
@@ -397,7 +399,7 @@ static int mc_irq_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,set_bit (bit, msi->used); -irq_domain_set_info (domain, virq, bit, &mc_msi_bottom_irq_chip, +irq_domain_set_info (domain, virq, bit, &plda_msi_bottom_irq_chip, domain->host_data, handle_edge_irq,NULL ,NULL );mutex_unlock (&msi->lock);
@@ -405,8 +407,9 @@ static int mc_irq_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,return 0 ; } -static void mc_irq_msi_domain_free (struct irq_domain *domain,unsigned int virq, -unsigned int nr_irqs) +static void plda_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 plda_pcie_rp *port =irq_data_get_irq_chip_data (d);
@@ -423,24 +426,24 @@ static void mc_irq_msi_domain_free(struct irq_domain *domain, unsigned int virq, }static const struct irq_domain_ops msi_domain_ops = { - .alloc = mc_irq_msi_domain_alloc, - .free = mc_irq_msi_domain_free, + .alloc = plda_irq_msi_domain_alloc, + .free = plda_irq_msi_domain_free, }; -static struct irq_chip mc_msi_irq_chip = { - .name ="Microchip PCIe MSI" , +static struct irq_chip plda_msi_irq_chip = { + .name ="PLDA 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 = { +static struct msi_domain_info plda_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, + .chip = &plda_msi_irq_chip, }; -static int mc_allocate_msi_domains (struct plda_pcie_rp *port) +static int plda_allocate_msi_domains (struct plda_pcie_rp *port) {struct device *dev = port->dev;struct fwnode_handle *fwnode =of_node_to_fwnode (dev->of_node);
@@ -455,7 +458,8 @@ static int mc_allocate_msi_domains(struct plda_pcie_rp *port)return -ENOMEM ; } - msi->msi_domain =pci_msi_create_irq_domain (fwnode, &mc_msi_domain_info, + msi->msi_domain =pci_msi_create_irq_domain (fwnode, + &plda_msi_domain_info, msi->dev_domain);if (!msi->msi_domain) {dev_err (dev,"failed to create MSI domain\n" );
@@ -466,7 +470,7 @@ static int mc_allocate_msi_domains(struct plda_pcie_rp *port)return 0 ; } -static void mc_handle_intx (struct irq_desc *desc) +static void plda_handle_intx (struct irq_desc *desc) {struct plda_pcie_rp *port =irq_desc_get_handler_data (desc);struct irq_chip *chip =irq_desc_get_chip (desc);
@@ -493,7 +497,7 @@ static void mc_handle_intx(struct irq_desc *desc)chained_irq_exit (chip, desc); } -static void mc_ack_intx_irq (struct irq_data *data) +static void plda_ack_intx_irq (struct irq_data *data) {struct plda_pcie_rp *port =irq_data_get_irq_chip_data (data);void __iomem *bridge_base_addr = port->bridge_addr;
@@ -502,7 +506,7 @@ static void mc_ack_intx_irq(struct irq_data *data)writel_relaxed (mask, bridge_base_addr +ISTATUS_LOCAL ); } -static void mc_mask_intx_irq (struct irq_data *data) +static void plda_mask_intx_irq (struct irq_data *data) {struct plda_pcie_rp *port =irq_data_get_irq_chip_data (data);void __iomem *bridge_base_addr = port->bridge_addr;
@@ -517,7 +521,7 @@ static void mc_mask_intx_irq(struct irq_data *data)raw_spin_unlock_irqrestore (&port->lock, flags); } -static void mc_unmask_intx_irq (struct irq_data *data) +static void plda_unmask_intx_irq (struct irq_data *data) {struct plda_pcie_rp *port =irq_data_get_irq_chip_data (data);void __iomem *bridge_base_addr = port->bridge_addr;
@@ -532,24 +536,24 @@ static void mc_unmask_intx_irq(struct irq_data *data)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 struct irq_chip plda_intx_irq_chip = { + .name ="PLDA PCIe INTx" , + .irq_ack = plda_ack_intx_irq, + .irq_mask = plda_mask_intx_irq, + .irq_unmask = plda_unmask_intx_irq, }; -static int mc_pcie_intx_map (struct irq_domain *domain,unsigned int irq, -irq_hw_number_t hwirq) +static int plda_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_and_handler (irq, &plda_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, + .map = plda_pcie_intx_map, };static inline u32 reg_to_event (u32 reg,struct event_map field)
@@ -609,7 +613,7 @@ static u32 local_events(struct mc_pcie *port)return val; } -static u32 get_events (struct plda_pcie_rp *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 ;
@@ -638,7 +642,7 @@ static irqreturn_t mc_event_handler(int irq, void *dev_id)return IRQ_HANDLED ; } -static void mc_handle_event (struct irq_desc *desc) +static void plda_handle_event (struct irq_desc *desc) {struct plda_pcie_rp *port =irq_desc_get_handler_data (desc);unsigned long events;
@@ -647,7 +651,7 @@ static void mc_handle_event(struct irq_desc *desc)chained_irq_enter (chip, desc); - events =get_events (port); + events =mc_get_events (port);for_each_set_bit (bit, &events,NUM_EVENTS )generic_handle_domain_irq (port->event_domain, bit);
@@ -741,8 +745,8 @@ static struct irq_chip mc_event_irq_chip = { .irq_unmask = mc_unmask_event_irq, }; -static int mc_pcie_event_map (struct irq_domain *domain,unsigned int irq, -irq_hw_number_t hwirq) +static int plda_pcie_event_map (struct irq_domain *domain,unsigned int irq, +irq_hw_number_t hwirq) {irq_set_chip_and_handler (irq, &mc_event_irq_chip, handle_level_irq);irq_set_chip_data (irq, domain->host_data);
@@ -750,8 +754,8 @@ static int mc_pcie_event_map(struct irq_domain *domain, unsigned int irq,return 0 ; } -static const struct irq_domain_ops event_domain_ops = { - .map = mc_pcie_event_map, +static const struct irq_domain_ops plda_event_domain_ops = { + .map = plda_pcie_event_map, };static inline void mc_pcie_deinit_clk (void *data)
@@ -799,7 +803,7 @@ static int mc_pcie_init_clks(struct device *dev)return 0 ; } -static int mc_pcie_init_irq_domains (struct plda_pcie_rp *port) +static int plda_pcie_init_irq_domains (struct plda_pcie_rp *port) {struct device *dev = port->dev;struct device_node *node = dev->of_node;
@@ -813,7 +817,8 @@ static int mc_pcie_init_irq_domains(struct plda_pcie_rp *port) } port->event_domain =irq_domain_add_linear (pcie_intc_node,NUM_EVENTS , - &event_domain_ops, port); + &plda_event_domain_ops, + port);if (!port->event_domain) {dev_err (dev,"failed to get event domain\n" );of_node_put (pcie_intc_node);
@@ -835,7 +840,7 @@ static int mc_pcie_init_irq_domains(struct plda_pcie_rp *port)of_node_put (pcie_intc_node);raw_spin_lock_init (&port->lock); -return mc_allocate_msi_domains (port); +return plda_allocate_msi_domains (port); }static inline void mc_clear_secs (struct mc_pcie *port)
@@ -898,14 +903,14 @@ static void mc_disable_interrupts(struct mc_pcie *port)writel_relaxed (GENMASK (31 ,0 ), bridge_base_addr +ISTATUS_HOST ); } -static int mc_init_interrupts (struct platform_device *pdev,struct plda_pcie_rp *port) +static int plda_init_interrupts (struct platform_device *pdev,struct plda_pcie_rp *port) {struct device *dev = &pdev->dev;int irq;int i, intx_irq, msi_irq, event_irq;int ret; - ret =mc_pcie_init_irq_domains (port); + ret =plda_pcie_init_irq_domains (port);if (ret) {dev_err (dev,"failed creating IRQ domains\n" );return ret;
@@ -938,7 +943,7 @@ static int mc_init_interrupts(struct platform_device *pdev, struct plda_pcie_rp }/* Plug the INTx chained handler */ -irq_set_chained_handler_and_data (intx_irq, mc_handle_intx, port); +irq_set_chained_handler_and_data (intx_irq, plda_handle_intx, port); msi_irq =irq_create_mapping (port->event_domain,EVENT_LOCAL_PM_MSI_INT_MSI );
@@ -946,10 +951,10 @@ static int mc_init_interrupts(struct platform_device *pdev, struct plda_pcie_rpreturn -ENXIO ;/* Plug the MSI chained handler */ -irq_set_chained_handler_and_data (msi_irq, mc_handle_msi, port); +irq_set_chained_handler_and_data (msi_irq, plda_handle_msi, port);/* Plug the main event chained handler */ -irq_set_chained_handler_and_data (irq, mc_handle_event, port); +irq_set_chained_handler_and_data (irq, plda_handle_event, port);return 0 ; }
@@ -977,7 +982,7 @@ static int mc_platform_init(struct pci_config_window *cfg)return ret;/* Address translation is up; safe to enable interrupts */ - ret =mc_init_interrupts (pdev, &port->plda); + ret =plda_init_interrupts (pdev, &port->plda);if (ret)return ret;
Signature · 1 line
2.17.1
PATCH v16 11/22 PCI: microchip: Add num_events field to struct plda_pcie_rp
In reply to Minda ChenThe number of events is different across platforms. In order to share interrupt processing code, add a variable that defines the number of events so that it can be set per-platform instead of hardcoding it.
--- drivers/pci/controller/plda/pcie-microchip-host.c | 8 +++++--- drivers/pci/controller/plda/pcie-plda.h | 1 + 2 files changed, 6 insertions(+), 3 deletions(-)
drivers/pci/controller/plda/pcie-microchip-host.c +5 -3
@@ -653,7 +653,7 @@ static void plda_handle_event(struct irq_desc *desc) events =mc_get_events (port); -for_each_set_bit (bit, &events,NUM_EVENTS ) +for_each_set_bit (bit, &events, port->num_events)generic_handle_domain_irq (port->event_domain, bit);chained_irq_exit (chip, desc);
@@ -816,7 +816,8 @@ static int plda_pcie_init_irq_domains(struct plda_pcie_rp *port)return -EINVAL ; } - port->event_domain =irq_domain_add_linear (pcie_intc_node,NUM_EVENTS , + port->event_domain =irq_domain_add_linear (pcie_intc_node, + port->num_events, &plda_event_domain_ops, port);if (!port->event_domain) {
@@ -920,7 +921,7 @@ static int plda_init_interrupts(struct platform_device *pdev, struct plda_pcie_rif (irq <0 )return -ENODEV ; -for (i =0 ; i <NUM_EVENTS ; i++) { +for (i =0 ; i < port->num_events; i++) { event_irq =irq_create_mapping (port->event_domain, i);if (!event_irq) {dev_err (dev,"failed to map hwirq %d\n" , i);
@@ -1012,6 +1013,7 @@ static int mc_host_probe(struct platform_device *pdev) bridge_base_addr = port->axi_base_addr +MC_PCIE_BRIDGE_ADDR ; plda->bridge_addr = bridge_base_addr; + plda->num_events =NUM_EVENTS ;/* Allow enabling MSI by disabling MSI-X */ val =readl (bridge_base_addr +PCIE_PCI_IRQ_DW0 );
drivers/pci/controller/plda/pcie-plda.h +1 -0
@@ -124,6 +124,7 @@ struct plda_pcie_rp {raw_spinlock_t lock;struct plda_msi msi;void __iomem *bridge_addr; +int num_events; }; void plda_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,
Signature · 1 line
2.17.1
PATCH v16 12/22 PCI: microchip: Add request_event_irq() callback function
In reply to Minda ChenAs PLDA dts binding doc(Documentation/devicetree/bindings/pci/ plda,xpressrich3-axi-common.yaml) showed, PLDA PCIe contains an interrupt controller. Microchip Polarfire PCIe add some PCIe interrupts base on PLDA interrupt controller.
Microchip Polarfire PCIe additional intrerrupts:
(defined in drivers/pci/controller/plda/pcie-microchip-host.c) EVENT_PCIE_L2_EXITEVENT_PCIE_HOTRST_EXITEVENT_PCIE_DLUP_EXITEVENT_SEC_TX_RAM_SEC_ERREVENT_SEC_RX_RAM_SEC_ERR
....
Both code of request interrupts and mc_event_handler() contain additional interrupts symbol names, these can not be re-used. So add a new plda_event_handler() functions, which implements PLDA interrupt defalt handler, add request_event_irq() callback function to compat Microchip Polorfire PCIe additional interrupts.
--- .../pci/controller/plda/pcie-microchip-host.c | 31 ++++++++++++++++--- drivers/pci/controller/plda/pcie-plda.h | 5 +++ 2 files changed, 32 insertions(+), 4 deletions(-)
drivers/pci/controller/plda/pcie-microchip-host.c +27 -4
@@ -642,6 +642,11 @@ static irqreturn_t mc_event_handler(int irq, void *dev_id)return IRQ_HANDLED ; } +static irqreturn_t plda_event_handler (int irq,void *dev_id) +{ +return IRQ_HANDLED ; +} +static void plda_handle_event (struct irq_desc *desc) {struct plda_pcie_rp *port =irq_desc_get_handler_data (desc);
@@ -803,6 +808,17 @@ static int mc_pcie_init_clks(struct device *dev)return 0 ; } +static int mc_request_event_irq (struct plda_pcie_rp *plda,int event_irq, +int event) +{ +return devm_request_irq (plda->dev, event_irq, mc_event_handler, +0 , event_cause[event].sym, plda); +} + +static const struct plda_event mc_event = { + .request_event_irq = mc_request_event_irq, +}; +static int plda_pcie_init_irq_domains (struct plda_pcie_rp *port) {struct device *dev = port->dev;
@@ -904,7 +920,9 @@ static void mc_disable_interrupts(struct mc_pcie *port)writel_relaxed (GENMASK (31 ,0 ), bridge_base_addr +ISTATUS_HOST ); } -static int plda_init_interrupts (struct platform_device *pdev,struct plda_pcie_rp *port) +static int plda_init_interrupts (struct platform_device *pdev, +struct plda_pcie_rp *port, +const struct plda_event *event) {struct device *dev = &pdev->dev;int irq;
@@ -928,8 +946,13 @@ static int plda_init_interrupts(struct platform_device *pdev, struct plda_pcie_rreturn -ENXIO ; } - ret =devm_request_irq (dev, event_irq, mc_event_handler, -0 , event_cause[i].sym, port); +if (event->request_event_irq) + ret = event->request_event_irq (port, event_irq, i); +else + ret =devm_request_irq (dev, event_irq, + plda_event_handler, +0 ,NULL , port); +if (ret) {dev_err (dev,"failed to request IRQ %d\n" , event_irq);return ret;
@@ -983,7 +1006,7 @@ static int mc_platform_init(struct pci_config_window *cfg)return ret;/* Address translation is up; safe to enable interrupts */ - ret =plda_init_interrupts (pdev, &port->plda); + ret =plda_init_interrupts (pdev, &port->plda, &mc_event);if (ret)return ret;
drivers/pci/controller/plda/pcie-plda.h +5 -0
@@ -127,6 +127,11 @@ struct plda_pcie_rp {int num_events; }; +struct plda_event { +int (*request_event_irq)(struct plda_pcie_rp *pcie, +int event_irq,int event); +}; +void plda_pcie_setup_window (void __iomem *bridge_base_addr,u32 index,phys_addr_t axi_addr,phys_addr_t pci_addr,size_t size);
Signature · 1 line
2.17.1
PATCH v16 13/22 PCI: microchip: Add INTx and MSI event num to struct plda_event
In reply to Minda ChenThe INTx and MSI interrupt event num is different across platforms, so add two event num fields in struct plda_event.
--- drivers/pci/controller/plda/pcie-microchip-host.c | 6 ++++-- drivers/pci/controller/plda/pcie-plda.h | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-)
drivers/pci/controller/plda/pcie-microchip-host.c +4 -2
@@ -817,6 +817,8 @@ static int mc_request_event_irq(struct plda_pcie_rp *plda, int event_irq,static const struct plda_event mc_event = { .request_event_irq = mc_request_event_irq, + .intx_event =EVENT_LOCAL_PM_MSI_INT_INTX , + .msi_event =EVENT_LOCAL_PM_MSI_INT_MSI , };static int plda_pcie_init_irq_domains (struct plda_pcie_rp *port)
@@ -960,7 +962,7 @@ static int plda_init_interrupts(struct platform_device *pdev, } intx_irq =irq_create_mapping (port->event_domain, -EVENT_LOCAL_PM_MSI_INT_INTX ); + event->intx_event);if (!intx_irq) {dev_err (dev,"failed to map INTx interrupt\n" );return -ENXIO ;
@@ -970,7 +972,7 @@ static int plda_init_interrupts(struct platform_device *pdev,irq_set_chained_handler_and_data (intx_irq, plda_handle_intx, port); msi_irq =irq_create_mapping (port->event_domain, -EVENT_LOCAL_PM_MSI_INT_MSI ); + event->msi_event);if (!msi_irq)return -ENXIO ;
drivers/pci/controller/plda/pcie-plda.h +2 -0
@@ -130,6 +130,8 @@ struct plda_pcie_rp {struct plda_event {int (*request_event_irq)(struct plda_pcie_rp *pcie,int event_irq,int event); +int intx_event; +int msi_event; }; void plda_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,
Signature · 1 line
2.17.1
PATCH v16 14/22 PCI: microchip: Add get_events() callback and add PLDA get_event()
In reply to Minda ChenAs PLDA dts binding doc(Documentation/devicetree/bindings/pci/ plda,xpressrich3-axi-common.yaml) showed, PLDA PCIe contains an interrupt controller.
PolarFire implements its own PCIe interrupts, additional to the regular PCIe interrupts, due to lack of an MSI controller, so the interrupt to event number mapping is different to the PLDA regular interrupts, necessitating a custom get_events() implementation.
Microchip Polarfire PCIe additional intrerrupts:
(defined in drivers/pci/controller/plda/pcie-microchip-host.c) EVENT_PCIE_L2_EXITEVENT_PCIE_HOTRST_EXITEVENT_PCIE_DLUP_EXITEVENT_SEC_TX_RAM_SEC_ERREVENT_SEC_RX_RAM_SEC_ERR
....
plda_get_events() adds interrupt register to PLDA event num mapping codes. All The PLDA interrupts can be seen in new added graph.
--- .../pci/controller/plda/pcie-microchip-host.c | 35 ++++++++++++++++++- drivers/pci/controller/plda/pcie-plda.h | 32 +++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-)
drivers/pci/controller/plda/pcie-microchip-host.c +34 -1
@@ -626,6 +626,26 @@ static u32 mc_get_events(struct plda_pcie_rp *port)return events; } +static u32 plda_get_events (struct plda_pcie_rp *port) +{ +u32 events, val, origin; + + origin =readl_relaxed (port->bridge_addr +ISTATUS_LOCAL ); + +/* MSI event and sys events */ + val = (origin &SYS_AND_MSI_MASK ) >>PM_MSI_INT_MSI_SHIFT ; + events = val << (PM_MSI_INT_MSI_SHIFT -PCI_NUM_INTX +1 ); + +/* INTx events */ +if (origin &PM_MSI_INT_INTX_MASK ) + events |=BIT (PM_MSI_INT_INTX_SHIFT ); + +/* remains are same with register */ + events |= origin &GENMASK (P_ATR_EVT_DOORBELL_SHIFT ,0 ); + +return events; +} +static irqreturn_t mc_event_handler (int irq,void *dev_id) {struct plda_pcie_rp *port = dev_id;
@@ -656,7 +676,7 @@ static void plda_handle_event(struct irq_desc *desc)chained_irq_enter (chip, desc); - events =mc_get_events (port); + events = port->event_ops->get_events (port);for_each_set_bit (bit, &events, port->num_events)generic_handle_domain_irq (port->event_domain, bit);
@@ -750,6 +770,10 @@ static struct irq_chip mc_event_irq_chip = { .irq_unmask = mc_unmask_event_irq, }; +static const struct plda_event_ops plda_event_ops = { + .get_events = plda_get_events, +}; +static int plda_pcie_event_map (struct irq_domain *domain,unsigned int irq,irq_hw_number_t hwirq) {
@@ -815,6 +839,10 @@ static int mc_request_event_irq(struct plda_pcie_rp *plda, int event_irq, 0, event_cause[event].sym, plda); } +static const struct plda_event_ops mc_event_ops = { + .get_events = mc_get_events, +}; +static const struct plda_event mc_event = { .request_event_irq = mc_request_event_irq, .intx_event =EVENT_LOCAL_PM_MSI_INT_INTX ,
@@ -931,6 +959,9 @@ static int plda_init_interrupts(struct platform_device *pdev,int i, intx_irq, msi_irq, event_irq;int ret; +if (!port->event_ops) + port->event_ops = &plda_event_ops; + ret =plda_pcie_init_irq_domains (port);if (ret) {dev_err (dev,"failed creating IRQ domains\n" );
@@ -1007,6 +1038,8 @@ static int mc_platform_init(struct pci_config_window *cfg)if (ret)return ret; + port->plda.event_ops = &mc_event_ops; +/* Address translation is up; safe to enable interrupts */ ret =plda_init_interrupts (pdev, &port->plda, &mc_event);if (ret)
drivers/pci/controller/plda/pcie-plda.h +32 -0
@@ -58,6 +58,7 @@#define PM_MSI_INT_EVENTS_SHIFT 30#define PM_MSI_INT_SYS_ERR_MASK 0x80000000u#define PM_MSI_INT_SYS_ERR_SHIFT 31 +#define SYS_AND_MSI_MASK GENMASK(31, 28)#define NUM_LOCAL_EVENTS 15#define ISTATUS_LOCAL 0x184#define IMASK_HOST 0x188
@@ -108,6 +109,36 @@ enum plda_int_event {#define PLDA_MAX_EVENT_NUM (PLDA_NUM_DMA_EVENTS + PLDA_INT_EVENT_NUM) +/* +* PLDA interrupt register +* +* 31 27 23 15 7 0 +* +--+--+--+-+------+-+-+-+-+-+-+-+-+-----------+-----------+ +* |12|11|10|9| intx |7|6|5|4|3|2|1|0| DMA error | DMA end | +* +--+--+--+-+------+-+-+-+-+-+-+-+-+-----------+-----------+ +* bit 0-7 DMA interrupt end : reserved for vendor implement +* bit 8-15 DMA error : reserved for vendor implement +* 0: AXI post error (PLDA_AXI_POST_ERR) +* 1: AXI fetch error (PLDA_AXI_FETCH_ERR) +* 2: AXI discard error (PLDA_AXI_DISCARD_ERR) +* 3: AXI doorbell (PLDA_PCIE_DOORBELL) +* 4: PCIe post error (PLDA_PCIE_POST_ERR) +* 5: PCIe fetch error (PLDA_PCIE_FETCH_ERR) +* 6: PCIe discard error (PLDA_PCIE_DISCARD_ERR) +* 7: PCIe doorbell (PLDA_PCIE_DOORBELL) +* 8: 4 INTx interruts (PLDA_INTX) +* 9: MSI interrupt (PLDA_MSI) +* 10: AER event (PLDA_AER_EVENT) +* 11: PM/LTR/Hotplug (PLDA_MISC_EVENTS) +* 12: System error (PLDA_SYS_ERR) +*/ + +struct plda_pcie_rp ; + +struct plda_event_ops { +u32 (*get_events)(struct plda_pcie_rp *pcie); +}; +struct plda_msi {struct mutex lock;/* Protect used bitmap */ struct irq_domain *msi_domain;
@@ -123,6 +154,7 @@ struct plda_pcie_rp {struct irq_domain *event_domain;raw_spinlock_t lock;struct plda_msi msi; +const struct plda_event_ops *event_ops;void __iomem *bridge_addr;int num_events; };
Signature · 1 line
2.17.1
PATCH v16 15/22 PCI: microchip: Add event irqchip field to host port and add PLDA irqchip
In reply to Minda ChenAs PLDA dts binding doc(Documentation/devicetree/bindings/pci/ plda,xpressrich3-axi-common.yaml) showed, PLDA PCIe contains an interrupt controller.
Microchip PolarFire PCIE event IRQs includes PLDA interrupts and Polarfire additional interrupts. The interrupt irqchip ops includes ack/mask/unmask interrupt ops, which will write correct registers. Microchip Polarfire PCIe additional interrupts require to write Polarfire SoC self-defined registers. So Microchip PCIe event irqchip ops can not be re-used.
Microchip Polarfire PCIe additional intrerrupts:
(defined in drivers/pci/controller/plda/pcie-microchip-host.c) EVENT_PCIE_L2_EXITEVENT_PCIE_HOTRST_EXITEVENT_PCIE_DLUP_EXITEVENT_SEC_TX_RAM_SEC_ERREVENT_SEC_RX_RAM_SEC_ERR
....
To support PLDA its own event IRQ process, implements PLDA irqchip ops and add event irqchip field to struct pcie_plda_rp.
--- .../pci/controller/plda/pcie-microchip-host.c | 66 ++++++++++++++++++- drivers/pci/controller/plda/pcie-plda.h | 34 +++++----- 2 files changed, 84 insertions(+), 16 deletions(-)
drivers/pci/controller/plda/pcie-microchip-host.c +65 -1
@@ -770,6 +770,64 @@ static struct irq_chip mc_event_irq_chip = { .irq_unmask = mc_unmask_event_irq, }; +static u32 plda_hwirq_to_mask (int hwirq) +{ +u32 mask; + +/* hwirq 23 - 0 are the same with register */ +if (hwirq <EVENT_PM_MSI_INT_INTX ) + mask =BIT (hwirq); +else if (hwirq ==EVENT_PM_MSI_INT_INTX ) + mask =PM_MSI_INT_INTX_MASK ; +else + mask =BIT (hwirq +PCI_NUM_INTX -1 ); + +return mask; +} + +static void plda_ack_event_irq (struct irq_data *data) +{ +struct plda_pcie_rp *port =irq_data_get_irq_chip_data (data); + +writel_relaxed (plda_hwirq_to_mask (data->hwirq), + port->bridge_addr +ISTATUS_LOCAL ); +} + +static void plda_mask_event_irq (struct irq_data *data) +{ +struct plda_pcie_rp *port =irq_data_get_irq_chip_data (data); +u32 mask, val; + + mask =plda_hwirq_to_mask (data->hwirq); + +raw_spin_lock (&port->lock); + val =readl_relaxed (port->bridge_addr +IMASK_LOCAL ); + val &= ~mask; +writel_relaxed (val, port->bridge_addr +IMASK_LOCAL ); +raw_spin_unlock (&port->lock); +} + +static void plda_unmask_event_irq (struct irq_data *data) +{ +struct plda_pcie_rp *port =irq_data_get_irq_chip_data (data); +u32 mask, val; + + mask =plda_hwirq_to_mask (data->hwirq); + +raw_spin_lock (&port->lock); + val =readl_relaxed (port->bridge_addr +IMASK_LOCAL ); + val |= mask; +writel_relaxed (val, port->bridge_addr +IMASK_LOCAL ); +raw_spin_unlock (&port->lock); +} + +static struct irq_chip plda_event_irq_chip = { + .name ="PLDA PCIe EVENT" , + .irq_ack = plda_ack_event_irq, + .irq_mask = plda_mask_event_irq, + .irq_unmask = plda_unmask_event_irq, +}; +static const struct plda_event_ops plda_event_ops = { .get_events = plda_get_events, };
@@ -777,7 +835,9 @@ static const struct plda_event_ops plda_event_ops = {static int plda_pcie_event_map (struct irq_domain *domain,unsigned int irq,irq_hw_number_t hwirq) { -irq_set_chip_and_handler (irq, &mc_event_irq_chip, handle_level_irq); +struct plda_pcie_rp *port = (void *)domain->host_data; + +irq_set_chip_and_handler (irq, port->event_irq_chip, handle_level_irq);irq_set_chip_data (irq, domain->host_data);return 0 ;
@@ -962,6 +1022,9 @@ static int plda_init_interrupts(struct platform_device *pdev,if (!port->event_ops) port->event_ops = &plda_event_ops; +if (!port->event_irq_chip) + port->event_irq_chip = &plda_event_irq_chip; + ret =plda_pcie_init_irq_domains (port);if (ret) {dev_err (dev,"failed creating IRQ domains\n" );
@@ -1039,6 +1102,7 @@ static int mc_platform_init(struct pci_config_window *cfg)return ret; port->plda.event_ops = &mc_event_ops; + port->plda.event_irq_chip = &mc_event_irq_chip;/* Address translation is up; safe to enable interrupts */ ret =plda_init_interrupts (pdev, &port->plda, &mc_event);
drivers/pci/controller/plda/pcie-plda.h +19 -15
@@ -107,6 +107,8 @@ enum plda_int_event {#define PLDA_NUM_DMA_EVENTS 16 +#define EVENT_PM_MSI_INT_INTX (PLDA_NUM_DMA_EVENTS + PLDA_INTX) +#define EVENT_PM_MSI_INT_MSI (PLDA_NUM_DMA_EVENTS + PLDA_MSI)#define PLDA_MAX_EVENT_NUM (PLDA_NUM_DMA_EVENTS + PLDA_INT_EVENT_NUM)/*
@@ -116,21 +118,22 @@ enum plda_int_event {* +--+--+--+-+------+-+-+-+-+-+-+-+-+-----------+-----------+ * |12|11|10|9| intx |7|6|5|4|3|2|1|0| DMA error | DMA end | * +--+--+--+-+------+-+-+-+-+-+-+-+-+-----------+-----------+ -* bit 0-7 DMA interrupt end : reserved for vendor implement -* bit 8-15 DMA error : reserved for vendor implement -* 0: AXI post error (PLDA_AXI_POST_ERR) -* 1: AXI fetch error (PLDA_AXI_FETCH_ERR) -* 2: AXI discard error (PLDA_AXI_DISCARD_ERR) -* 3: AXI doorbell (PLDA_PCIE_DOORBELL) -* 4: PCIe post error (PLDA_PCIE_POST_ERR) -* 5: PCIe fetch error (PLDA_PCIE_FETCH_ERR) -* 6: PCIe discard error (PLDA_PCIE_DISCARD_ERR) -* 7: PCIe doorbell (PLDA_PCIE_DOORBELL) -* 8: 4 INTx interruts (PLDA_INTX) -* 9: MSI interrupt (PLDA_MSI) -* 10: AER event (PLDA_AER_EVENT) -* 11: PM/LTR/Hotplug (PLDA_MISC_EVENTS) -* 12: System error (PLDA_SYS_ERR) +* event bit +* 0-7 (0-7) DMA interrupt end : reserved for vendor implement +* 8-15 (8-15) DMA error : reserved for vendor implement +* 16 (16) AXI post error (PLDA_AXI_POST_ERR) +* 17 (17) AXI fetch error (PLDA_AXI_FETCH_ERR) +* 18 (18) AXI discard error (PLDA_AXI_DISCARD_ERR) +* 19 (19) AXI doorbell (PLDA_PCIE_DOORBELL) +* 20 (20) PCIe post error (PLDA_PCIE_POST_ERR) +* 21 (21) PCIe fetch error (PLDA_PCIE_FETCH_ERR) +* 22 (22) PCIe discard error (PLDA_PCIE_DISCARD_ERR) +* 23 (23) PCIe doorbell (PLDA_PCIE_DOORBELL) +* 24 (27-24) INTx interruts (PLDA_INTX) +* 25 (28): MSI interrupt (PLDA_MSI) +* 26 (29): AER event (PLDA_AER_EVENT) +* 27 (30): PM/LTR/Hotplug (PLDA_MISC_EVENTS) +* 28 (31): System error (PLDA_SYS_ERR) */ struct plda_pcie_rp ;
@@ -155,6 +158,7 @@ struct plda_pcie_rp {raw_spinlock_t lock;struct plda_msi msi;const struct plda_event_ops *event_ops; +const struct irq_chip *event_irq_chip;void __iomem *bridge_addr;int num_events; };
Signature · 1 line
2.17.1
Re: [PATCH v16 15/22] PCI: microchip: Add event irqchip field to host port and add PLDA irqchip
Quoted 21 lines
As PLDA dts binding
doc(Documentation/devicetree/bindings/pci/ plda,xpressrich3-axi-common.yaml)showed, PLDA PCIe contains an interrupt controller.Microchip PolarFire PCIE event IRQs includes PLDA interrupts and Polarfire additional interrupts. The interrupt irqchip ops includes ack/mask/unmask interrupt ops, which will write correct registers.
Microchip Polarfire PCIe additional interrupts require to write Polarfire SoC self-defined registers. So Microchip PCIe event irqchip ops can not be re-used.Microchip Polarfire PCIe additional intrerrupts:
(defined indrivers/pci/controller/plda/pcie-microchip-host.c)EVENT_PCIE_L2_EXITEVENT_PCIE_HOTRST_EXITEVENT_PCIE_DLUP_EXITEVENT_SEC_TX_RAM_SEC_ERREVENT_SEC_RX_RAM_SEC_ERR
....
Quoted 3 lines
To support PLDA its own event IRQ process, implements PLDA irqchip ops and add event irqchip field to struct
pcie_plda_rp.
Hi Thomas
Could you review this patch? Thanks.
Quoted 167 lines
Signed-off-by Minda Chen <[email protected]>Acked-by Conor Dooley <[email protected]>--- .../pci/controller/plda/pcie-microchip-host.c | 66 ++++++++++++++++++- drivers/pci/controller/plda/pcie-plda.h | 34 +++++----- 2 files changed, 84 insertions(+), 16 deletions(-)drivers/pci/controller/plda/pcie-microchip-host.c +59
-1@@ -770,6 +770,64 @@ static struct irq_chip mc_event_irq_chip = { .irq_unmask = mc_unmask_event_irq, }; +static u32 plda_hwirq_to_mask (int hwirq) { +u32 mask; + +/* hwirq 23 - 0 are the same with register */ +if (hwirq <EVENT_PM_MSI_INT_INTX ) + mask =BIT (hwirq); +else if (hwirq ==EVENT_PM_MSI_INT_INTX ) + mask =PM_MSI_INT_INTX_MASK ; +else + mask =BIT (hwirq +PCI_NUM_INTX -1 ); + +return mask; +} + +static void plda_ack_event_irq (struct irq_data *data) { +struct plda_pcie_rp *port =irq_data_get_irq_chip_data (data); + +writel_relaxed (plda_hwirq_to_mask (data->hwirq), + port->bridge_addr +ISTATUS_LOCAL ); } + +static void plda_mask_event_irq (struct irq_data *data) { +struct plda_pcie_rp *port =irq_data_get_irq_chip_data (data); +u32 mask, val; + + mask =plda_hwirq_to_mask (data->hwirq); + +raw_spin_lock (&port->lock); + val =readl_relaxed (port->bridge_addr +IMASK_LOCAL ); + val &= ~mask; +writel_relaxed (val, port->bridge_addr +IMASK_LOCAL ); +raw_spin_unlock (&port->lock); +} + +static void plda_unmask_event_irq (struct irq_data *data) { +struct plda_pcie_rp *port =irq_data_get_irq_chip_data (data); +u32 mask, val; + + mask =plda_hwirq_to_mask (data->hwirq); + +raw_spin_lock (&port->lock); + val =readl_relaxed (port->bridge_addr +IMASK_LOCAL ); + val |= mask; +writel_relaxed (val, port->bridge_addr +IMASK_LOCAL ); +raw_spin_unlock (&port->lock); +} + +static struct irq_chip plda_event_irq_chip = { + .name ="PLDA PCIe EVENT" , + .irq_ack = plda_ack_event_irq, + .irq_mask = plda_mask_event_irq, + .irq_unmask = plda_unmask_event_irq, +}; +static const struct plda_event_ops plda_event_ops = { .get_events = plda_get_events, };@@ -777,7 +835,9 @@ static const struct plda_event_ops plda_event_ops = {static int plda_pcie_event_map (struct irq_domain *domain,unsigned int irq,irq_hw_number_t hwirq) { -irq_set_chip_and_handler (irq, &mc_event_irq_chip, handle_level_irq); +struct plda_pcie_rp *port = (void *)domain->host_data; + +irq_set_chip_and_handler (irq, port->event_irq_chip, handle_level_irq);irq_set_chip_data (irq, domain->host_data);return 0 ;@@ -962,6 +1022,9 @@ static int plda_init_interrupts(struct platform_device *pdev, if (!port->event_ops) port->event_ops = &plda_event_ops; +if (!port->event_irq_chip) + port->event_irq_chip = &plda_event_irq_chip; + ret =plda_pcie_init_irq_domains (port);if (ret) {
dev_err(dev, "failed creating IRQ domains\n"); @@ -1039,6 +1102,7
@@ static intmc_platform_init(struct pci_config_window *cfg)drivers/pci/controller/plda/pcie-microchip-host.c +1
-0return ret; port->plda.event_ops = &mc_event_ops; + port->plda.event_irq_chip = &mc_event_irq_chip;/* Address translation is up; safe to enable interrupts */ ret = plda_init_interrupts(pdev, &port->plda, &mc_event); diff --git
a/drivers/pci/controller/plda/pcie-plda.hb/drivers/pci/controller/plda/pcie-plda.h
indexe0e5e7cc8434..0e5157eb3a32100644drivers/pci/controller/plda/pcie-plda.h +2
-0@@ -107,6 +107,8 @@ enum plda_int_event {#define PLDA_NUM_DMA_EVENTS 16 +#define EVENT_PM_MSI_INT_INTX (PLDA_NUM_DMA_EVENTS + PLDA_INTX) +#define EVENT_PM_MSI_INT_MSI (PLDA_NUM_DMA_EVENTS + PLDA_MSI)#define PLDA_MAX_EVENT_NUM (PLDA_NUM_DMA_EVENTS +
PLDA_INT_EVENT_NUM)/*
drivers/pci/controller/plda/pcie-plda.h +17
-16@@ -116,21 +118,22 @@ enum plda_int_event {* +--+--+--+-+------+-+-+-+-+-+-+-+-+-----------+-----------+ * |12|11|10|9| intx |7|6|5|4|3|2|1|0| DMA error | DMA end | * +--+--+--+-+------+-+-+-+-+-+-+-+-+-----------+-----------+ -* bit 0-7 DMA interrupt end : reserved for vendor implement -* bit 8-15 DMA error : reserved for vendor implement -* 0: AXI post error (PLDA_AXI_POST_ERR) -* 1: AXI fetch error (PLDA_AXI_FETCH_ERR) -* 2: AXI discard error (PLDA_AXI_DISCARD_ERR) -* 3: AXI doorbell (PLDA_PCIE_DOORBELL) -* 4: PCIe post error (PLDA_PCIE_POST_ERR) -* 5: PCIe fetch error (PLDA_PCIE_FETCH_ERR) -* 6: PCIe discard error (PLDA_PCIE_DISCARD_ERR) -* 7: PCIe doorbell (PLDA_PCIE_DOORBELL) -* 8: 4 INTx interruts (PLDA_INTX) -* 9: MSI interrupt (PLDA_MSI) -* 10: AER event (PLDA_AER_EVENT) -* 11: PM/LTR/Hotplug (PLDA_MISC_EVENTS) -* 12: System error (PLDA_SYS_ERR) +* event bit +* 0-7 (0-7) DMA interrupt end : reserved for vendor implement +* 8-15 (8-15) DMA error : reserved for vendor implement +* 16 (16) AXI post error (PLDA_AXI_POST_ERR) +* 17 (17) AXI fetch error (PLDA_AXI_FETCH_ERR) +* 18 (18) AXI discard error (PLDA_AXI_DISCARD_ERR) +* 19 (19) AXI doorbell (PLDA_PCIE_DOORBELL) +* 20 (20) PCIe post error (PLDA_PCIE_POST_ERR) +* 21 (21) PCIe fetch error (PLDA_PCIE_FETCH_ERR) +* 22 (22) PCIe discard error (PLDA_PCIE_DISCARD_ERR) +* 23 (23) PCIe doorbell (PLDA_PCIE_DOORBELL) +* 24 (27-24) INTx interruts (PLDA_INTX) +* 25 (28): MSI interrupt (PLDA_MSI) +* 26 (29): AER event (PLDA_AER_EVENT) +* 27 (30): PM/LTR/Hotplug (PLDA_MISC_EVENTS) +* 28 (31): System error (PLDA_SYS_ERR) */ struct plda_pcie_rp ;@@ -155,6 +158,7 @@ struct plda_pcie_rp {raw_spinlock_t lock;struct plda_msi msi;const struct plda_event_ops *event_ops; +const struct irq_chip *event_irq_chip;void __iomem *bridge_addr;int num_events; }; --2.17.1
Re: [PATCH v16 15/22] PCI: microchip: Add event irqchip field to host port and add PLDA irqchip
Quoted 24 lines
Quoted 8 lines
As PLDA dts binding
doc(Documentation/devicetree/bindings/pci/ plda,xpressrich3-axi-common.yaml)showed, PLDA PCIe contains an interrupt controller.Quoted 5 lines
Microchip PolarFire PCIE event IRQs includes PLDA interrupts and Polarfire additional interrupts. The interrupt irqchip ops includes ack/mask/unmask interrupt ops, which will write correct registers. Microchip Polarfire PCIe additional interrupts require to write Polarfire SoC self-defined registers. So Microchip PCIe event irqchip ops can
not be re-used.
Quoted 10 lines
Microchip Polarfire PCIe additional intrerrupts:
(defined indrivers/pci/controller/plda/pcie-microchip-host.c)EVENT_PCIE_L2_EXITEVENT_PCIE_HOTRST_EXITEVENT_PCIE_DLUP_EXITEVENT_SEC_TX_RAM_SEC_ERREVENT_SEC_RX_RAM_SEC_ERR
....
Quoted 6 lines
Quoted 3 lines
To support PLDA its own event IRQ process, implements PLDA irqchip ops and add event irqchip field to struct
pcie_plda_rp.Hi Thomas
Could you review this patch? Thanks.
Hi Thomas
Previous Lorrenzo ask you to review this patch. The PLDA PCIe interrupt register
can be seen in the patch.
All:
Sorry to resend this.
Minda
PATCH v16 16/22 PCI: microchip: Move IRQ functions to pcie-plda-host.c
In reply to Minda ChenMove IRQ related functions to common file pcie-plda-host.c
The re-use code including MSI, INTx, event interrupts and IRQ init functions.
--- .../pci/controller/plda/pcie-microchip-host.c | 467 ----------------- drivers/pci/controller/plda/pcie-plda-host.c | 473 ++++++++++++++++++ drivers/pci/controller/plda/pcie-plda.h | 3 + 3 files changed, 476 insertions(+), 467 deletions(-)
drivers/pci/controller/plda/pcie-microchip-host.c +0 -467
@@ -318,244 +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 plda_handle_msi (struct irq_desc *desc) -{ -struct plda_pcie_rp *port =irq_desc_get_handler_data (desc); -struct irq_chip *chip =irq_desc_get_chip (desc); -struct device *dev = port->dev; -struct plda_msi *msi = &port->msi; -void __iomem *bridge_base_addr = port->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 plda_msi_bottom_irq_ack (struct irq_data *data) -{ -struct plda_pcie_rp *port =irq_data_get_irq_chip_data (data); -void __iomem *bridge_base_addr = port->bridge_addr; -u32 bitpos = data->hwirq; - -writel_relaxed (BIT (bitpos), bridge_base_addr +ISTATUS_MSI ); -} - -static void plda_compose_msi_msg (struct irq_data *data,struct msi_msg *msg) -{ -struct plda_pcie_rp *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 plda_msi_set_affinity (struct irq_data *irq_data, -const struct cpumask *mask,bool force) -{ -return -EINVAL ; -} - -static struct irq_chip plda_msi_bottom_irq_chip = { - .name ="PLDA MSI" , - .irq_ack = plda_msi_bottom_irq_ack, - .irq_compose_msi_msg = plda_compose_msi_msg, - .irq_set_affinity = plda_msi_set_affinity, -}; - -static int plda_irq_msi_domain_alloc (struct irq_domain *domain, -unsigned int virq, -unsigned int nr_irqs, -void *args) -{ -struct plda_pcie_rp *port = domain->host_data; -struct plda_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, &plda_msi_bottom_irq_chip, - domain->host_data, handle_edge_irq,NULL ,NULL ); - -mutex_unlock (&msi->lock); - -return 0 ; -} - -static void plda_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 plda_pcie_rp *port =irq_data_get_irq_chip_data (d); -struct plda_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 = plda_irq_msi_domain_alloc, - .free = plda_irq_msi_domain_free, -}; - -static struct irq_chip plda_msi_irq_chip = { - .name ="PLDA 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 plda_msi_domain_info = { - .flags = (MSI_FLAG_USE_DEF_DOM_OPS |MSI_FLAG_USE_DEF_CHIP_OPS | -MSI_FLAG_PCI_MSIX ), - .chip = &plda_msi_irq_chip, -}; - -static int plda_allocate_msi_domains (struct plda_pcie_rp *port) -{ -struct device *dev = port->dev; -struct fwnode_handle *fwnode =of_node_to_fwnode (dev->of_node); -struct plda_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, - &plda_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 plda_handle_intx (struct irq_desc *desc) -{ -struct plda_pcie_rp *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->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 plda_ack_intx_irq (struct irq_data *data) -{ -struct plda_pcie_rp *port =irq_data_get_irq_chip_data (data); -void __iomem *bridge_base_addr = port->bridge_addr; -u32 mask =BIT (data->hwirq +PM_MSI_INT_INTX_SHIFT ); - -writel_relaxed (mask, bridge_base_addr +ISTATUS_LOCAL ); -} - -static void plda_mask_intx_irq (struct irq_data *data) -{ -struct plda_pcie_rp *port =irq_data_get_irq_chip_data (data); -void __iomem *bridge_base_addr = port->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 plda_unmask_intx_irq (struct irq_data *data) -{ -struct plda_pcie_rp *port =irq_data_get_irq_chip_data (data); -void __iomem *bridge_base_addr = port->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 plda_intx_irq_chip = { - .name ="PLDA PCIe INTx" , - .irq_ack = plda_ack_intx_irq, - .irq_mask = plda_mask_intx_irq, - .irq_unmask = plda_unmask_intx_irq, -}; - -static int plda_pcie_intx_map (struct irq_domain *domain,unsigned int irq, -irq_hw_number_t hwirq) -{ -irq_set_chip_and_handler (irq, &plda_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 = plda_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 ;
@@ -626,26 +388,6 @@ static u32 mc_get_events(struct plda_pcie_rp *port)return events; } -static u32 plda_get_events (struct plda_pcie_rp *port) -{ -u32 events, val, origin; - - origin =readl_relaxed (port->bridge_addr +ISTATUS_LOCAL ); - -/* MSI event and sys events */ - val = (origin &SYS_AND_MSI_MASK ) >>PM_MSI_INT_MSI_SHIFT ; - events = val << (PM_MSI_INT_MSI_SHIFT -PCI_NUM_INTX +1 ); - -/* INTx events */ -if (origin &PM_MSI_INT_INTX_MASK ) - events |=BIT (PM_MSI_INT_INTX_SHIFT ); - -/* remains are same with register */ - events |= origin &GENMASK (P_ATR_EVT_DOORBELL_SHIFT ,0 ); - -return events; -} -static irqreturn_t mc_event_handler (int irq,void *dev_id) {struct plda_pcie_rp *port = dev_id;
@@ -662,28 +404,6 @@ static irqreturn_t mc_event_handler(int irq, void *dev_id)return IRQ_HANDLED ; } -static irqreturn_t plda_event_handler (int irq,void *dev_id) -{ -return IRQ_HANDLED ; -} - -static void plda_handle_event (struct irq_desc *desc) -{ -struct plda_pcie_rp *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 = port->event_ops->get_events (port); - -for_each_set_bit (bit, &events, port->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 plda_pcie_rp *port =irq_data_get_irq_chip_data (data);
@@ -770,83 +490,6 @@ static struct irq_chip mc_event_irq_chip = { .irq_unmask = mc_unmask_event_irq, }; -static u32 plda_hwirq_to_mask (int hwirq) -{ -u32 mask; - -/* hwirq 23 - 0 are the same with register */ -if (hwirq <EVENT_PM_MSI_INT_INTX ) - mask =BIT (hwirq); -else if (hwirq ==EVENT_PM_MSI_INT_INTX ) - mask =PM_MSI_INT_INTX_MASK ; -else - mask =BIT (hwirq +PCI_NUM_INTX -1 ); - -return mask; -} - -static void plda_ack_event_irq (struct irq_data *data) -{ -struct plda_pcie_rp *port =irq_data_get_irq_chip_data (data); - -writel_relaxed (plda_hwirq_to_mask (data->hwirq), - port->bridge_addr +ISTATUS_LOCAL ); -} - -static void plda_mask_event_irq (struct irq_data *data) -{ -struct plda_pcie_rp *port =irq_data_get_irq_chip_data (data); -u32 mask, val; - - mask =plda_hwirq_to_mask (data->hwirq); - -raw_spin_lock (&port->lock); - val =readl_relaxed (port->bridge_addr +IMASK_LOCAL ); - val &= ~mask; -writel_relaxed (val, port->bridge_addr +IMASK_LOCAL ); -raw_spin_unlock (&port->lock); -} - -static void plda_unmask_event_irq (struct irq_data *data) -{ -struct plda_pcie_rp *port =irq_data_get_irq_chip_data (data); -u32 mask, val; - - mask =plda_hwirq_to_mask (data->hwirq); - -raw_spin_lock (&port->lock); - val =readl_relaxed (port->bridge_addr +IMASK_LOCAL ); - val |= mask; -writel_relaxed (val, port->bridge_addr +IMASK_LOCAL ); -raw_spin_unlock (&port->lock); -} - -static struct irq_chip plda_event_irq_chip = { - .name ="PLDA PCIe EVENT" , - .irq_ack = plda_ack_event_irq, - .irq_mask = plda_mask_event_irq, - .irq_unmask = plda_unmask_event_irq, -}; - -static const struct plda_event_ops plda_event_ops = { - .get_events = plda_get_events, -}; - -static int plda_pcie_event_map (struct irq_domain *domain,unsigned int irq, -irq_hw_number_t hwirq) -{ -struct plda_pcie_rp *port = (void *)domain->host_data; - -irq_set_chip_and_handler (irq, port->event_irq_chip, handle_level_irq); -irq_set_chip_data (irq, domain->host_data); - -return 0 ; -} - -static const struct irq_domain_ops plda_event_domain_ops = { - .map = plda_pcie_event_map, -}; -static inline void mc_pcie_deinit_clk (void *data) {struct clk *clk = data;
@@ -909,47 +552,6 @@ static const struct plda_event mc_event = { .msi_event = EVENT_LOCAL_PM_MSI_INT_MSI, }; -static int plda_pcie_init_irq_domains (struct plda_pcie_rp *port) -{ -struct device *dev = port->dev; -struct device_node *node = dev->of_node; -struct device_node *pcie_intc_node; - -/* Setup INTx */ - pcie_intc_node =of_get_next_child (node,NULL ); -if (!pcie_intc_node) { -dev_err (dev,"failed to find PCIe Intc node\n" ); -return -EINVAL ; - } - - port->event_domain =irq_domain_add_linear (pcie_intc_node, - port->num_events, - &plda_event_domain_ops, - port); -if (!port->event_domain) { -dev_err (dev,"failed to get event domain\n" ); -of_node_put (pcie_intc_node); -return -ENOMEM ; - } - -irq_domain_update_bus_token (port->event_domain,DOMAIN_BUS_NEXUS ); - - port->intx_domain =irq_domain_add_linear (pcie_intc_node,PCI_NUM_INTX , - &intx_domain_ops, port); -if (!port->intx_domain) { -dev_err (dev,"failed to get an INTx IRQ domain\n" ); -of_node_put (pcie_intc_node); -return -ENOMEM ; - } - -irq_domain_update_bus_token (port->intx_domain,DOMAIN_BUS_WIRED ); - -of_node_put (pcie_intc_node); -raw_spin_lock_init (&port->lock); - -return plda_allocate_msi_domains (port); -} -static inline void mc_clear_secs (struct mc_pcie *port) {void __iomem *ctrl_base_addr = port->axi_base_addr +MC_PCIE_CTRL_ADDR ;
@@ -1010,75 +612,6 @@ static void mc_disable_interrupts(struct mc_pcie *port)writel_relaxed (GENMASK (31 ,0 ), bridge_base_addr +ISTATUS_HOST ); } -static int plda_init_interrupts (struct platform_device *pdev, -struct plda_pcie_rp *port, -const struct plda_event *event) -{ -struct device *dev = &pdev->dev; -int irq; -int i, intx_irq, msi_irq, event_irq; -int ret; - -if (!port->event_ops) - port->event_ops = &plda_event_ops; - -if (!port->event_irq_chip) - port->event_irq_chip = &plda_event_irq_chip; - - ret =plda_pcie_init_irq_domains (port); -if (ret) { -dev_err (dev,"failed creating IRQ domains\n" ); -return ret; - } - - irq =platform_get_irq (pdev,0 ); -if (irq <0 ) -return -ENODEV ; - -for (i =0 ; i < port->num_events; i++) { - event_irq =irq_create_mapping (port->event_domain, i); -if (!event_irq) { -dev_err (dev,"failed to map hwirq %d\n" , i); -return -ENXIO ; - } - -if (event->request_event_irq) - ret = event->request_event_irq (port, event_irq, i); -else - ret =devm_request_irq (dev, event_irq, - plda_event_handler, -0 ,NULL , port); - -if (ret) { -dev_err (dev,"failed to request IRQ %d\n" , event_irq); -return ret; - } - } - - intx_irq =irq_create_mapping (port->event_domain, - event->intx_event); -if (!intx_irq) { -dev_err (dev,"failed to map INTx interrupt\n" ); -return -ENXIO ; - } - -/* Plug the INTx chained handler */ -irq_set_chained_handler_and_data (intx_irq, plda_handle_intx, port); - - msi_irq =irq_create_mapping (port->event_domain, - event->msi_event); -if (!msi_irq) -return -ENXIO ; - -/* Plug the MSI chained handler */ -irq_set_chained_handler_and_data (msi_irq, plda_handle_msi, port); - -/* Plug the main event chained handler */ -irq_set_chained_handler_and_data (irq, plda_handle_event, port); - -return 0 ; -} -static int mc_platform_init (struct pci_config_window *cfg) {struct device *dev = cfg->parent;
drivers/pci/controller/plda/pcie-plda-host.c +473 -0
483 lines not on this page · raw message
drivers/pci/controller/plda/pcie-plda.h +3 -0
@@ -170,6 +170,9 @@ struct plda_event {int msi_event; }; +int plda_init_interrupts (struct platform_device *pdev, +struct plda_pcie_rp *port, +const struct plda_event *event);void plda_pcie_setup_window (void __iomem *bridge_base_addr,u32 index,phys_addr_t axi_addr,phys_addr_t pci_addr,size_t size);
Signature · 1 line
2.17.1
PATCH v16 17/22 PCI: plda: Add event bitmap field to struct plda_pcie_rp
In reply to Minda ChenPLDA DMA interrupts are not all implemented, The non-implemented interrupts should be masked. So add a bitmap field to mask the non- implemented interrupts.
--- drivers/pci/controller/plda/pcie-microchip-host.c | 1 + drivers/pci/controller/plda/pcie-plda-host.c | 6 ++++-- drivers/pci/controller/plda/pcie-plda.h | 1 + 3 files changed, 6 insertions(+), 2 deletions(-)
drivers/pci/controller/plda/pcie-microchip-host.c +1 -0
@@ -636,6 +636,7 @@ static int mc_platform_init(struct pci_config_window *cfg) port->plda.event_ops = &mc_event_ops; port->plda.event_irq_chip = &mc_event_irq_chip; + port->plda.events_bitmap =GENMASK (NUM_EVENTS -1 ,0 );/* Address translation is up; safe to enable interrupts */ ret =plda_init_interrupts (pdev, &port->plda, &mc_event);
drivers/pci/controller/plda/pcie-plda-host.c +4 -2
@@ -290,6 +290,7 @@ static void plda_handle_event(struct irq_desc *desc) events = port->event_ops->get_events (port); + events &= port->events_bitmap;for_each_set_bit (bit, &events, port->num_events)generic_handle_domain_irq (port->event_domain, bit);
@@ -420,8 +421,9 @@ int plda_init_interrupts(struct platform_device *pdev, {struct device *dev = &pdev->dev;int irq; -int i, intx_irq, msi_irq, event_irq; +int intx_irq, msi_irq, event_irq;int ret; +u32 i;if (!port->event_ops) port->event_ops = &plda_event_ops;
@@ -439,7 +441,7 @@ int plda_init_interrupts(struct platform_device *pdev,if (irq <0 )return -ENODEV ; -for (i =0 ; i < port->num_events; i++) { +for_each_set_bit (i, &port->events_bitmap, port->num_events) { event_irq =irq_create_mapping (port->event_domain, i);if (!event_irq) {dev_err (dev,"failed to map hwirq %d\n" , i);
drivers/pci/controller/plda/pcie-plda.h +1 -0
@@ -160,6 +160,7 @@ struct plda_pcie_rp {const struct plda_event_ops *event_ops;const struct irq_chip *event_irq_chip;void __iomem *bridge_addr; +unsigned long events_bitmap;int num_events; };
Signature · 1 line
2.17.1
PATCH v16 18/22 PCI: plda: Add host init/deinit and map bus functions
In reply to Minda ChenAdd PLDA host plda_pcie_host_init()/plda_pcie_host_deinit() and map bus function. So vendor can use it to init PLDA PCIe host core.
--- drivers/pci/controller/plda/pcie-plda-host.c | 131 +++++++++++++++++-- drivers/pci/controller/plda/pcie-plda.h | 22 ++++ 2 files changed, 139 insertions(+), 14 deletions(-)
drivers/pci/controller/plda/pcie-plda-host.c +117 -14
@@ -3,6 +3,7 @@* PLDA PCIe XpressRich host controller driver * * Copyright (C) 2023 Microchip Co. Ltd +* StarFive Co. Ltd * * Author: Daire McNamara <[email protected]> */
@@ -15,6 +16,15 @@#include "pcie-plda.h" +void __iomem *plda_pcie_map_bus (struct pci_bus *bus,unsigned int devfn, +int where) +{ +struct plda_pcie_rp *pcie = bus->sysdata; + +return pcie->config_base +PCIE_ECAM_OFFSET (bus->number, devfn, where); +} +EXPORT_SYMBOL_GPL (plda_pcie_map_bus); +static void plda_handle_msi (struct irq_desc *desc) {struct plda_pcie_rp *port =irq_desc_get_handler_data (desc);
@@ -420,9 +430,7 @@ int plda_init_interrupts(struct platform_device *pdev, const struct plda_event *event) {struct device *dev = &pdev->dev; -int irq; -int intx_irq, msi_irq, event_irq; -int ret; +int event_irq, ret;u32 i;if (!port->event_ops)
@@ -437,8 +445,8 @@ int plda_init_interrupts(struct platform_device *pdev,return ret; } - irq =platform_get_irq (pdev,0 ); -if (irq <0 ) + port->irq =platform_get_irq (pdev,0 ); +if (port->irq <0 )return -ENODEV ;for_each_set_bit (i, &port->events_bitmap, port->num_events) {
@@ -461,26 +469,26 @@ int plda_init_interrupts(struct platform_device *pdev, } } - intx_irq =irq_create_mapping (port->event_domain, - event->intx_event); -if (!intx_irq) { + port->intx_irq =irq_create_mapping (port->event_domain, + event->intx_event); +if (!port->intx_irq) {dev_err (dev,"failed to map INTx interrupt\n" );return -ENXIO ; }/* Plug the INTx chained handler */ -irq_set_chained_handler_and_data (intx_irq, plda_handle_intx, port); +irq_set_chained_handler_and_data (port->intx_irq, plda_handle_intx, port); - msi_irq =irq_create_mapping (port->event_domain, - event->msi_event); -if (!msi_irq) + port->msi_irq =irq_create_mapping (port->event_domain, + event->msi_event); +if (!port->msi_irq)return -ENXIO ;/* Plug the MSI chained handler */ -irq_set_chained_handler_and_data (msi_irq, plda_handle_msi, port); +irq_set_chained_handler_and_data (port->msi_irq, plda_handle_msi, port);/* Plug the main event chained handler */ -irq_set_chained_handler_and_data (irq, plda_handle_event, port); +irq_set_chained_handler_and_data (port->irq, plda_handle_event, port);return 0 ; }
@@ -546,3 +554,98 @@ int plda_pcie_setup_iomems(struct pci_host_bridge *bridge,return 0 ; }EXPORT_SYMBOL_GPL (plda_pcie_setup_iomems); + +static void plda_pcie_irq_domain_deinit (struct plda_pcie_rp *pcie) +{ +irq_set_chained_handler_and_data (pcie->irq,NULL ,NULL ); +irq_set_chained_handler_and_data (pcie->msi_irq,NULL ,NULL ); +irq_set_chained_handler_and_data (pcie->intx_irq,NULL ,NULL ); + +irq_domain_remove (pcie->msi.msi_domain); +irq_domain_remove (pcie->msi.dev_domain); + +irq_domain_remove (pcie->intx_domain); +irq_domain_remove (pcie->event_domain); +} + +int plda_pcie_host_init (struct plda_pcie_rp *port,struct pci_ops *ops, +const struct plda_event *plda_event) +{ +struct device *dev = port->dev; +struct pci_host_bridge *bridge; +struct platform_device *pdev =to_platform_device (dev); +struct resource *cfg_res; +int ret; + + pdev =to_platform_device (dev); + + port->bridge_addr = +devm_platform_ioremap_resource_byname (pdev,"apb" ); + +if (IS_ERR (port->bridge_addr)) +return dev_err_probe (dev,PTR_ERR (port->bridge_addr), +"failed to map reg memory\n" ); + + cfg_res =platform_get_resource_byname (pdev,IORESOURCE_MEM ,"cfg" ); +if (!cfg_res) +return dev_err_probe (dev, -ENODEV , +"failed to get config memory\n" ); + + port->config_base =devm_ioremap_resource (dev, cfg_res); +if (IS_ERR (port->config_base)) +return dev_err_probe (dev,PTR_ERR (port->config_base), +"failed to map config memory\n" ); + + bridge =devm_pci_alloc_host_bridge (dev,0 ); +if (!bridge) +return dev_err_probe (dev, -ENOMEM , +"failed to alloc bridge\n" ); + +if (port->host_ops && port->host_ops->host_init) { + ret = port->host_ops->host_init (port); +if (ret) +return ret; + } + + port->bridge = bridge; +plda_pcie_setup_window (port->bridge_addr,0 , cfg_res->start,0 , +resource_size (cfg_res)); +plda_pcie_setup_iomems (bridge, port); +plda_set_default_msi (&port->msi); + ret =plda_init_interrupts (pdev, port, plda_event); +if (ret) + goto err_host; + +/* Set default bus ops */ + bridge->ops = ops; + bridge->sysdata = port; + + ret =pci_host_probe (bridge); +if (ret <0 ) { +dev_err_probe (dev, ret,"failed to probe pci host\n" ); + goto err_probe; + } + +return ret; + +err_probe: +plda_pcie_irq_domain_deinit (port); +err_host: +if (port->host_ops && port->host_ops->host_deinit) + port->host_ops->host_deinit (port); + +return ret; +} +EXPORT_SYMBOL_GPL (plda_pcie_host_init); + +void plda_pcie_host_deinit (struct plda_pcie_rp *port) +{ +pci_stop_root_bus (port->bridge->bus); +pci_remove_root_bus (port->bridge->bus); + +plda_pcie_irq_domain_deinit (port); + +if (port->host_ops && port->host_ops->host_deinit) + port->host_ops->host_deinit (port); +} +EXPORT_SYMBOL_GPL (plda_pcie_host_deinit);
drivers/pci/controller/plda/pcie-plda.h +22 -0
@@ -142,6 +142,11 @@ struct plda_event_ops {u32 (*get_events)(struct plda_pcie_rp *pcie); }; +struct plda_pcie_host_ops { +int (*host_init)(struct plda_pcie_rp *pcie); +void (*host_deinit)(struct plda_pcie_rp *pcie); +}; +struct plda_msi {struct mutex lock;/* Protect used bitmap */ struct irq_domain *msi_domain;
@@ -153,14 +158,20 @@ struct plda_msi {struct plda_pcie_rp {struct device *dev; +struct pci_host_bridge *bridge;struct irq_domain *intx_domain;struct irq_domain *event_domain;raw_spinlock_t lock;struct plda_msi msi;const struct plda_event_ops *event_ops;const struct irq_chip *event_irq_chip; +const struct plda_pcie_host_ops *host_ops;void __iomem *bridge_addr; +void __iomem *config_base;unsigned long events_bitmap; +int irq; +int msi_irq; +int intx_irq;int num_events; };
@@ -171,6 +182,8 @@ struct plda_event {int msi_event; }; +void __iomem *plda_pcie_map_bus (struct pci_bus *bus,unsigned int devfn, +int where);int plda_init_interrupts (struct platform_device *pdev,struct plda_pcie_rp *port,const struct plda_event *event);
@@ -179,4 +192,13 @@ void plda_pcie_setup_window(void __iomem *bridge_base_addr, u32 index, size_t size);int plda_pcie_setup_iomems (struct pci_host_bridge *bridge,struct plda_pcie_rp *port); +int plda_pcie_host_init (struct plda_pcie_rp *port,struct pci_ops *ops, +const struct plda_event *plda_event); +void plda_pcie_host_deinit (struct plda_pcie_rp *pcie); + +static inline void plda_set_default_msi (struct plda_msi *msi) +{ + msi->vector_phy =IMSI_ADDR ; + msi->num_vectors =PLDA_MAX_NUM_MSI_IRQS ; +}#endif
Signature · 1 line
2.17.1
PATCH v16 19/22 dt-bindings: PCI: Add StarFive JH7110 PCIe controller
In reply to Minda ChenAdd StarFive JH7110 SoC PCIe controller dt-bindings. JH7110 using PLDA XpressRICH PCIe host controller IP.
--- .../bindings/pci/starfive,jh7110-pcie.yaml | 120 ++++++++++++++++++ MAINTAINERS | 6 + 2 files changed, 126 insertions(+) create mode 100644 Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml
Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml new file +120 -0
@@ -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 <[email protected]> + +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; + }; + }; + };
MAINTAINERS +6 -0
@@ -17215,6 +17215,12 @@ L: [email protected] S: Maintained F: drivers/pci/controller/dwc/*spear* +PCIE DRIVER FOR STARFIVE JH71x0 +M: Kevin Xie <[email protected]> +L: [email protected] +S: Maintained +F: Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml + PCIE ENDPOINT DRIVER FOR QUALCOMM M: Manivannan Sadhasivam <[email protected]> L: [email protected]
Signature · 1 line
2.17.1
Re: [PATCH v16 19/22] dt-bindings: PCI: Add StarFive JH7110 PCIe controller
Quoted 7 lines · Minda Chen
Add StarFive JH7110 SoC PCIe controller dt-bindings. JH7110 using PLDA XpressRICH PCIe host controller IP.
Signed-off-by Minda Chen <[email protected]>Reviewed-by Hal Feng <[email protected]>Reviewed-by Conor Dooley <[email protected]>Reviewed-by Rob Herring <[email protected]>
This really should have a Signed-off-by or an Acked-by from Kevin.
Quoted 5 lines
MAINTAINERS +5
-0+PCIE DRIVER FOR STARFIVE JH71x0 +M: Kevin Xie <[email protected]> +L: [email protected] +S: Maintained +F: Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml
Re: [PATCH v16 19/22] dt-bindings: PCI: Add StarFive JH7110 PCIe controller
In reply to Minda ChenQuoted 7 lines
Add StarFive JH7110 SoC PCIe controller dt-bindings. JH7110 using PLDA XpressRICH PCIe host controller IP.
Signed-off-by Minda Chen <[email protected]>Reviewed-by Hal Feng <[email protected]>Reviewed-by Conor Dooley <[email protected]>Reviewed-by Rob Herring <[email protected]>
Quoted 6 lines
--- .../bindings/pci/starfive,jh7110-pcie.yaml | 120 ++++++++++++++++++ MAINTAINERS | 6 + 2 files changed, 126 insertions(+) create mode 100644
Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml
PATCH v16 20/22 PCI: Add PCIE_RESET_CONFIG_DEVICE_WAIT_MS waiting time value
In reply to Minda ChenFrom: Kevin Xie <[email protected]>
Add the PCIE_RESET_CONFIG_DEVICE_WAIT_MS macro to define the minimum waiting time between exit from a conventional reset and sending the first configuration request to the device.
As described in PCI base specification r6.0, section 6.6.1 <Conventional Reset>, there are two different use cases of the value:
- "With a Downstream Port that does not support Link speeds greater than 5.0 GT/s, software must wait a minimum of 100 ms following exit from a Conventional Reset before sending a Configuration Request to the device immediately below that Port."
- "With a Downstream Port that supports Link speeds greater than 5.0 GT/s, software must wait a minimum of 100 ms after Link training completes before sending a Configuration Request to the device immediately below that Port."
--- drivers/pci/pci.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
drivers/pci/pci.h +16 -0
@@ -22,6 +22,22 @@*/ #define PCIE_PME_TO_L2_TIMEOUT_US 10000 +/* +* As described in PCI base specification r6.0, section 6.6.1 <Conventional +* Reset>, there are two different use cases of the value: +* +* - "With a Downstream Port that does not support Link speeds greater +* than 5.0 GT/s, software must wait a minimum of 100 ms following exit +* from a Conventional Reset before sending a Configuration Request to +* the device immediately below that Port." +* +* - "With a Downstream Port that supports Link speeds greater than +* 5.0 GT/s, software must wait a minimum of 100 ms after Link training +* completes before sending a Configuration Request to the device +* immediately below that Port." +*/ +#define PCIE_RESET_CONFIG_DEVICE_WAIT_MS 100 +extern const unsigned char pcie_link_speed[];extern bool pci_early_dump;
Signature · 1 line
2.17.1
PATCH v16 21/22 PCI: starfive: Add JH7110 PCIe controller
In reply to Minda ChenAdd StarFive JH7110 SoC PCIe controller platform driver code, JH7110 with PLDA host PCIe core.
--- MAINTAINERS | 1 + drivers/pci/controller/plda/Kconfig | 12 + drivers/pci/controller/plda/Makefile | 1 + drivers/pci/controller/plda/pcie-plda.h | 71 ++- drivers/pci/controller/plda/pcie-starfive.c | 488 ++++++++++++++++++++ 5 files changed, 572 insertions(+), 1 deletion(-) create mode 100644 drivers/pci/controller/plda/pcie-starfive.c
MAINTAINERS +1 -0
@@ -17220,6 +17220,7 @@ M: Kevin Xie <[email protected]> L: [email protected] 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 <[email protected]>
drivers/pci/controller/plda/Kconfig +12 -0
@@ -15,4 +15,16 @@ config PCIE_MICROCHIP_HOST 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
drivers/pci/controller/plda/Makefile +1 -0
@@ -1,3 +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
drivers/pci/controller/plda/pcie-plda.h +70 -1
96 lines not on this page · raw message
drivers/pci/controller/plda/pcie-starfive.c new file +488 -0
488 lines not on this page · raw message
Signature · 1 line
2.17.1
PATCH v16 22/22 riscv: dts: starfive: add PCIe dts configuration for JH7110
In reply to Minda ChenAdd PCIe dts configuraion for JH7110 SoC platform.
--- .../jh7110-starfive-visionfive-2.dtsi | 64 ++++++++++++++ arch/riscv/boot/dts/starfive/jh7110.dtsi | 86 +++++++++++++++++++ 2 files changed, 150 insertions(+)
arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi +64 -0
@@ -330,6 +330,22 @@ status = "okay"; }; +&pcie0 { + perst-gpios = <&sysgpio 26 GPIO_ACTIVE_LOW>; + phys = <&pciephy0>; + pinctrl-names = "default"; + pinctrl-0 = <&pcie0_pins>; + status = "okay"; +}; + +&pcie1 { + perst-gpios = <&sysgpio 28 GPIO_ACTIVE_LOW>; + phys = <&pciephy1>; + pinctrl-names = "default"; + pinctrl-0 = <&pcie1_pins>; + status = "okay"; +}; + &pwmdac { pinctrl-names = "default"; pinctrl-0 = <&pwmdac_pins>;
@@ -552,6 +568,54 @@ }; }; + pcie0_pins: pcie0-0 { + clkreq-pins { + pinmux = <GPIOMUX(27, GPOUT_LOW, + GPOEN_DISABLE, + GPI_NONE)>; + bias-pull-down; + drive-strength = <2>; + input-enable; + input-schmitt-disable; + slew-rate = <0>; + }; + + wake-pins { + pinmux = <GPIOMUX(32, GPOUT_LOW, + GPOEN_DISABLE, + GPI_NONE)>; + bias-pull-up; + drive-strength = <2>; + input-enable; + input-schmitt-disable; + slew-rate = <0>; + }; + }; + + pcie1_pins: pcie1-0 { + clkreq-pins { + pinmux = <GPIOMUX(29, GPOUT_LOW, + GPOEN_DISABLE, + GPI_NONE)>; + bias-pull-down; + drive-strength = <2>; + input-enable; + input-schmitt-disable; + slew-rate = <0>; + }; + + wake-pins { + pinmux = <GPIOMUX(21, GPOUT_LOW, + GPOEN_DISABLE, + GPI_NONE)>; + bias-pull-up; + drive-strength = <2>; + input-enable; + input-schmitt-disable; + slew-rate = <0>; + }; + }; + pwmdac_pins: pwmdac-0 { pwmdac-pins { pinmux = <GPIOMUX(33, GPOUT_SYS_PWMDAC_LEFT,
arch/riscv/boot/dts/starfive/jh7110.dtsi +86 -0
91 lines not on this page · raw message
Signature · 1 line
2.17.1
Quoted 11 lines
This patchset final purpose is add PCIe driver for StarFive JH7110 SoC. JH7110 using PLDA XpressRICH PCIe IP. Microchip PolarFire Using the same IP and have commit their codes, which are mixed with PLDA controller codes and Microchip platform codes.
For re-use the PLDA controller codes, I request refactoring microchip codes, move PLDA common codes to PLDA files.
Desigware and Cadence is good example for refactoring codes.
Quoted 8 lines
----------------------------------------------------------
The refactoring patches total number is 16,(patch 1-16) which do NOT contain changing logic of codes.These patches just contain three type basic operations.
(rename, modify codes to support starfive platform, and moving to common file) If these patched are all be reviewed. They can be accepted first.
Hi Lorenzo Krzysztof ,Bjorn and other PCIe maintainer
Do you have any comment to patch 1-16? Hope patch 1-16(refactoring patches) ready
to merged first.
Krzysztof Wilczyński
AppliedHello,
Quoted 8 lines
This patchset final purpose is add PCIe driver for StarFive JH7110 SoC. JH7110 using PLDA XpressRICH PCIe IP. Microchip PolarFire Using the same IP and have commit their codes, which are mixed with PLDA controller codes and Microchip platform codes.
For re-use the PLDA controller codes, I request refactoring microchip codes, move PLDA common codes to PLDA files.
Desigware and Cadence is good example for refactoring codes.
Applied to controller/microchip, thank you!
[01/21] dt-bindings: PCI: Add PLDA XpressRICH PCIe host common properties
https://git.kernel.org/pci/pci/c/0ce827c82eea [02/21] dt-bindings: PCI: Add StarFive JH7110 PCIe controller https://git.kernel.org/pci/pci/c/91b4524c9135 [03/21] PCI: Add PCIE_RESET_CONFIG_DEVICE_WAIT_MS waiting time value https://git.kernel.org/pci/pci/c/4b83a1379e8c [04/21] PCI: microchip: Move pcie-microchip-host.c to PLDA directory https://git.kernel.org/pci/pci/c/ced442bf0124 [05/21] PCI: microchip: Move PLDA IP register macros to pcie-plda.h https://git.kernel.org/pci/pci/c/571f57cc281c [06/21] PCI: microchip: Add bridge_addr field to struct mc_pcie https://git.kernel.org/pci/pci/c/73c9dcd35dd8 [07/21] PCI: microchip: Rename two PCIe data structures https://git.kernel.org/pci/pci/c/e92d66e0aa1e [08/08] PCI: microchip: Move PCIe host data structures to plda-pcie.h https://git.kernel.org/pci/pci/c/79c0d7d53a51 [09/21] PCI: microchip: Rename two setup functions https://git.kernel.org/pci/pci/c/082bda75f7b0 [10/21] PCI: microchip: Change the argument of plda_pcie_setup_iomems() https://git.kernel.org/pci/pci/c/9251a0b72188 [11/21] PCI: microchip: Move setup functions to pcie-plda-host.c https://git.kernel.org/pci/pci/c/047cc7da3a25 [12/21] PCI: microchip: Rename interrupt related functions https://git.kernel.org/pci/pci/c/ddac0618211f [13/21] PCI: microchip: Add num_events field to struct plda_pcie_rp https://git.kernel.org/pci/pci/c/cb90f7f6145b [14/21] PCI: microchip: Add request_event_irq() callback function https://git.kernel.org/pci/pci/c/0ffbe1c70551 [15/21] PCI: microchip: Add INTx and MSI event num to struct plda_event https://git.kernel.org/pci/pci/c/9932c5d45e5a [16/21] PCI: microchip: Add get_events() callback and add PLDA get_event() https://git.kernel.org/pci/pci/c/170407afbcc4 [17/21] PCI: microchip: Add event irqchip field to host port and add PLDA irqchip https://git.kernel.org/pci/pci/c/5e33af45dbcb [18/21] PCI: microchip: Move IRQ functions to pcie-plda-host.c https://git.kernel.org/pci/pci/c/4e47aaf7afed [19/21] PCI: plda: Add event bitmap field to struct plda_pcie_rp https://git.kernel.org/pci/pci/c/008d2bc41e3c [20/21] PCI: plda: Add host init/deinit and map bus functions https://git.kernel.org/pci/pci/c/d86b148a401c [21/21] PCI: starfive: Add JH7110 PCIe controller https://git.kernel.org/pci/pci/c/e6e7b974e425 Krzysztof
Hello Minda Chen.
I applied your PCIE series patches to v6.10-rc3 and v6.9.0, works like a charm - thank you!
So Tested-by: Alexey Lukyanchuk to all series.
Hovewere i had to fix some minor issues, you can view the results here:
https://github.com/skif-web/linux-starfive-vs2-mainline/tree/strafive-visionfive2-pcie-2
Hope it helps.
Hopefully to see this series being eventually applied soon.
Alexey Lukyanchuk
Tested-bySOZ, I forgot to add email to tag, sorry
Quoted 15 lines · On Sat, 22 Jun 2024 12:14:03 +0300 Alexey Lukyanchuk…
Hello Minda Chen.
I applied your PCIE series patches to v6.10-rc3 and v6.9.0, works like a charm - thank you!
So Tested-by: Alexey Lukyanchuk to all series.
Hovewere i had to fix some minor issues, you can view the results here:
https://github.com/skif-web/linux-starfive-vs2-mainline/tree/strafive-visionfive2-pcie-2
Hope it helps.
Hopefully to see this series being eventually applied soon.