* [PATCH v2 0/4] Refactoring Microchip PCIe driver and add StarFive PCIe
@ 2023-07-27 10:39 Minda Chen
2023-07-27 10:39 ` [PATCH v2 1/4] dt-bindings: PCI: Add PLDA XpressRICH PCIe host common properties Minda Chen
` (5 more replies)
0 siblings, 6 replies; 19+ messages in thread
From: Minda Chen @ 2023-07-27 10:39 UTC (permalink / raw)
To: Krzysztof Wilczyński, Daire McNamara, Conor Dooley,
Rob Herring, Krzysztof Kozlowski, Bjorn Helgaas,
Lorenzo Pieralisi, Emil Renner Berthing
Cc: devicetree, linux-kernel, linux-pci, Philipp Zabel, Mason Huo,
Leyfoon Tan, Kevin Xie, Minda Chen
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.
So first step is extract the PLDA common codes from microchip, and
refactoring the microchip codes.(patch1 - 2)
Then, add Starfive codes. (patch3 - 4)
This patchset is base on v6.5-rc1
patch1 is move PLDA XpressRICH PCIe host common properties dt-binding
docs from microchip,pcie-host.yaml
patch2 is extracting the PLDA common codes from microchip Polarfire PCIe
codes. The change list in the commit message.
patch3 is add StarFive JH7110 PCIe dt-binding doc.
patch4 is add StarFive JH7110 Soc PCIe codes.
I have noticed that Daire have changed microchip's codes.
https://patchwork.kernel.org/project/linux-pci/cover/20230630154859.2049521-1-daire.mcnamara@microchip.com/
I have changed patch2 base on their commits. StarFive
PCIe driver still can work. But their codes is under reviewed and
maybe changing. Do not base on their changes first.
I will base on their commit to change patch2 as soon as
their commits are accepted.
previous version:
v1:https://patchwork.kernel.org/project/linux-pci/cover/20230719102057.22329-1-minda.chen@starfivetech.com/
change:
v2:
patch1:
- squash dt-bindings patches to patch1
- add 'required' list.
- plda doc rename to plda,xpressrich-axi-common.yaml
patch2:
- squash the microchip modification patch to patch 2.
patch3:
- remove the plda common required property.
patch4:
- Sync the hide rc bar ops with config read function.
- Revert the T_PVPERL to 100ms and add comments for the source.
- Replace the link check function by the standard link ops.
- Convert to new pm ops marcos.
- Some formats modification.
- pcie-plda-host modification merge to patch4.
other:
- remove the pcie-plda-plat.c
- remove the starfive dts patch first. for it depends on
stg clock and syscon setting.
Minda Chen (4):
dt-bindings: PCI: Add PLDA XpressRICH PCIe host common properties
PCI: plda: Get common codes from Microchip PolarFire host
dt-bindings: PCI: Add StarFive JH7110 PCIe controller
PCI: starfive: Add JH7110 PCIe controller
.../bindings/pci/microchip,pcie-host.yaml | 49 +-
.../pci/plda,xpressrich3-axi-common.yaml | 69 ++
.../bindings/pci/starfive,jh7110-pcie.yaml | 133 ++++
MAINTAINERS | 19 +-
drivers/pci/controller/Kconfig | 9 +-
drivers/pci/controller/Makefile | 2 +-
drivers/pci/controller/plda/Kconfig | 31 +
drivers/pci/controller/plda/Makefile | 4 +
.../{ => plda}/pcie-microchip-host.c | 594 ++--------------
drivers/pci/controller/plda/pcie-plda-host.c | 665 ++++++++++++++++++
drivers/pci/controller/plda/pcie-plda.h | 242 +++++++
drivers/pci/controller/plda/pcie-starfive.c | 438 ++++++++++++
12 files changed, 1645 insertions(+), 610 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 (50%)
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.c
base-commit: 06c2afb862f9da8dc5efa4b6076a0e48c3fbaaa5
--
2.17.1
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v2 1/4] dt-bindings: PCI: Add PLDA XpressRICH PCIe host common properties
2023-07-27 10:39 [PATCH v2 0/4] Refactoring Microchip PCIe driver and add StarFive PCIe Minda Chen
@ 2023-07-27 10:39 ` Minda Chen
2023-08-04 7:12 ` Conor Dooley
2023-07-27 10:39 ` [PATCH v2 2/4] PCI: plda: Get common codes from Microchip PolarFire host Minda Chen
` (4 subsequent siblings)
5 siblings, 1 reply; 19+ messages in thread
From: Minda Chen @ 2023-07-27 10:39 UTC (permalink / raw)
To: Krzysztof Wilczyński, Daire McNamara, Conor Dooley,
Rob Herring, Krzysztof Kozlowski, Bjorn Helgaas,
Lorenzo Pieralisi, Emil Renner Berthing
Cc: devicetree, linux-kernel, linux-pci, Philipp Zabel, Mason Huo,
Leyfoon Tan, Kevin Xie, Minda Chen
Add PLDA XpressRICH PCIe host common properties dt-binding doc.
Microchip PolarFire PCIe host using PLDA IP.
Move common properties from Microchip PolarFire PCIe host
to PLDA files.
Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
Reviewed-by: Hal Feng <hal.feng@starfivetech.com>
---
.../bindings/pci/microchip,pcie-host.yaml | 49 +------------
.../pci/plda,xpressrich3-axi-common.yaml | 69 +++++++++++++++++++
2 files changed, 70 insertions(+), 48 deletions(-)
create mode 100644 Documentation/devicetree/bindings/pci/plda,xpressrich3-axi-common.yaml
diff --git a/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml b/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml
index f7a3c2636355..cff46f8b8320 100644
--- a/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml
+++ b/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml
@@ -11,20 +11,13 @@ maintainers:
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 +45,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,38 +52,10 @@ 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
diff --git a/Documentation/devicetree/bindings/pci/plda,xpressrich3-axi-common.yaml b/Documentation/devicetree/bindings/pci/plda,xpressrich3-axi-common.yaml
new file mode 100644
index 000000000000..1a27ade931ff
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/plda,xpressrich3-axi-common.yaml
@@ -0,0 +1,69 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/plda,xpressrich3-axi-common.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: PLDA XpressRICH PCIe host common properties
+
+maintainers:
+ - Daire McNamara <daire.mcnamara@microchip.com>
+ - Kevin Xie <kevin.xie@starfivetech.com>
+
+description:
+ Generic PLDA XpressRICH PCIe host common properties.
+
+properties:
+ reg:
+ maxItems: 2
+
+ reg-names:
+ items:
+ - const: cfg
+ - const: apb
+
+ interrupts:
+ minItems: 1
+ items:
+ - description: PCIe host controller
+ - description: builtin MSI controller
+
+ interrupt-names:
+ minItems: 1
+ items:
+ - const: pcie
+ - const: msi
+
+ msi-controller:
+ description: Identifies the node as an MSI controller.
+
+ msi-parent:
+ description: MSI controller the device is capable of using.
+
+ interrupt-controller:
+ type: object
+ properties:
+ '#address-cells':
+ const: 0
+
+ '#interrupt-cells':
+ const: 1
+
+ interrupt-controller: true
+
+ required:
+ - '#address-cells'
+ - '#interrupt-cells'
+ - interrupt-controller
+
+ additionalProperties: false
+
+required:
+ - reg
+ - reg-names
+ - interrupts
+ - msi-controller
+
+additionalProperties: true
+
+...
--
2.17.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 2/4] PCI: plda: Get common codes from Microchip PolarFire host
2023-07-27 10:39 [PATCH v2 0/4] Refactoring Microchip PCIe driver and add StarFive PCIe Minda Chen
2023-07-27 10:39 ` [PATCH v2 1/4] dt-bindings: PCI: Add PLDA XpressRICH PCIe host common properties Minda Chen
@ 2023-07-27 10:39 ` Minda Chen
2023-07-27 12:02 ` Bjorn Helgaas
2023-07-27 15:21 ` Randy Dunlap
2023-07-27 10:39 ` [PATCH v2 3/4] dt-bindings: PCI: Add StarFive JH7110 PCIe controller Minda Chen
` (3 subsequent siblings)
5 siblings, 2 replies; 19+ messages in thread
From: Minda Chen @ 2023-07-27 10:39 UTC (permalink / raw)
To: Krzysztof Wilczyński, Daire McNamara, Conor Dooley,
Rob Herring, Krzysztof Kozlowski, Bjorn Helgaas,
Lorenzo Pieralisi, Emil Renner Berthing
Cc: devicetree, linux-kernel, linux-pci, Philipp Zabel, Mason Huo,
Leyfoon Tan, Kevin Xie, Minda Chen
Add PLDA PCIe controller driver codes, Move them from Microchip
PolarFire PCIe host driver codes. And move pcie-microchip-host.c
to plda directory.
The change includes:
- copy the IP register marcos.
- Add related data structures of PCIe host instance.
mc_pcie --> plda_pcie (Get most of data members)
mc_msi --> plda_msi
add plda_pcie_ops and plda_evt data structures.
- function rename list:
mc_pcie_enable_msi --> plda_pcie_enable_msi
mc_pcie_setup_window --> plda_pcie_setup_window
mc_pcie_setup_windows --> plda_pcie_setup_iomems
mc_pcie_init_irq_domains --> plda_pcie_init_irq_domains
mc_allocate_msi_domains --> plda_allocate_msi_domains
mc_init_interrupts --> plda_pcie_init_irq
msi interrupts related functions and irq domain
(primary function is mc_handle_msi):
mc_handle_msi --> plda_handle_msi
intx interrupts related functions and irq domain
(primary function is mc_handle_intx):
mc_handle_intx --> plda_handle_intx
event interrupts:
mc_handle_event --> plda_handle_event
- For PolarFire implements non-plda local interrupt events, most of
event interrupt process codes can not be re-used. PLDA implements
new codes and irq domain ops like PolarFire.
New event functions:
plda_event_handler
plda_pcie_event_map
plda_ack_event_irq
plda_mask_event_irq
plda_unmask_event_irq
plda_hwirq_to_mask
- plda_handle_event adds a new irqnum to event num mapping codes for
PLDA local event except DMA engine interrupt events. The DMA engine
interrupt events are implemented by vendors. So do not add these
events. PolarFire PCIe uses get_events function pointer to get
their events num.
Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
---
MAINTAINERS | 12 +-
drivers/pci/controller/Kconfig | 9 +-
drivers/pci/controller/Makefile | 2 +-
drivers/pci/controller/plda/Kconfig | 19 +
drivers/pci/controller/plda/Makefile | 3 +
.../{ => plda}/pcie-microchip-host.c | 594 ++----------------
drivers/pci/controller/plda/pcie-plda-host.c | 554 ++++++++++++++++
drivers/pci/controller/plda/pcie-plda.h | 173 +++++
8 files changed, 804 insertions(+), 562 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 (50%)
create mode 100644 drivers/pci/controller/plda/pcie-plda-host.c
create mode 100644 drivers/pci/controller/plda/pcie-plda.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 8e4f9d5dca55..ec59c6d00bf9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -16170,6 +16170,14 @@ S: Maintained
F: Documentation/devicetree/bindings/pci/cdns,*
F: drivers/pci/controller/cadence/
+PCI DRIVER FOR PLDA PCIE IP
+M: Daire McNamara <daire.mcnamara@microchip.com>
+M: Kevin Xie <kevin.xie@starfivetech.com>
+L: linux-pci@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/pci/plda,*
+F: drivers/pci/controller/plda/*plda*
+
PCI DRIVER FOR FREESCALE LAYERSCAPE
M: Minghuan Lian <minghuan.Lian@nxp.com>
M: Mingkai Hu <mingkai.hu@nxp.com>
@@ -16495,7 +16503,7 @@ M: Daire McNamara <daire.mcnamara@microchip.com>
L: linux-pci@vger.kernel.org
S: Supported
F: Documentation/devicetree/bindings/pci/microchip*
-F: drivers/pci/controller/*microchip*
+F: drivers/pci/controller/plda/*microchip*
PCIE DRIVER FOR QUALCOMM MSM
M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
@@ -18279,7 +18287,7 @@ F: drivers/char/hw_random/mpfs-rng.c
F: drivers/clk/microchip/clk-mpfs*.c
F: drivers/i2c/busses/i2c-microchip-corei2c.c
F: drivers/mailbox/mailbox-mpfs.c
-F: drivers/pci/controller/pcie-microchip-host.c
+F: drivers/pci/controller/plda/pcie-microchip-host.c
F: drivers/pwm/pwm-microchip-core.c
F: drivers/reset/reset-mpfs.c
F: drivers/rtc/rtc-mpfs.c
diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index 8d49bad7f847..107cdb69e15c 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -216,14 +216,6 @@ config PCIE_MT7621
help
This selects a driver for the MediaTek MT7621 PCIe Controller.
-config PCIE_MICROCHIP_HOST
- bool "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
@@ -346,4 +338,5 @@ config PCIE_XILINX_CPM
source "drivers/pci/controller/cadence/Kconfig"
source "drivers/pci/controller/dwc/Kconfig"
source "drivers/pci/controller/mobiveil/Kconfig"
+source "drivers/pci/controller/plda/Kconfig"
endmenu
diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
index 37c8663de7fe..93236dc97b21 100644
--- a/drivers/pci/controller/Makefile
+++ b/drivers/pci/controller/Makefile
@@ -32,7 +32,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
@@ -43,6 +42,7 @@ obj-$(CONFIG_PCIE_MT7621) += pcie-mt7621.o
# pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW
obj-y += dwc/
obj-y += mobiveil/
+obj-y += plda/
# The following drivers are for devices that use the generic ACPI
diff --git a/drivers/pci/controller/plda/Kconfig b/drivers/pci/controller/plda/Kconfig
new file mode 100644
index 000000000000..28f5cf7ebb29
--- /dev/null
+++ b/drivers/pci/controller/plda/Kconfig
@@ -0,0 +1,19 @@
+# SPDX-License-Identifier: GPL-2.0
+
+menu "PLDA PCIe controllers support"
+ depends on PCI
+
+config PCIE_PLDA_HOST
+ bool
+ select IRQ_DOMAIN
+
+config PCIE_MICROCHIP_HOST
+ bool "Microchip AXI PCIe controller"
+ depends on OF && PCI_MSI
+ 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.
+
+endmenu
diff --git a/drivers/pci/controller/plda/Makefile b/drivers/pci/controller/plda/Makefile
new file mode 100644
index 000000000000..4340ab007f44
--- /dev/null
+++ b/drivers/pci/controller/plda/Makefile
@@ -0,0 +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
diff --git a/drivers/pci/controller/pcie-microchip-host.c b/drivers/pci/controller/plda/pcie-microchip-host.c
similarity index 50%
rename from drivers/pci/controller/pcie-microchip-host.c
rename to drivers/pci/controller/plda/pcie-microchip-host.c
index 5e710e485464..4ff3d956c7f8 100644
--- a/drivers/pci/controller/pcie-microchip-host.c
+++ b/drivers/pci/controller/plda/pcie-microchip-host.c
@@ -17,11 +17,8 @@
#include <linux/pci-ecam.h>
#include <linux/platform_device.h>
-#include "../pci.h"
-
-/* Number of MSI IRQs */
-#define MC_NUM_MSI_IRQS 32
-#define MC_NUM_MSI_IRQS_CODED 5
+#include "../../pci.h"
+#include "pcie-plda.h"
/* PCIe Bridge Phy and Controller Phy offsets */
#define MC_PCIE1_BRIDGE_ADDR 0x00008000u
@@ -29,6 +26,7 @@
#define MC_PCIE_BRIDGE_ADDR (MC_PCIE1_BRIDGE_ADDR)
#define MC_PCIE_CTRL_ADDR (MC_PCIE1_CTRL_ADDR)
+#define MC_PCIE_CTRL_ADDR_OFFSET 0x00002000u
/* PCIe Controller Phy Regs */
#define SEC_ERROR_CNT 0x20
@@ -82,86 +80,6 @@
#define PCIE_EVENT_INT_ENB_SHIFT 16
#define NUM_PCIE_EVENTS (3)
-/* PCIe Bridge Phy Regs */
-#define PCIE_PCI_IDS_DW1 0x9c
-
-/* PCIe Config space MSI capability structure */
-#define MC_MSI_CAP_CTRL_OFFSET 0xe0u
-#define MC_MSI_MAX_Q_AVAIL (MC_NUM_MSI_IRQS_CODED << 1)
-#define MC_MSI_Q_SIZE (MC_NUM_MSI_IRQS_CODED << 4)
-
-#define IMASK_LOCAL 0x180
-#define DMA_END_ENGINE_0_MASK 0x00000000u
-#define DMA_END_ENGINE_0_SHIFT 0
-#define DMA_END_ENGINE_1_MASK 0x00000000u
-#define DMA_END_ENGINE_1_SHIFT 1
-#define DMA_ERROR_ENGINE_0_MASK 0x00000100u
-#define DMA_ERROR_ENGINE_0_SHIFT 8
-#define DMA_ERROR_ENGINE_1_MASK 0x00000200u
-#define DMA_ERROR_ENGINE_1_SHIFT 9
-#define A_ATR_EVT_POST_ERR_MASK 0x00010000u
-#define A_ATR_EVT_POST_ERR_SHIFT 16
-#define A_ATR_EVT_FETCH_ERR_MASK 0x00020000u
-#define A_ATR_EVT_FETCH_ERR_SHIFT 17
-#define A_ATR_EVT_DISCARD_ERR_MASK 0x00040000u
-#define A_ATR_EVT_DISCARD_ERR_SHIFT 18
-#define A_ATR_EVT_DOORBELL_MASK 0x00000000u
-#define A_ATR_EVT_DOORBELL_SHIFT 19
-#define P_ATR_EVT_POST_ERR_MASK 0x00100000u
-#define P_ATR_EVT_POST_ERR_SHIFT 20
-#define P_ATR_EVT_FETCH_ERR_MASK 0x00200000u
-#define P_ATR_EVT_FETCH_ERR_SHIFT 21
-#define P_ATR_EVT_DISCARD_ERR_MASK 0x00400000u
-#define P_ATR_EVT_DISCARD_ERR_SHIFT 22
-#define P_ATR_EVT_DOORBELL_MASK 0x00000000u
-#define P_ATR_EVT_DOORBELL_SHIFT 23
-#define PM_MSI_INT_INTA_MASK 0x01000000u
-#define PM_MSI_INT_INTA_SHIFT 24
-#define PM_MSI_INT_INTB_MASK 0x02000000u
-#define PM_MSI_INT_INTB_SHIFT 25
-#define PM_MSI_INT_INTC_MASK 0x04000000u
-#define PM_MSI_INT_INTC_SHIFT 26
-#define PM_MSI_INT_INTD_MASK 0x08000000u
-#define PM_MSI_INT_INTD_SHIFT 27
-#define PM_MSI_INT_INTX_MASK 0x0f000000u
-#define PM_MSI_INT_INTX_SHIFT 24
-#define PM_MSI_INT_MSI_MASK 0x10000000u
-#define PM_MSI_INT_MSI_SHIFT 28
-#define PM_MSI_INT_AER_EVT_MASK 0x20000000u
-#define PM_MSI_INT_AER_EVT_SHIFT 29
-#define PM_MSI_INT_EVENTS_MASK 0x40000000u
-#define PM_MSI_INT_EVENTS_SHIFT 30
-#define PM_MSI_INT_SYS_ERR_MASK 0x80000000u
-#define PM_MSI_INT_SYS_ERR_SHIFT 31
-#define NUM_LOCAL_EVENTS 15
-#define ISTATUS_LOCAL 0x184
-#define IMASK_HOST 0x188
-#define ISTATUS_HOST 0x18c
-#define MSI_ADDR 0x190
-#define ISTATUS_MSI 0x194
-
-/* PCIe Master table init defines */
-#define ATR0_PCIE_WIN0_SRCADDR_PARAM 0x600u
-#define ATR0_PCIE_ATR_SIZE 0x25
-#define ATR0_PCIE_ATR_SIZE_SHIFT 1
-#define ATR0_PCIE_WIN0_SRC_ADDR 0x604u
-#define ATR0_PCIE_WIN0_TRSL_ADDR_LSB 0x608u
-#define ATR0_PCIE_WIN0_TRSL_ADDR_UDW 0x60cu
-#define ATR0_PCIE_WIN0_TRSL_PARAM 0x610u
-
-/* PCIe AXI slave table init defines */
-#define ATR0_AXI4_SLV0_SRCADDR_PARAM 0x800u
-#define ATR_SIZE_SHIFT 1
-#define ATR_IMPL_ENABLE 1
-#define ATR0_AXI4_SLV0_SRC_ADDR 0x804u
-#define ATR0_AXI4_SLV0_TRSL_ADDR_LSB 0x808u
-#define ATR0_AXI4_SLV0_TRSL_ADDR_UDW 0x80cu
-#define ATR0_AXI4_SLV0_TRSL_PARAM 0x810u
-#define PCIE_TX_RX_INTERFACE 0x00000000u
-#define PCIE_CONFIG_INTERFACE 0x00000001u
-
-#define ATR_ENTRY_SIZE 32
-
#define EVENT_PCIE_L2_EXIT 0
#define EVENT_PCIE_HOTRST_EXIT 1
#define EVENT_PCIE_DLUP_EXIT 2
@@ -205,7 +123,7 @@
[EVENT_LOCAL_ ## x] = { __stringify(x), s }
#define PCIE_EVENT(x) \
- .base = MC_PCIE_CTRL_ADDR, \
+ .base = MC_PCIE_CTRL_ADDR_OFFSET, \
.offset = PCIE_EVENT_INT, \
.mask_offset = PCIE_EVENT_INT, \
.mask_high = 1, \
@@ -213,7 +131,7 @@
.enb_mask = PCIE_EVENT_INT_ENB_MASK
#define SEC_EVENT(x) \
- .base = MC_PCIE_CTRL_ADDR, \
+ .base = MC_PCIE_CTRL_ADDR_OFFSET, \
.offset = SEC_ERROR_INT, \
.mask_offset = SEC_ERROR_INT_MASK, \
.mask = SEC_ERROR_INT_ ## x ## _INT, \
@@ -221,7 +139,7 @@
.enb_mask = 0
#define DED_EVENT(x) \
- .base = MC_PCIE_CTRL_ADDR, \
+ .base = MC_PCIE_CTRL_ADDR_OFFSET, \
.offset = DED_ERROR_INT, \
.mask_offset = DED_ERROR_INT_MASK, \
.mask_high = 1, \
@@ -229,7 +147,7 @@
.enb_mask = 0
#define LOCAL_EVENT(x) \
- .base = MC_PCIE_BRIDGE_ADDR, \
+ .base = 0, \
.offset = ISTATUS_LOCAL, \
.mask_offset = IMASK_LOCAL, \
.mask_high = 0, \
@@ -253,22 +171,9 @@ struct event_map {
u32 event_bit;
};
-struct mc_msi {
- struct mutex lock; /* Protect used bitmap */
- struct irq_domain *msi_domain;
- struct irq_domain *dev_domain;
- u32 num_vectors;
- u64 vector_phy;
- DECLARE_BITMAP(used, MC_NUM_MSI_IRQS);
-};
-
struct mc_pcie {
+ struct plda_pcie plda;
void __iomem *axi_base_addr;
- struct device *dev;
- struct irq_domain *intx_domain;
- struct irq_domain *event_domain;
- raw_spinlock_t lock;
- struct mc_msi msi;
};
struct cause {
@@ -382,275 +287,6 @@ static struct {
static char poss_clks[][5] = { "fic0", "fic1", "fic2", "fic3" };
-static void mc_pcie_enable_msi(struct mc_pcie *port, void __iomem *base)
-{
- struct mc_msi *msi = &port->msi;
- u32 cap_offset = MC_MSI_CAP_CTRL_OFFSET;
- u16 msg_ctrl = readw_relaxed(base + cap_offset + PCI_MSI_FLAGS);
-
- msg_ctrl |= PCI_MSI_FLAGS_ENABLE;
- msg_ctrl &= ~PCI_MSI_FLAGS_QMASK;
- msg_ctrl |= MC_MSI_MAX_Q_AVAIL;
- msg_ctrl &= ~PCI_MSI_FLAGS_QSIZE;
- msg_ctrl |= MC_MSI_Q_SIZE;
- msg_ctrl |= PCI_MSI_FLAGS_64BIT;
-
- writew_relaxed(msg_ctrl, base + cap_offset + PCI_MSI_FLAGS);
-
- writel_relaxed(lower_32_bits(msi->vector_phy),
- base + cap_offset + PCI_MSI_ADDRESS_LO);
- writel_relaxed(upper_32_bits(msi->vector_phy),
- base + cap_offset + PCI_MSI_ADDRESS_HI);
-}
-
-static void mc_handle_msi(struct irq_desc *desc)
-{
- struct mc_pcie *port = irq_desc_get_handler_data(desc);
- struct irq_chip *chip = irq_desc_get_chip(desc);
- struct device *dev = port->dev;
- struct mc_msi *msi = &port->msi;
- void __iomem *bridge_base_addr =
- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
- unsigned long status;
- u32 bit;
- int ret;
-
- chained_irq_enter(chip, desc);
-
- status = readl_relaxed(bridge_base_addr + ISTATUS_LOCAL);
- if (status & PM_MSI_INT_MSI_MASK) {
- writel_relaxed(status & PM_MSI_INT_MSI_MASK, bridge_base_addr + ISTATUS_LOCAL);
- status = readl_relaxed(bridge_base_addr + ISTATUS_MSI);
- for_each_set_bit(bit, &status, msi->num_vectors) {
- ret = generic_handle_domain_irq(msi->dev_domain, bit);
- if (ret)
- dev_err_ratelimited(dev, "bad MSI IRQ %d\n",
- bit);
- }
- }
-
- chained_irq_exit(chip, desc);
-}
-
-static void mc_msi_bottom_irq_ack(struct irq_data *data)
-{
- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
- void __iomem *bridge_base_addr =
- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
- u32 bitpos = data->hwirq;
-
- writel_relaxed(BIT(bitpos), bridge_base_addr + ISTATUS_MSI);
-}
-
-static void mc_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
-{
- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
- phys_addr_t addr = port->msi.vector_phy;
-
- msg->address_lo = lower_32_bits(addr);
- msg->address_hi = upper_32_bits(addr);
- msg->data = data->hwirq;
-
- dev_dbg(port->dev, "msi#%x address_hi %#x address_lo %#x\n",
- (int)data->hwirq, msg->address_hi, msg->address_lo);
-}
-
-static int mc_msi_set_affinity(struct irq_data *irq_data,
- const struct cpumask *mask, bool force)
-{
- return -EINVAL;
-}
-
-static struct irq_chip mc_msi_bottom_irq_chip = {
- .name = "Microchip MSI",
- .irq_ack = mc_msi_bottom_irq_ack,
- .irq_compose_msi_msg = mc_compose_msi_msg,
- .irq_set_affinity = mc_msi_set_affinity,
-};
-
-static int mc_irq_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
- unsigned int nr_irqs, void *args)
-{
- struct mc_pcie *port = domain->host_data;
- struct mc_msi *msi = &port->msi;
- void __iomem *bridge_base_addr =
- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
- unsigned long bit;
- u32 val;
-
- mutex_lock(&msi->lock);
- bit = find_first_zero_bit(msi->used, msi->num_vectors);
- if (bit >= msi->num_vectors) {
- mutex_unlock(&msi->lock);
- return -ENOSPC;
- }
-
- set_bit(bit, msi->used);
-
- irq_domain_set_info(domain, virq, bit, &mc_msi_bottom_irq_chip,
- domain->host_data, handle_edge_irq, NULL, NULL);
-
- /* Enable MSI interrupts */
- val = readl_relaxed(bridge_base_addr + IMASK_LOCAL);
- val |= PM_MSI_INT_MSI_MASK;
- writel_relaxed(val, bridge_base_addr + IMASK_LOCAL);
-
- mutex_unlock(&msi->lock);
-
- return 0;
-}
-
-static void mc_irq_msi_domain_free(struct irq_domain *domain, unsigned int virq,
- unsigned int nr_irqs)
-{
- struct irq_data *d = irq_domain_get_irq_data(domain, virq);
- struct mc_pcie *port = irq_data_get_irq_chip_data(d);
- struct mc_msi *msi = &port->msi;
-
- mutex_lock(&msi->lock);
-
- if (test_bit(d->hwirq, msi->used))
- __clear_bit(d->hwirq, msi->used);
- else
- dev_err(port->dev, "trying to free unused MSI%lu\n", d->hwirq);
-
- mutex_unlock(&msi->lock);
-}
-
-static const struct irq_domain_ops msi_domain_ops = {
- .alloc = mc_irq_msi_domain_alloc,
- .free = mc_irq_msi_domain_free,
-};
-
-static struct irq_chip mc_msi_irq_chip = {
- .name = "Microchip PCIe MSI",
- .irq_ack = irq_chip_ack_parent,
- .irq_mask = pci_msi_mask_irq,
- .irq_unmask = pci_msi_unmask_irq,
-};
-
-static struct msi_domain_info mc_msi_domain_info = {
- .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
- MSI_FLAG_PCI_MSIX),
- .chip = &mc_msi_irq_chip,
-};
-
-static int mc_allocate_msi_domains(struct mc_pcie *port)
-{
- struct device *dev = port->dev;
- struct fwnode_handle *fwnode = of_node_to_fwnode(dev->of_node);
- struct mc_msi *msi = &port->msi;
-
- mutex_init(&port->msi.lock);
-
- msi->dev_domain = irq_domain_add_linear(NULL, msi->num_vectors,
- &msi_domain_ops, port);
- if (!msi->dev_domain) {
- dev_err(dev, "failed to create IRQ domain\n");
- return -ENOMEM;
- }
-
- msi->msi_domain = pci_msi_create_irq_domain(fwnode, &mc_msi_domain_info,
- msi->dev_domain);
- if (!msi->msi_domain) {
- dev_err(dev, "failed to create MSI domain\n");
- irq_domain_remove(msi->dev_domain);
- return -ENOMEM;
- }
-
- return 0;
-}
-
-static void mc_handle_intx(struct irq_desc *desc)
-{
- struct mc_pcie *port = irq_desc_get_handler_data(desc);
- struct irq_chip *chip = irq_desc_get_chip(desc);
- struct device *dev = port->dev;
- void __iomem *bridge_base_addr =
- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
- unsigned long status;
- u32 bit;
- int ret;
-
- chained_irq_enter(chip, desc);
-
- status = readl_relaxed(bridge_base_addr + ISTATUS_LOCAL);
- if (status & PM_MSI_INT_INTX_MASK) {
- status &= PM_MSI_INT_INTX_MASK;
- status >>= PM_MSI_INT_INTX_SHIFT;
- for_each_set_bit(bit, &status, PCI_NUM_INTX) {
- ret = generic_handle_domain_irq(port->intx_domain, bit);
- if (ret)
- dev_err_ratelimited(dev, "bad INTx IRQ %d\n",
- bit);
- }
- }
-
- chained_irq_exit(chip, desc);
-}
-
-static void mc_ack_intx_irq(struct irq_data *data)
-{
- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
- void __iomem *bridge_base_addr =
- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
- u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
-
- writel_relaxed(mask, bridge_base_addr + ISTATUS_LOCAL);
-}
-
-static void mc_mask_intx_irq(struct irq_data *data)
-{
- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
- void __iomem *bridge_base_addr =
- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
- unsigned long flags;
- u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
- u32 val;
-
- raw_spin_lock_irqsave(&port->lock, flags);
- val = readl_relaxed(bridge_base_addr + IMASK_LOCAL);
- val &= ~mask;
- writel_relaxed(val, bridge_base_addr + IMASK_LOCAL);
- raw_spin_unlock_irqrestore(&port->lock, flags);
-}
-
-static void mc_unmask_intx_irq(struct irq_data *data)
-{
- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
- void __iomem *bridge_base_addr =
- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
- unsigned long flags;
- u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
- u32 val;
-
- raw_spin_lock_irqsave(&port->lock, flags);
- val = readl_relaxed(bridge_base_addr + IMASK_LOCAL);
- val |= mask;
- writel_relaxed(val, bridge_base_addr + IMASK_LOCAL);
- raw_spin_unlock_irqrestore(&port->lock, flags);
-}
-
-static struct irq_chip mc_intx_irq_chip = {
- .name = "Microchip PCIe INTx",
- .irq_ack = mc_ack_intx_irq,
- .irq_mask = mc_mask_intx_irq,
- .irq_unmask = mc_unmask_intx_irq,
-};
-
-static int mc_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
- irq_hw_number_t hwirq)
-{
- irq_set_chip_and_handler(irq, &mc_intx_irq_chip, handle_level_irq);
- irq_set_chip_data(irq, domain->host_data);
-
- return 0;
-}
-
-static const struct irq_domain_ops intx_domain_ops = {
- .map = mc_pcie_intx_map,
-};
-
static inline u32 reg_to_event(u32 reg, struct event_map field)
{
return (reg & field.reg_mask) ? BIT(field.event_bit) : 0;
@@ -704,11 +340,10 @@ static u32 local_events(void __iomem *addr)
return val;
}
-static u32 get_events(struct mc_pcie *port)
+static u32 get_events(struct plda_pcie *port)
{
- void __iomem *bridge_base_addr =
- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
- void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
+ void __iomem *bridge_base_addr = port->bridge_addr;
+ void __iomem *ctrl_base_addr = port->bridge_addr + MC_PCIE_CTRL_ADDR_OFFSET;
u32 events = 0;
events |= pcie_events(ctrl_base_addr + PCIE_EVENT_INT);
@@ -721,7 +356,7 @@ static u32 get_events(struct mc_pcie *port)
static irqreturn_t mc_event_handler(int irq, void *dev_id)
{
- struct mc_pcie *port = dev_id;
+ struct plda_pcie *port = dev_id;
struct device *dev = port->dev;
struct irq_data *data;
@@ -735,31 +370,14 @@ static irqreturn_t mc_event_handler(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static void mc_handle_event(struct irq_desc *desc)
-{
- struct mc_pcie *port = irq_desc_get_handler_data(desc);
- unsigned long events;
- u32 bit;
- struct irq_chip *chip = irq_desc_get_chip(desc);
-
- chained_irq_enter(chip, desc);
-
- events = get_events(port);
-
- for_each_set_bit(bit, &events, NUM_EVENTS)
- generic_handle_domain_irq(port->event_domain, bit);
-
- chained_irq_exit(chip, desc);
-}
-
static void mc_ack_event_irq(struct irq_data *data)
{
- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
+ struct plda_pcie *port = irq_data_get_irq_chip_data(data);
u32 event = data->hwirq;
void __iomem *addr;
u32 mask;
- addr = port->axi_base_addr + event_descs[event].base +
+ addr = port->bridge_addr + event_descs[event].base +
event_descs[event].offset;
mask = event_descs[event].mask;
mask |= event_descs[event].enb_mask;
@@ -769,13 +387,13 @@ 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 *port = irq_data_get_irq_chip_data(data);
u32 event = data->hwirq;
void __iomem *addr;
u32 mask;
u32 val;
- addr = port->axi_base_addr + event_descs[event].base +
+ addr = port->bridge_addr + event_descs[event].base +
event_descs[event].mask_offset;
mask = event_descs[event].mask;
if (event_descs[event].enb_mask) {
@@ -799,13 +417,13 @@ 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 *port = irq_data_get_irq_chip_data(data);
u32 event = data->hwirq;
void __iomem *addr;
u32 mask;
u32 val;
- addr = port->axi_base_addr + event_descs[event].base +
+ addr = port->bridge_addr + event_descs[event].base +
event_descs[event].mask_offset;
mask = event_descs[event].mask;
@@ -887,123 +505,42 @@ static int mc_pcie_init_clks(struct device *dev)
return 0;
}
-static int mc_pcie_init_irq_domains(struct mc_pcie *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, NUM_EVENTS,
- &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 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)
-{
- u32 atr_sz = ilog2(size) - 1;
- u32 val;
-
- if (index == 0)
- val = PCIE_CONFIG_INTERFACE;
- else
- val = PCIE_TX_RX_INTERFACE;
-
- writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
- ATR0_AXI4_SLV0_TRSL_PARAM);
-
- val = lower_32_bits(axi_addr) | (atr_sz << ATR_SIZE_SHIFT) |
- ATR_IMPL_ENABLE;
- writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
- ATR0_AXI4_SLV0_SRCADDR_PARAM);
-
- val = upper_32_bits(axi_addr);
- writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
- ATR0_AXI4_SLV0_SRC_ADDR);
-
- val = lower_32_bits(pci_addr);
- writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
- ATR0_AXI4_SLV0_TRSL_ADDR_LSB);
-
- val = upper_32_bits(pci_addr);
- writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
- ATR0_AXI4_SLV0_TRSL_ADDR_UDW);
-
- val = readl(bridge_base_addr + ATR0_PCIE_WIN0_SRCADDR_PARAM);
- val |= (ATR0_PCIE_ATR_SIZE << ATR0_PCIE_ATR_SIZE_SHIFT);
- writel(val, bridge_base_addr + ATR0_PCIE_WIN0_SRCADDR_PARAM);
- writel(0, bridge_base_addr + ATR0_PCIE_WIN0_SRC_ADDR);
-}
+static const struct plda_pcie_ops pcie_ops = {
+ .get_events = get_events,
+};
-static int mc_pcie_setup_windows(struct platform_device *pdev,
- struct mc_pcie *port)
+static int mc_request_evt_irq(struct plda_pcie *plda, int event_irq,
+ int evt)
{
- void __iomem *bridge_base_addr =
- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
- struct pci_host_bridge *bridge = platform_get_drvdata(pdev);
- struct resource_entry *entry;
- u64 pci_addr;
- u32 index = 1;
-
- 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));
- index++;
- }
- }
+ struct device *dev = plda->dev;
- return 0;
+ return devm_request_irq(dev, event_irq, mc_event_handler,
+ 0, event_cause[evt].sym, plda);
}
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);
struct mc_pcie *port;
+ struct plda_pcie *plda;
void __iomem *bridge_base_addr;
void __iomem *ctrl_base_addr;
+ struct plda_evt evt = {&event_domain_ops, mc_request_evt_irq,
+ EVENT_LOCAL_PM_MSI_INT_INTX,
+ EVENT_LOCAL_PM_MSI_INT_MSI};
int ret;
- int irq;
- int i, intx_irq, msi_irq, event_irq;
u32 val;
- int err;
port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
if (!port)
return -ENOMEM;
- port->dev = dev;
+
+ plda = &port->plda;
+ plda->dev = dev;
+ plda->ops = &pcie_ops;
+ plda->num_events = NUM_EVENTS;
ret = mc_pcie_init_clks(dev);
if (ret) {
@@ -1017,57 +554,12 @@ static int mc_platform_init(struct pci_config_window *cfg)
bridge_base_addr = port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
+ plda->bridge_addr = bridge_base_addr;
- port->msi.vector_phy = MSI_ADDR;
- port->msi.num_vectors = MC_NUM_MSI_IRQS;
- ret = mc_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 < 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;
- }
-
- err = devm_request_irq(dev, event_irq, mc_event_handler,
- 0, event_cause[i].sym, port);
- if (err) {
- dev_err(dev, "failed to request IRQ %d\n", event_irq);
- return err;
- }
- }
-
- intx_irq = irq_create_mapping(port->event_domain,
- EVENT_LOCAL_PM_MSI_INT_INTX);
- 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, mc_handle_intx, port);
-
- msi_irq = irq_create_mapping(port->event_domain,
- EVENT_LOCAL_PM_MSI_INT_MSI);
- if (!msi_irq)
- return -ENXIO;
-
- /* Plug the MSI chained handler */
- irq_set_chained_handler_and_data(msi_irq, mc_handle_msi, port);
-
- /* Plug the main event chained handler */
- irq_set_chained_handler_and_data(irq, mc_handle_event, port);
-
+ plda_set_default_msi(&plda->msi);
+ plda_pcie_init_irq(plda, pdev, &evt);
/* Hardware doesn't setup MSI by default */
- mc_pcie_enable_msi(port, cfg->win);
+ plda_pcie_enable_msi(plda);
val = readl_relaxed(bridge_base_addr + IMASK_LOCAL);
val |= PM_MSI_INT_INTX_MASK;
@@ -1100,10 +592,10 @@ static int mc_platform_init(struct pci_config_window *cfg)
writel_relaxed(GENMASK(31, 0), bridge_base_addr + ISTATUS_HOST);
/* Configure Address Translation Table 0 for PCIe config space */
- mc_pcie_setup_window(bridge_base_addr, 0, cfg->res.start & 0xffffffff,
- cfg->res.start, resource_size(&cfg->res));
+ plda_pcie_setup_window(bridge_base_addr, 0, cfg->res.start & 0xffffffff,
+ cfg->res.start, resource_size(&cfg->res));
- return mc_pcie_setup_windows(pdev, port);
+ return plda_pcie_setup_iomems(&port->plda, bridge);
}
static const struct pci_ecam_ops mc_ecam_ops = {
diff --git a/drivers/pci/controller/plda/pcie-plda-host.c b/drivers/pci/controller/plda/pcie-plda-host.c
new file mode 100644
index 000000000000..ca720430721c
--- /dev/null
+++ b/drivers/pci/controller/plda/pcie-plda-host.c
@@ -0,0 +1,554 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PLDA PCIe XpressRich host controller driver
+ *
+ * Copyright (C) 2023 Microchip Co. Ltd
+ * StarFive Co. Ltd.
+ *
+ * Author: Daire McNamara <daire.mcnamara@microchip.com>
+ * Author: Minda Chen <minda.chen@starfivetech.com>
+ */
+
+#include <linux/irqchip/chained_irq.h>
+#include <linux/irqdomain.h>
+#include <linux/msi.h>
+#include <linux/of_address.h>
+#include <linux/of_pci.h>
+#include <linux/pci_regs.h>
+#include <linux/pci-ecam.h>
+#include <linux/platform_device.h>
+
+#include "pcie-plda.h"
+
+void plda_pcie_enable_msi(struct plda_pcie *port)
+{
+ struct plda_msi *msi = &port->msi;
+ void __iomem *base = port->bridge_addr;
+ u32 cap_offset = MSI_CAP_CTRL_OFFSET;
+ u16 msg_ctrl = readw_relaxed(base + cap_offset + PCI_MSI_FLAGS);
+
+ msg_ctrl |= PCI_MSI_FLAGS_ENABLE;
+ msg_ctrl &= ~PCI_MSI_FLAGS_QMASK;
+ msg_ctrl |= MSI_MAX_Q_AVAIL;
+ msg_ctrl &= ~PCI_MSI_FLAGS_QSIZE;
+ msg_ctrl |= MSI_Q_SIZE;
+ msg_ctrl |= PCI_MSI_FLAGS_64BIT;
+
+ writew_relaxed(msg_ctrl, base + cap_offset + PCI_MSI_FLAGS);
+
+ writel_relaxed(lower_32_bits(msi->vector_phy),
+ base + cap_offset + PCI_MSI_ADDRESS_LO);
+ writel_relaxed(upper_32_bits(msi->vector_phy),
+ base + cap_offset + PCI_MSI_ADDRESS_HI);
+}
+EXPORT_SYMBOL_GPL(plda_pcie_enable_msi);
+
+static void plda_handle_msi(struct irq_desc *desc)
+{
+ struct plda_pcie *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(BIT(PM_MSI_INT_MSI_SHIFT), 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 *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 *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 *port = domain->host_data;
+ struct plda_msi *msi = &port->msi;
+ void __iomem *bridge_base_addr = port->bridge_addr;
+ unsigned long bit;
+ u32 val;
+
+ 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);
+
+ /* Enable MSI interrupts */
+ val = readl_relaxed(bridge_base_addr + IMASK_LOCAL);
+ val |= PM_MSI_INT_MSI_MASK;
+ writel_relaxed(val, bridge_base_addr + IMASK_LOCAL);
+
+ 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 *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 *port)
+{
+ struct device *dev = port->dev;
+ struct fwnode_handle *fwnode = of_node_to_fwnode(dev->of_node);
+ struct plda_msi *msi = &port->msi;
+
+ raw_spin_lock_init(&port->lock);
+ 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 *port = irq_desc_get_handler_data(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ struct device *dev = port->dev;
+ unsigned long status;
+ u32 bit;
+ int ret;
+
+ chained_irq_enter(chip, desc);
+ status = readl_relaxed(port->bridge_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 %d\n",
+ bit, ret);
+ }
+ }
+ chained_irq_exit(chip, desc);
+}
+
+static void plda_ack_intx_irq(struct irq_data *data)
+{
+ struct plda_pcie *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 *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 *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 void plda_handle_event(struct irq_desc *desc)
+{
+ struct plda_pcie *port = irq_desc_get_handler_data(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ unsigned long events = 0;
+ u32 bit, val, origin;
+
+ chained_irq_enter(chip, desc);
+
+ if (port->ops && port->ops->get_events) {
+ events = port->ops->get_events(port);
+ } else {
+ val = readl_relaxed(port->bridge_addr + ISTATUS_LOCAL);
+ origin = val;
+ val = val >> A_ATR_EVT_POST_ERR_SHIFT;
+ events |= val & 0xff;
+ if (origin & PM_MSI_INT_INTX_MASK)
+ events |= BIT(EVENT_PM_MSI_INT_INTX);
+ val = (origin >> PM_MSI_INT_MSI_SHIFT) & 0xf;
+ events |= val << EVENT_PM_MSI_INT_MSI;
+ }
+
+ for_each_set_bit(bit, &events, port->num_events)
+ generic_handle_domain_irq(port->event_domain, bit);
+
+ chained_irq_exit(chip, desc);
+}
+
+static u32 plda_hwirq_to_mask(int hwirq)
+{
+ u32 mask;
+
+ if (hwirq < EVENT_PM_MSI_INT_INTX)
+ mask = BIT(hwirq + A_ATR_EVT_POST_ERR_SHIFT);
+ else if (hwirq == EVENT_PM_MSI_INT_INTX)
+ mask = PM_MSI_INT_INTX_MASK;
+ else
+ mask = BIT(hwirq + PM_MSI_TO_MASK_OFFSET);
+
+ return mask;
+}
+
+static void plda_ack_event_irq(struct irq_data *data)
+{
+ struct plda_pcie *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 *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 *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 int plda_pcie_event_map(struct irq_domain *domain, unsigned int irq,
+ irq_hw_number_t hwirq)
+{
+ irq_set_chip_and_handler(irq, &plda_event_irq_chip, handle_level_irq);
+ irq_set_chip_data(irq, domain->host_data);
+
+ return 0;
+}
+
+static const struct irq_domain_ops event_domain_ops = {
+ .map = plda_pcie_event_map,
+};
+
+static irqreturn_t plda_event_handler(int irq, void *dev_id)
+{
+ return IRQ_HANDLED;
+}
+
+static int plda_pcie_init_irq_domains(struct plda_pcie *port,
+ const struct irq_domain_ops *domain_ops)
+{
+ 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,
+ 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(node, PCI_NUM_INTX, &intx_domain_ops, port);
+ if (!port->intx_domain) {
+ dev_err(dev, "Failed to get a 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);
+}
+
+int plda_pcie_init_irq(struct plda_pcie *port, struct platform_device *pdev,
+ struct plda_evt *evt)
+{
+ struct device *dev = port->dev;
+ const struct irq_domain_ops *ops;
+ int i;
+ int ret, err, event_irq, intx_irq, msi_irq;
+
+ if (!evt->domain_ops)
+ ops = &event_domain_ops;
+ else
+ ops = evt->domain_ops;
+
+ ret = plda_pcie_init_irq_domains(port, ops);
+ if (ret)
+ return ret;
+
+ port->irq = platform_get_irq(pdev, 0);
+ if (port->irq < 0) {
+ dev_err(dev, "Failed to get IRQ: %d\n", port->irq);
+ return port->irq;
+ }
+
+ 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 (evt->request_evt_irq)
+ err = evt->request_evt_irq(port, event_irq, i);
+ else
+ err = devm_request_irq(dev, event_irq,
+ plda_event_handler,
+ 0, NULL, port);
+ if (err) {
+ dev_err(dev, "failed to request IRQ %d\n", event_irq);
+ return err;
+ }
+ }
+
+ intx_irq = irq_create_mapping(port->event_domain,
+ evt->intx_evt);
+ if (!intx_irq) {
+ dev_err(dev, "failed to map INTx interrupt\n");
+ return -ENXIO;
+ }
+ port->intx_irq = intx_irq;
+
+ /* 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,
+ evt->msi_evt);
+ if (!msi_irq)
+ return -ENXIO;
+
+ port->msi_irq = msi_irq;
+ /* 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(port->irq, plda_handle_event, port);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(plda_pcie_init_irq);
+
+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;
+
+ if (index == 0)
+ val = PCIE_CONFIG_INTERFACE;
+ else
+ val = PCIE_TX_RX_INTERFACE;
+
+ writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
+ ATR0_AXI4_SLV0_TRSL_PARAM);
+
+ val = lower_32_bits(axi_addr) | (atr_sz << ATR_SIZE_SHIFT) |
+ ATR_IMPL_ENABLE;
+ writel_relaxed(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
+ ATR0_AXI4_SLV0_SRCADDR_PARAM);
+
+ val = upper_32_bits(axi_addr);
+ writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
+ ATR0_AXI4_SLV0_SRC_ADDR);
+
+ val = lower_32_bits(pci_addr);
+ writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
+ ATR0_AXI4_SLV0_TRSL_ADDR_LSB);
+
+ val = upper_32_bits(pci_addr);
+ writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
+ ATR0_AXI4_SLV0_TRSL_ADDR_UDW);
+
+ val = readl(bridge_base_addr + ATR0_PCIE_WIN0_SRCADDR_PARAM);
+ val |= (ATR0_PCIE_ATR_SIZE << ATR0_PCIE_ATR_SIZE_SHIFT);
+ writel(val, bridge_base_addr + ATR0_PCIE_WIN0_SRCADDR_PARAM);
+ writel(0, bridge_base_addr + ATR0_PCIE_WIN0_SRC_ADDR);
+}
+EXPORT_SYMBOL_GPL(plda_pcie_setup_window);
+
+int plda_pcie_setup_iomems(struct plda_pcie *port, struct pci_host_bridge *bridge)
+{
+ void __iomem *bridge_base_addr = port->bridge_addr;
+ struct resource_entry *entry;
+ u64 pci_addr;
+ u32 index = 1;
+
+ resource_list_for_each_entry(entry, &bridge->windows) {
+ if (resource_type(entry->res) == IORESOURCE_MEM) {
+ pci_addr = entry->res->start - entry->offset;
+ plda_pcie_setup_window(bridge_base_addr, index,
+ entry->res->start, pci_addr,
+ resource_size(entry->res));
+ index++;
+ }
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(plda_pcie_setup_iomems);
diff --git a/drivers/pci/controller/plda/pcie-plda.h b/drivers/pci/controller/plda/pcie-plda.h
new file mode 100644
index 000000000000..feb3a0d9ace5
--- /dev/null
+++ b/drivers/pci/controller/plda/pcie-plda.h
@@ -0,0 +1,173 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * PLDA PCIe host controller driver
+ */
+
+#ifndef _PCIE_PLDA_H
+#define _PCIE_PLDA_H
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/pci-epf.h>
+#include <linux/phy/phy.h>
+
+/* Number of MSI IRQs */
+#define PLDA_NUM_MSI_IRQS 32
+#define NUM_MSI_IRQS_CODED 5
+
+/* PCIe Bridge Phy Regs */
+#define PCIE_PCI_IDS_DW1 0x9c
+
+/* PCIe Config space MSI capability structure */
+#define MSI_CAP_CTRL_OFFSET 0xe0
+#define MSI_MAX_Q_AVAIL (NUM_MSI_IRQS_CODED << 1)
+#define MSI_Q_SIZE (NUM_MSI_IRQS_CODED << 4)
+
+#define IMASK_LOCAL 0x180
+#define DMA_END_ENGINE_0_MASK 0x00000000u
+#define DMA_END_ENGINE_0_SHIFT 0
+#define DMA_END_ENGINE_1_MASK 0x00000000u
+#define DMA_END_ENGINE_1_SHIFT 1
+#define DMA_ERROR_ENGINE_0_MASK BIT(8)
+#define DMA_ERROR_ENGINE_0_SHIFT 8
+#define DMA_ERROR_ENGINE_1_MASK BIT(9)
+#define DMA_ERROR_ENGINE_1_SHIFT 9
+#define DMA_END_MASK GENMASK(7, 0)
+#define DMA_ERR_MASK GENMASK(15, 8)
+#define DMA_ERR_SHIFT 8
+#define A_ATR_EVT_POST_ERR_MASK BIT(16)
+#define A_ATR_EVT_POST_ERR_SHIFT 16
+#define A_ATR_EVT_FETCH_ERR_MASK BIT(17)
+#define A_ATR_EVT_FETCH_ERR_SHIFT 17
+#define A_ATR_EVT_DISCARD_ERR_MASK BIT(18)
+#define A_ATR_EVT_DISCARD_ERR_SHIFT 18
+#define A_ATR_EVT_DOORBELL_MASK BIT(19)
+#define A_ATR_EVT_DOORBELL_SHIFT 19
+#define P_ATR_EVT_POST_ERR_MASK BIT(20)
+#define P_ATR_EVT_POST_ERR_SHIFT 20
+#define P_ATR_EVT_FETCH_ERR_MASK BIT(21)
+#define P_ATR_EVT_FETCH_ERR_SHIFT 21
+#define P_ATR_EVT_DISCARD_ERR_MASK BIT(22)
+#define P_ATR_EVT_DISCARD_ERR_SHIFT 22
+#define P_ATR_EVT_DOORBELL_MASK BIT(23)
+#define P_ATR_EVT_DOORBELL_SHIFT 23
+#define PM_MSI_INT_INTA_MASK BIT(24)
+#define PM_MSI_INT_INTA_SHIFT 24
+#define PM_MSI_INT_INTB_MASK BIT(25)
+#define PM_MSI_INT_INTB_SHIFT 25
+#define PM_MSI_INT_INTC_MASK BIT(26)
+#define PM_MSI_INT_INTC_SHIFT 26
+#define PM_MSI_INT_INTD_MASK BIT(27)
+#define PM_MSI_INT_INTD_SHIFT 27
+#define PM_MSI_INT_INTX_MASK GENMASK(27, 24)
+#define PM_MSI_INT_INTX_SHIFT 24
+#define PM_MSI_INT_MSI_MASK BIT(28)
+#define PM_MSI_INT_MSI_SHIFT 28
+#define PM_MSI_INT_AER_EVT_MASK BIT(29)
+#define PM_MSI_INT_AER_EVT_SHIFT 29
+#define PM_MSI_INT_EVENTS_MASK BIT(30)
+#define PM_MSI_INT_EVENTS_SHIFT 30
+#define PM_MSI_INT_SYS_ERR_MASK BIT(31)
+#define PM_MSI_INT_SYS_ERR_SHIFT 31
+
+#define ISTATUS_LOCAL 0x184
+#define IMASK_HOST 0x188
+#define ISTATUS_HOST 0x18c
+#define IMSI_ADDR 0x190
+#define ISTATUS_MSI 0x194
+
+/* PCIe Master table init defines */
+#define ATR0_PCIE_WIN0_SRCADDR_PARAM 0x600u
+#define ATR0_PCIE_ATR_SIZE 0x25
+#define ATR0_PCIE_ATR_SIZE_SHIFT 1
+#define ATR0_PCIE_WIN0_SRC_ADDR 0x604u
+#define ATR0_PCIE_WIN0_TRSL_ADDR_LSB 0x608u
+#define ATR0_PCIE_WIN0_TRSL_ADDR_UDW 0x60cu
+#define ATR0_PCIE_WIN0_TRSL_PARAM 0x610u
+
+/* PCIe AXI slave table init defines */
+#define ATR0_AXI4_SLV0_SRCADDR_PARAM 0x800u
+#define ATR_SIZE_SHIFT 1
+#define ATR_IMPL_ENABLE 1
+#define ATR0_AXI4_SLV0_SRC_ADDR 0x804u
+#define ATR0_AXI4_SLV0_TRSL_ADDR_LSB 0x808u
+#define ATR0_AXI4_SLV0_TRSL_ADDR_UDW 0x80cu
+#define ATR0_AXI4_SLV0_TRSL_PARAM 0x810u
+#define ATR0_AXI4_TABLE_OFFSET 0x20
+#define PCIE_TX_RX_INTERFACE 0x00000000u
+#define PCIE_CONFIG_INTERFACE 0x00000001u
+
+#define ATR_ENTRY_SIZE 32
+
+#define EVENT_A_ATR_EVT_POST_ERR 0
+#define EVENT_A_ATR_EVT_FETCH_ERR 1
+#define EVENT_A_ATR_EVT_DISCARD_ERR 2
+#define EVENT_A_ATR_EVT_DOORBELL 3
+#define EVENT_P_ATR_EVT_POST_ERR 4
+#define EVENT_P_ATR_EVT_FETCH_ERR 5
+#define EVENT_P_ATR_EVT_DISCARD_ERR 6
+#define EVENT_P_ATR_EVT_DOORBELL 7
+#define EVENT_PM_MSI_INT_INTX 8
+#define EVENT_PM_MSI_INT_MSI 9
+#define EVENT_PM_MSI_INT_AER_EVT 10
+#define EVENT_PM_MSI_INT_EVENTS 11
+#define EVENT_PM_MSI_INT_SYS_ERR 12
+#define NUM_PLDA_EVENTS 13
+
+#define PM_MSI_TO_MASK_OFFSET 19
+
+struct plda_pcie;
+
+struct plda_msi {
+ struct mutex lock; /* Protect used bitmap */
+ struct irq_domain *msi_domain;
+ struct irq_domain *dev_domain; /* inner_domain*/
+ u32 num_vectors;
+ u64 vector_phy;
+ DECLARE_BITMAP(used, PLDA_NUM_MSI_IRQS);
+};
+
+struct plda_pcie_ops {
+ int (*host_init)(struct plda_pcie *pcie);
+ void (*host_deinit)(struct plda_pcie *pcie);
+ u32 (*get_events)(struct plda_pcie *pcie);
+};
+
+struct plda_pcie {
+ struct pci_host_bridge *bridge;
+ void __iomem *bridge_addr;
+ void __iomem *config_base;
+ struct irq_domain *intx_domain;
+ struct irq_domain *event_domain;
+ struct device *dev;
+ raw_spinlock_t lock;
+ struct plda_msi msi;
+ const struct plda_pcie_ops *ops;
+ struct phy *phy;
+ int irq;
+ int msi_irq;
+ int intx_irq;
+ int num_events;
+};
+
+struct plda_evt {
+ const struct irq_domain_ops *domain_ops;
+ int (*request_evt_irq)(struct plda_pcie *pcie, int evt_irq, int event);
+ int intx_evt;
+ int msi_evt;
+};
+
+void plda_pcie_enable_msi(struct plda_pcie *port);
+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 plda_pcie *port, struct pci_host_bridge *host_bridge);
+int plda_pcie_init_irq(struct plda_pcie *port, struct platform_device *pdev,
+ struct plda_evt *evt);
+
+static inline void plda_set_default_msi(struct plda_msi *msi)
+{
+ msi->vector_phy = IMSI_ADDR;
+ msi->num_vectors = PLDA_NUM_MSI_IRQS;
+}
+#endif /* _PCIE_PLDA_H */
--
2.17.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 3/4] dt-bindings: PCI: Add StarFive JH7110 PCIe controller
2023-07-27 10:39 [PATCH v2 0/4] Refactoring Microchip PCIe driver and add StarFive PCIe Minda Chen
2023-07-27 10:39 ` [PATCH v2 1/4] dt-bindings: PCI: Add PLDA XpressRICH PCIe host common properties Minda Chen
2023-07-27 10:39 ` [PATCH v2 2/4] PCI: plda: Get common codes from Microchip PolarFire host Minda Chen
@ 2023-07-27 10:39 ` Minda Chen
2023-08-04 7:10 ` Conor Dooley
2023-08-10 22:47 ` Rob Herring
2023-07-27 10:39 ` [PATCH v2 4/4] PCI: starfive: Add " Minda Chen
` (2 subsequent siblings)
5 siblings, 2 replies; 19+ messages in thread
From: Minda Chen @ 2023-07-27 10:39 UTC (permalink / raw)
To: Krzysztof Wilczyński, Daire McNamara, Conor Dooley,
Rob Herring, Krzysztof Kozlowski, Bjorn Helgaas,
Lorenzo Pieralisi, Emil Renner Berthing
Cc: devicetree, linux-kernel, linux-pci, Philipp Zabel, Mason Huo,
Leyfoon Tan, Kevin Xie, Minda Chen
Add StarFive JH7110 SoC PCIe controller dt-bindings.
JH7110 using PLDA XpressRICH PCIe host controller IP.
Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
Reviewed-by: Hal Feng <hal.feng@starfivetech.com>
---
.../bindings/pci/starfive,jh7110-pcie.yaml | 133 ++++++++++++++++++
1 file changed, 133 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml
diff --git a/Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml b/Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml
new file mode 100644
index 000000000000..9273e029fb20
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml
@@ -0,0 +1,133 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/starfive,jh7110-pcie.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: StarFive JH7110 PCIe host controller
+
+maintainers:
+ - Kevin Xie <kevin.xie@starfivetech.com>
+
+allOf:
+ - $ref: /schemas/pci/pci-bus.yaml#
+ - $ref: plda,xpressrich3-axi-common.yaml#
+ - $ref: /schemas/interrupt-controller/msi-controller.yaml#
+ - $ref: /schemas/gpio/gpio-consumer-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
+ items:
+ - items:
+ - description: phandle to System Register Controller stg_syscon node.
+ - description: register0 offset of STG_SYSCONSAIF__SYSCFG register for PCIe.
+ - description: register1 offset of STG_SYSCONSAIF__SYSCFG register for PCIe.
+ - description: register2 offset of STG_SYSCONSAIF__SYSCFG register for PCIe.
+ - description: register3 offset of STG_SYSCONSAIF__SYSCFG register for PCIe.
+ description:
+ The phandle to System Register Controller syscon node and the offset
+ of STG_SYSCONSAIF__SYSCFG register for PCIe. Total 4 regsisters offset
+ for PCIe.
+
+ phys:
+ description:
+ Specified PHY is attached to PCIe controller.
+ maxItems: 1
+
+required:
+ - compatible
+ - clocks
+ - resets
+ - starfive,stg-syscon
+ - "#interrupt-cells"
+ - interrupt-map-mask
+ - interrupt-map
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ pcie0: pcie@2b000000 {
+ 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 0xc0 0xc4 0x130 0x1b8>;
+ 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-parent = <&pcie0>;
+ 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>;
+ reset-gpios = <&gpios 26 GPIO_ACTIVE_LOW>;
+ phys = <&pciephy0>;
+
+ pcie_intc0: interrupt-controller {
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ };
+ };
+ };
--
2.17.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 4/4] PCI: starfive: Add JH7110 PCIe controller
2023-07-27 10:39 [PATCH v2 0/4] Refactoring Microchip PCIe driver and add StarFive PCIe Minda Chen
` (2 preceding siblings ...)
2023-07-27 10:39 ` [PATCH v2 3/4] dt-bindings: PCI: Add StarFive JH7110 PCIe controller Minda Chen
@ 2023-07-27 10:39 ` Minda Chen
2023-08-04 1:46 ` [PATCH v2 0/4] Refactoring Microchip PCIe driver and add StarFive PCIe Minda Chen
2023-08-05 13:05 ` Emil Renner Berthing
5 siblings, 0 replies; 19+ messages in thread
From: Minda Chen @ 2023-07-27 10:39 UTC (permalink / raw)
To: Krzysztof Wilczyński, Daire McNamara, Conor Dooley,
Rob Herring, Krzysztof Kozlowski, Bjorn Helgaas,
Lorenzo Pieralisi, Emil Renner Berthing
Cc: devicetree, linux-kernel, linux-pci, Philipp Zabel, Mason Huo,
Leyfoon Tan, Kevin Xie, Minda Chen
Add StarFive JH7110 SoC PCIe controller platform
driver codes, and add host init/deinit to pcie-plda-host.c
Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
Co-developed-by: Kevin Xie <kevin.xie@starfivetech.com>
Reviewed-by: Mason Huo <mason.huo@starfivetech.com>
---
MAINTAINERS | 7 +
drivers/pci/controller/plda/Kconfig | 12 +
drivers/pci/controller/plda/Makefile | 1 +
drivers/pci/controller/plda/pcie-plda-host.c | 111 +++++
drivers/pci/controller/plda/pcie-plda.h | 71 ++-
drivers/pci/controller/plda/pcie-starfive.c | 438 +++++++++++++++++++
6 files changed, 639 insertions(+), 1 deletion(-)
create mode 100644 drivers/pci/controller/plda/pcie-starfive.c
diff --git a/MAINTAINERS b/MAINTAINERS
index ec59c6d00bf9..b265664d6062 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -20356,6 +20356,13 @@ S: Supported
F: Documentation/devicetree/bindings/watchdog/starfive*
F: drivers/watchdog/starfive-wdt.c
+STARFIVE JH71x0 PCIE DRIVER
+M: Kevin Xie <kevin.xie@starfivetech.com>
+L: linux-pci@vger.kernel.org
+S: Supported
+F: Documentation/devicetree/bindings/pci/starfive*
+F: drivers/pci/controller/plda/pcie-starfive.c
+
STATIC BRANCH/CALL
M: Peter Zijlstra <peterz@infradead.org>
M: Josh Poimboeuf <jpoimboe@kernel.org>
diff --git a/drivers/pci/controller/plda/Kconfig b/drivers/pci/controller/plda/Kconfig
index 28f5cf7ebb29..9813fd61376d 100644
--- a/drivers/pci/controller/plda/Kconfig
+++ b/drivers/pci/controller/plda/Kconfig
@@ -16,4 +16,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 OF && PCI_MSI
+ select PCIE_PLDA_HOST
+ help
+ Say Y here if you want to support the StarFive PCIe controller
+ in host mode. StarFive PCIe controller uses PLDA PCIe
+ core.
+ If you choose to build this driver as module it will
+ be dynamically linked and module will be called
+ pcie-starfive.ko
+
endmenu
diff --git a/drivers/pci/controller/plda/Makefile b/drivers/pci/controller/plda/Makefile
index 4340ab007f44..0ac6851bed48 100644
--- a/drivers/pci/controller/plda/Makefile
+++ b/drivers/pci/controller/plda/Makefile
@@ -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
diff --git a/drivers/pci/controller/plda/pcie-plda-host.c b/drivers/pci/controller/plda/pcie-plda-host.c
index ca720430721c..2575900c8ade 100644
--- a/drivers/pci/controller/plda/pcie-plda-host.c
+++ b/drivers/pci/controller/plda/pcie-plda-host.c
@@ -20,6 +20,15 @@
#include "pcie-plda.h"
+void __iomem *plda_pcie_map_bus(struct pci_bus *bus, unsigned int devfn,
+ int where)
+{
+ struct plda_pcie *pcie = bus->sysdata;
+
+ return pcie->config_base + PCIE_ECAM_OFFSET(bus->number, devfn, where);
+}
+EXPORT_SYMBOL_GPL(plda_pcie_map_bus);
+
void plda_pcie_enable_msi(struct plda_pcie *port)
{
struct plda_msi *msi = &port->msi;
@@ -552,3 +561,105 @@ int plda_pcie_setup_iomems(struct plda_pcie *port, struct pci_host_bridge *bridg
return 0;
}
EXPORT_SYMBOL_GPL(plda_pcie_setup_iomems);
+
+static void plda_pcie_irq_domain_deinit(struct plda_pcie *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 *pcie, struct pci_ops *ops)
+{
+ struct resource *cfg_res;
+ struct device *dev = pcie->dev;
+ int ret;
+ struct pci_host_bridge *bridge;
+ struct platform_device *pdev = to_platform_device(dev);
+ struct plda_evt evt = {NULL, NULL, EVENT_PM_MSI_INT_INTX,
+ EVENT_PM_MSI_INT_MSI};
+
+ pcie->bridge_addr =
+ devm_platform_ioremap_resource_byname(pdev, "apb");
+
+ if (IS_ERR(pcie->bridge_addr))
+ return dev_err_probe(dev, PTR_ERR(pcie->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");
+
+ pcie->config_base = devm_ioremap_resource(dev, cfg_res);
+ if (IS_ERR(pcie->config_base))
+ return dev_err_probe(dev, PTR_ERR(pcie->config_base),
+ "failed to map config memory\n");
+
+ pcie->phy = devm_phy_optional_get(dev, NULL);
+ if (IS_ERR(pcie->phy))
+ return dev_err_probe(dev, PTR_ERR(pcie->phy),
+ "failed to get pcie phy\n");
+
+ bridge = devm_pci_alloc_host_bridge(dev, 0);
+ if (!bridge)
+ return dev_err_probe(dev, -ENOMEM,
+ "failed to alloc bridge\n");
+
+ pcie->bridge = bridge;
+
+ if (pcie->ops->host_init) {
+ ret = pcie->ops->host_init(pcie);
+ if (ret)
+ return ret;
+ }
+
+ plda_pcie_setup_window(pcie->bridge_addr, 0, cfg_res->start, 0,
+ resource_size(cfg_res));
+ plda_pcie_setup_iomems(pcie, bridge);
+ plda_set_default_msi(&pcie->msi);
+ ret = plda_pcie_init_irq(pcie, pdev, &evt);
+ if (ret)
+ goto err_host;
+
+ /* Set default bus ops */
+ bridge->ops = ops;
+ bridge->sysdata = pcie;
+
+ plda_pcie_enable_msi(pcie);
+
+ ret = pci_host_probe(bridge);
+ if (ret < 0) {
+ dev_err(dev, "failed to pci host probe: %d\n", ret);
+ goto err_probe;
+ }
+
+ return ret;
+
+err_probe:
+ plda_pcie_irq_domain_deinit(pcie);
+err_host:
+ if (pcie->ops->host_deinit)
+ pcie->ops->host_deinit(pcie);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(plda_pcie_host_init);
+
+void plda_pcie_host_deinit(struct plda_pcie *pcie)
+{
+ pci_stop_root_bus(pcie->bridge->bus);
+ pci_remove_root_bus(pcie->bridge->bus);
+
+ plda_pcie_irq_domain_deinit(pcie);
+
+ if (pcie->ops->host_deinit)
+ pcie->ops->host_deinit(pcie);
+}
+EXPORT_SYMBOL_GPL(plda_pcie_host_deinit);
diff --git a/drivers/pci/controller/plda/pcie-plda.h b/drivers/pci/controller/plda/pcie-plda.h
index feb3a0d9ace5..ea933f00f76d 100644
--- a/drivers/pci/controller/plda/pcie-plda.h
+++ b/drivers/pci/controller/plda/pcie-plda.h
@@ -10,18 +10,25 @@
#include <linux/pci.h>
#include <linux/pci-epf.h>
#include <linux/phy/phy.h>
+#include <linux/bitfield.h>
/* Number of MSI IRQs */
#define PLDA_NUM_MSI_IRQS 32
#define NUM_MSI_IRQS_CODED 5
/* PCIe Bridge Phy Regs */
+#define GEN_SETTINGS 0x80
+#define RP_ENABLE 1
#define PCIE_PCI_IDS_DW1 0x9c
-
+#define IDS_CLASS_CODE_SHIFT 16
+#define PCI_MISC 0xb4
+#define PHY_FUNCTION_DIS BIT(15)
/* PCIe Config space MSI capability structure */
#define MSI_CAP_CTRL_OFFSET 0xe0
#define MSI_MAX_Q_AVAIL (NUM_MSI_IRQS_CODED << 1)
#define MSI_Q_SIZE (NUM_MSI_IRQS_CODED << 4)
+#define PCIE_WINROM 0xfc
+#define PREF_MEM_WIN_64_SUPPORT BIT(3)
#define IMASK_LOCAL 0x180
#define DMA_END_ENGINE_0_MASK 0x00000000u
@@ -75,6 +82,8 @@
#define ISTATUS_HOST 0x18c
#define IMSI_ADDR 0x190
#define ISTATUS_MSI 0x194
+#define PMSG_SUPPORT_RX 0x3f0
+#define PMSG_LTR_SUPPORT BIT(2)
/* PCIe Master table init defines */
#define ATR0_PCIE_WIN0_SRCADDR_PARAM 0x600u
@@ -97,6 +106,8 @@
#define PCIE_TX_RX_INTERFACE 0x00000000u
#define PCIE_CONFIG_INTERFACE 0x00000001u
+#define CONFIG_SPACE_ADDR 0x1000u
+
#define ATR_ENTRY_SIZE 32
#define EVENT_A_ATR_EVT_POST_ERR 0
@@ -131,6 +142,7 @@ struct plda_pcie_ops {
int (*host_init)(struct plda_pcie *pcie);
void (*host_deinit)(struct plda_pcie *pcie);
u32 (*get_events)(struct plda_pcie *pcie);
+ bool (*link_up)(struct plda_pcie *pcie);
};
struct plda_pcie {
@@ -157,6 +169,7 @@ struct plda_evt {
int msi_evt;
};
+void __iomem *plda_pcie_map_bus(struct pci_bus *bus, unsigned int devfn, int where);
void plda_pcie_enable_msi(struct plda_pcie *port);
void plda_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,
phys_addr_t axi_addr, phys_addr_t pci_addr,
@@ -164,10 +177,66 @@ void plda_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,
int plda_pcie_setup_iomems(struct plda_pcie *port, struct pci_host_bridge *host_bridge);
int plda_pcie_init_irq(struct plda_pcie *port, struct platform_device *pdev,
struct plda_evt *evt);
+int plda_pcie_host_init(struct plda_pcie *pcie, struct pci_ops *ops);
+void plda_pcie_host_deinit(struct plda_pcie *pcie);
static inline void plda_set_default_msi(struct plda_msi *msi)
{
msi->vector_phy = IMSI_ADDR;
msi->num_vectors = PLDA_NUM_MSI_IRQS;
}
+
+static inline void plda_pcie_enable_root_port(struct plda_pcie *plda)
+{
+ u32 value;
+
+ value = readl_relaxed(plda->bridge_addr + GEN_SETTINGS);
+ value |= RP_ENABLE;
+ writel_relaxed(value, plda->bridge_addr + GEN_SETTINGS);
+}
+
+static inline void plda_pcie_set_standard_class(struct plda_pcie *plda)
+{
+ u32 value;
+
+ value = readl_relaxed(plda->bridge_addr + PCIE_PCI_IDS_DW1);
+ value &= 0xff;
+ value |= (PCI_CLASS_BRIDGE_PCI << IDS_CLASS_CODE_SHIFT);
+ writel_relaxed(value, plda->bridge_addr + PCIE_PCI_IDS_DW1);
+}
+
+static inline void plda_pcie_set_pref_win_64bit(struct plda_pcie *plda)
+{
+ u32 value;
+
+ value = readl_relaxed(plda->bridge_addr + PCIE_WINROM);
+ value |= PREF_MEM_WIN_64_SUPPORT;
+ writel_relaxed(value, plda->bridge_addr + PCIE_WINROM);
+}
+
+static inline void plda_pcie_disable_ltr(struct plda_pcie *plda)
+{
+ u32 value;
+
+ value = readl_relaxed(plda->bridge_addr + PMSG_SUPPORT_RX);
+ value &= ~PMSG_LTR_SUPPORT;
+ writel_relaxed(value, plda->bridge_addr + PMSG_SUPPORT_RX);
+}
+
+static inline void plda_pcie_disable_func(struct plda_pcie *plda)
+{
+ u32 value;
+
+ value = readl_relaxed(plda->bridge_addr + PCI_MISC);
+ value |= PHY_FUNCTION_DIS;
+ writel_relaxed(value, plda->bridge_addr + PCI_MISC);
+}
+
+static inline void plda_pcie_write_rc_bar(struct plda_pcie *plda, u64 val)
+{
+ void __iomem *addr = plda->bridge_addr + CONFIG_SPACE_ADDR;
+
+ writel_relaxed(val & 0xffffffff, addr + PCI_BASE_ADDRESS_0);
+ writel_relaxed(val >> 32, addr + PCI_BASE_ADDRESS_1);
+}
#endif /* _PCIE_PLDA_H */
diff --git a/drivers/pci/controller/plda/pcie-starfive.c b/drivers/pci/controller/plda/pcie-starfive.c
new file mode 100644
index 000000000000..9234e9fd5428
--- /dev/null
+++ b/drivers/pci/controller/plda/pcie-starfive.c
@@ -0,0 +1,438 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * PCIe host controller driver for StarFive JH7110 Soc.
+ *
+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/interrupt.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_pci.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include "../../pci.h"
+
+#include "pcie-plda.h"
+
+#define DATA_LINK_ACTIVE BIT(5)
+#define PREF_MEM_WIN_64_SUPPORT BIT(3)
+#define PMSG_LTR_SUPPORT BIT(2)
+#define LINK_SPEED_GEN2 BIT(12)
+#define PHY_FUNCTION_DIS BIT(15)
+#define PCIE_FUNC_NUM 4
+
+/* system control */
+#define STG_SYSCON_K_RP_NEP BIT(8)
+#define STG_SYSCON_AXI4_SLVL_PHY_AWFUNC(x) FIELD_PREP(GENMASK(12, 9), x)
+#define STG_SYSCON_AXI4_SLVL_PHY_ARFUNC(x) FIELD_PREP(GENMASK(20, 17), x)
+#define STG_SYSCON_AXI4_SLVL_ARFUNC_MASK GENMASK(22, 8)
+#define STG_SYSCON_AXI4_SLVL_AWFUNC_MASK GENMASK(14, 0)
+#define STG_SYSCON_CLKREQ BIT(22)
+#define STG_SYSCON_CKREF_SRC_SHIFT 18
+#define STG_SYSCON_CKREF_SRC_MASK GENMASK(19, 18)
+
+/* Parameters for the waiting for link up routine */
+#define LINK_WAIT_MAX_RETRIES 10
+#define LINK_WAIT_USLEEP_MIN 90000
+#define LINK_WAIT_USLEEP_MAX 100000
+
+struct starfive_jh7110_pcie {
+ struct plda_pcie plda;
+ struct reset_control *resets;
+ struct clk_bulk_data *clks;
+ struct regmap *reg_syscon;
+ struct gpio_desc *power_gpio;
+ struct gpio_desc *reset_gpio;
+
+ u32 stg_arfun;
+ u32 stg_awfun;
+ u32 stg_rp_nep;
+ u32 stg_lnksta;
+
+ int num_clks;
+};
+
+/*
+ * The BAR0/1 of bridge should be hidden during enumeration to
+ * avoid the sizing and resource allocation by PCIe core.
+ */
+static bool starfive_pcie_hide_rc_bar(struct pci_bus *bus, unsigned int devfn,
+ int offset)
+{
+ if (pci_is_root_bus(bus) && !devfn &&
+ (offset == PCI_BASE_ADDRESS_0 || offset == PCI_BASE_ADDRESS_1))
+ return true;
+
+ return false;
+}
+
+int starfive_pcie_config_write(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 value)
+{
+ if (starfive_pcie_hide_rc_bar(bus, devfn, where))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ return pci_generic_config_write(bus, devfn, where, size, value);
+}
+
+int starfive_pcie_config_read(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 *value)
+{
+ if (starfive_pcie_hide_rc_bar(bus, devfn, where))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ return pci_generic_config_read(bus, devfn, where, size, value);
+}
+
+static int starfive_pcie_parse_dt(struct starfive_jh7110_pcie *pcie, struct device *dev)
+{
+ unsigned int args[4];
+
+ pcie->num_clks = devm_clk_bulk_get_all(dev, &pcie->clks);
+ if (pcie->num_clks < 0)
+ return dev_err_probe(dev, -ENODEV,
+ "failed to get pcie clocks\n");
+
+ pcie->resets = devm_reset_control_array_get_exclusive(dev);
+ if (IS_ERR(pcie->resets))
+ return dev_err_probe(dev, PTR_ERR(pcie->resets),
+ "failed to get pcie resets");
+
+ pcie->reg_syscon =
+ syscon_regmap_lookup_by_phandle_args(dev->of_node,
+ "starfive,stg-syscon", 4, args);
+
+ if (IS_ERR(pcie->reg_syscon))
+ return dev_err_probe(dev, PTR_ERR(pcie->reg_syscon),
+ "failed to parse starfive,stg-syscon\n");
+
+ pcie->stg_arfun = args[0];
+ pcie->stg_awfun = args[1];
+ pcie->stg_rp_nep = args[2];
+ pcie->stg_lnksta = args[3];
+
+ pcie->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
+ if (IS_ERR_OR_NULL(pcie->reset_gpio)) {
+ dev_warn(dev, "failed to get reset-gpio\n");
+ return -EINVAL;
+ }
+
+ pcie->power_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LOW);
+ if (IS_ERR(pcie->power_gpio)) {
+ dev_warn(dev, "failed to get power-gpio\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct pci_ops starfive_pcie_ops = {
+ .map_bus = plda_pcie_map_bus,
+ .read = starfive_pcie_config_read,
+ .write = starfive_pcie_config_write,
+};
+
+static int starfive_pcie_clk_rst_init(struct starfive_jh7110_pcie *pcie)
+{
+ int ret;
+ struct device *dev = pcie->plda.dev;
+
+ ret = clk_bulk_prepare_enable(pcie->num_clks, pcie->clks);
+ if (ret) {
+ dev_err(dev, "failed to enable clocks\n");
+ return ret;
+ }
+
+ ret = reset_control_deassert(pcie->resets);
+ if (ret) {
+ clk_bulk_disable_unprepare(pcie->num_clks, pcie->clks);
+ dev_err(dev, "failed to resets\n");
+ }
+
+ return ret;
+}
+
+static void starfive_pcie_clk_rst_deinit(struct starfive_jh7110_pcie *pcie)
+{
+ reset_control_assert(pcie->resets);
+ clk_bulk_disable_unprepare(pcie->num_clks, pcie->clks);
+}
+
+static bool starfive_pcie_link_up(struct plda_pcie *plda)
+{
+ struct starfive_jh7110_pcie *pcie =
+ container_of(plda, struct starfive_jh7110_pcie, plda);
+ struct device *dev = pcie->plda.dev;
+ int ret;
+ u32 stg_reg_val;
+
+ ret = regmap_read(pcie->reg_syscon, pcie->stg_lnksta, &stg_reg_val);
+ if (ret) {
+ dev_err(dev, "failed to read link status\n");
+ return false;
+ }
+
+ if (stg_reg_val & DATA_LINK_ACTIVE)
+ return true;
+
+ return false;
+}
+
+static int starfive_pcie_host_wait_for_link(struct starfive_jh7110_pcie *pcie)
+{
+ struct device *dev = pcie->plda.dev;
+ int retries;
+
+ /* Check if the link is up or not */
+ for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) {
+ if (starfive_pcie_link_up(&pcie->plda)) {
+ dev_info(dev, "port Link up\n");
+ return 0;
+ }
+ usleep_range(LINK_WAIT_USLEEP_MIN, LINK_WAIT_USLEEP_MAX);
+ }
+
+ return -ETIMEDOUT;
+}
+
+int starfive_pcie_enable_phy(struct device *dev, struct plda_pcie *pcie)
+{
+ int ret;
+
+ if (!pcie->phy)
+ return 0;
+
+ ret = phy_init(pcie->phy);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "failed to initialize pcie phy\n");
+
+ ret = phy_set_mode(pcie->phy, PHY_MODE_PCIE);
+ if (ret) {
+ dev_err(dev, "failed to set pcie mode\n");
+ goto err_phy_on;
+ }
+
+ ret = phy_power_on(pcie->phy);
+ if (ret) {
+ dev_err(dev, "failed to power on pcie phy\n");
+ goto err_phy_on;
+ }
+
+ return 0;
+
+err_phy_on:
+ phy_exit(pcie->phy);
+ return ret;
+}
+
+void starfive_pcie_disable_phy(struct plda_pcie *pcie)
+{
+ phy_power_off(pcie->phy);
+ phy_exit(pcie->phy);
+}
+
+static void starfive_pcie_host_deinit(struct plda_pcie *plda)
+{
+ struct starfive_jh7110_pcie *pcie =
+ container_of(plda, struct starfive_jh7110_pcie, plda);
+
+ starfive_pcie_clk_rst_deinit(pcie);
+ if (pcie->power_gpio)
+ gpiod_set_value_cansleep(pcie->power_gpio, 0);
+ starfive_pcie_disable_phy(plda);
+}
+
+static int starfive_pcie_host_init(struct plda_pcie *plda)
+{
+ int i;
+ struct starfive_jh7110_pcie *pcie =
+ container_of(plda, struct starfive_jh7110_pcie, plda);
+ struct device *dev = plda->dev;
+ int ret;
+
+ ret = starfive_pcie_enable_phy(dev, plda);
+ if (ret)
+ return ret;
+
+ regmap_update_bits(pcie->reg_syscon, pcie->stg_rp_nep,
+ STG_SYSCON_K_RP_NEP, STG_SYSCON_K_RP_NEP);
+
+ regmap_update_bits(pcie->reg_syscon, pcie->stg_awfun,
+ STG_SYSCON_CKREF_SRC_MASK,
+ FIELD_PREP(STG_SYSCON_CKREF_SRC_MASK, 2));
+
+ regmap_update_bits(pcie->reg_syscon, pcie->stg_awfun,
+ STG_SYSCON_CLKREQ, STG_SYSCON_CLKREQ);
+
+ ret = starfive_pcie_clk_rst_init(pcie);
+ if (ret)
+ return ret;
+
+ if (pcie->power_gpio)
+ gpiod_set_value_cansleep(pcie->power_gpio, 1);
+
+ gpiod_set_value_cansleep(pcie->reset_gpio, 1);
+
+ /* Disable physical functions except #0 */
+ for (i = 1; i < PCIE_FUNC_NUM; i++) {
+ regmap_update_bits(pcie->reg_syscon,
+ pcie->stg_arfun,
+ STG_SYSCON_AXI4_SLVL_ARFUNC_MASK,
+ STG_SYSCON_AXI4_SLVL_PHY_ARFUNC(i));
+
+ regmap_update_bits(pcie->reg_syscon,
+ pcie->stg_awfun,
+ STG_SYSCON_AXI4_SLVL_AWFUNC_MASK,
+ STG_SYSCON_AXI4_SLVL_PHY_AWFUNC(i));
+
+ plda_pcie_disable_func(plda);
+ }
+
+ regmap_update_bits(pcie->reg_syscon, pcie->stg_arfun,
+ STG_SYSCON_AXI4_SLVL_ARFUNC_MASK, 0);
+ regmap_update_bits(pcie->reg_syscon, pcie->stg_awfun,
+ STG_SYSCON_AXI4_SLVL_AWFUNC_MASK, 0);
+
+ plda_pcie_enable_root_port(plda);
+ plda_pcie_write_rc_bar(plda, 0);
+
+ /* PCIe PCI Standard Configuration Identification Settings. */
+ plda_pcie_set_standard_class(plda);
+
+ /*
+ * The LTR message forwarding of PCIe Message Reception was set by core
+ * as default, but the forward id & addr are also need to be reset.
+ * If we do not disable LTR message forwarding here, or set a legal
+ * forwarding address, the kernel will get stuck after this driver probe.
+ * To workaround, disable the LTR message forwarding support on
+ * PCIe Message Reception.
+ */
+ plda_pcie_disable_ltr(plda);
+
+ /* Prefetchable memory window 64-bit addressing support */
+ plda_pcie_set_pref_win_64bit(plda);
+
+ /* Ensure that PERST has been asserted for at least 100 ms,
+ * the sleep value is T_PVPERL from PCIe CEM spec r2.0 (Table 2-4)
+ */
+ msleep(100);
+ gpiod_set_value_cansleep(pcie->reset_gpio, 0);
+
+ ret = starfive_pcie_host_wait_for_link(pcie);
+
+ return ret;
+}
+
+static const struct plda_pcie_ops pcie_ops = {
+ .host_init = starfive_pcie_host_init,
+ .host_deinit = starfive_pcie_host_deinit,
+ .link_up = starfive_pcie_link_up,
+};
+
+static int starfive_pcie_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct starfive_jh7110_pcie *pcie;
+ struct plda_pcie *plda;
+ int ret;
+
+ pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
+ if (!pcie)
+ return -ENOMEM;
+
+ plda = &pcie->plda;
+ plda->dev = dev;
+
+ ret = starfive_pcie_parse_dt(pcie, dev);
+ if (ret)
+ return ret;
+
+ plda->ops = &pcie_ops;
+ plda->num_events = NUM_PLDA_EVENTS;
+ ret = plda_pcie_host_init(&pcie->plda, &starfive_pcie_ops);
+ if (ret)
+ return ret;
+
+ pm_runtime_enable(&pdev->dev);
+ pm_runtime_get_sync(&pdev->dev);
+ platform_set_drvdata(pdev, pcie);
+
+ return 0;
+}
+
+static void starfive_pcie_remove(struct platform_device *pdev)
+{
+ struct starfive_jh7110_pcie *pcie = platform_get_drvdata(pdev);
+
+ plda_pcie_host_deinit(&pcie->plda);
+ platform_set_drvdata(pdev, NULL);
+}
+
+static int starfive_pcie_suspend_noirq(struct device *dev)
+{
+ struct starfive_jh7110_pcie *pcie = dev_get_drvdata(dev);
+
+ if (!pcie)
+ return 0;
+
+ clk_bulk_disable_unprepare(pcie->num_clks, pcie->clks);
+ starfive_pcie_disable_phy(&pcie->plda);
+
+ return 0;
+}
+
+static int starfive_pcie_resume_noirq(struct device *dev)
+{
+ struct starfive_jh7110_pcie *pcie = dev_get_drvdata(dev);
+ int ret;
+
+ ret = starfive_pcie_enable_phy(dev, &pcie->plda);
+ if (ret)
+ return ret;
+
+ ret = clk_bulk_prepare_enable(pcie->num_clks, pcie->clks);
+ if (ret) {
+ dev_err(dev, "failed to enable clocks\n");
+ starfive_pcie_disable_phy(&pcie->plda);
+ return ret;
+ }
+
+ return ret;
+}
+
+static const struct dev_pm_ops starfive_pcie_pm_ops = {
+ NOIRQ_SYSTEM_SLEEP_PM_OPS(starfive_pcie_suspend_noirq,
+ starfive_pcie_resume_noirq)
+};
+
+static const struct of_device_id starfive_pcie_of_match[] = {
+ { .compatible = "starfive,jh7110-pcie"},
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, starfive_pcie_of_match);
+
+static struct platform_driver starfive_pcie_driver = {
+ .driver = {
+ .name = "pcie-starfive",
+ .of_match_table = of_match_ptr(starfive_pcie_of_match),
+#ifdef CONFIG_PM_SLEEP
+ .pm = &starfive_pcie_pm_ops,
+#endif
+ },
+ .probe = starfive_pcie_probe,
+ .remove_new = starfive_pcie_remove,
+};
+module_platform_driver(starfive_pcie_driver);
+
+MODULE_DESCRIPTION("StarFive JH7110 PCIe host driver");
+MODULE_LICENSE("GPL v2");
--
2.17.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH v2 2/4] PCI: plda: Get common codes from Microchip PolarFire host
2023-07-27 10:39 ` [PATCH v2 2/4] PCI: plda: Get common codes from Microchip PolarFire host Minda Chen
@ 2023-07-27 12:02 ` Bjorn Helgaas
2023-07-28 8:46 ` Minda Chen
2023-07-27 15:21 ` Randy Dunlap
1 sibling, 1 reply; 19+ messages in thread
From: Bjorn Helgaas @ 2023-07-27 12:02 UTC (permalink / raw)
To: Minda Chen
Cc: Krzysztof Wilczyński, Daire McNamara, Conor Dooley,
Rob Herring, Krzysztof Kozlowski, Bjorn Helgaas,
Lorenzo Pieralisi, Emil Renner Berthing, devicetree,
linux-kernel, linux-pci, Philipp Zabel, Mason Huo, Leyfoon Tan,
Kevin Xie
On Thu, Jul 27, 2023 at 06:39:47PM +0800, Minda Chen wrote:
> Add PLDA PCIe controller driver codes, Move them from Microchip
> PolarFire PCIe host driver codes. And move pcie-microchip-host.c
> to plda directory.
>
> The change includes:
> - copy the IP register marcos.
> - Add related data structures of PCIe host instance.
> mc_pcie --> plda_pcie (Get most of data members)
> mc_msi --> plda_msi
> add plda_pcie_ops and plda_evt data structures.
> - function rename list:
> mc_pcie_enable_msi --> plda_pcie_enable_msi
> mc_pcie_setup_window --> plda_pcie_setup_window
> mc_pcie_setup_windows --> plda_pcie_setup_iomems
> mc_pcie_init_irq_domains --> plda_pcie_init_irq_domains
> mc_allocate_msi_domains --> plda_allocate_msi_domains
> mc_init_interrupts --> plda_pcie_init_irq
> msi interrupts related functions and irq domain
> (primary function is mc_handle_msi):
> mc_handle_msi --> plda_handle_msi
> intx interrupts related functions and irq domain
> (primary function is mc_handle_intx):
> mc_handle_intx --> plda_handle_intx
> event interrupts:
> mc_handle_event --> plda_handle_event
> - For PolarFire implements non-plda local interrupt events, most of
> event interrupt process codes can not be re-used. PLDA implements
> new codes and irq domain ops like PolarFire.
> New event functions:
> plda_event_handler
> plda_pcie_event_map
> plda_ack_event_irq
> plda_mask_event_irq
> plda_unmask_event_irq
> plda_hwirq_to_mask
> - plda_handle_event adds a new irqnum to event num mapping codes for
> PLDA local event except DMA engine interrupt events. The DMA engine
> interrupt events are implemented by vendors. So do not add these
> events. PolarFire PCIe uses get_events function pointer to get
> their events num.
There's a lot going on here, which makes this hard to review. If
possible, I suggest splitting this into multiple patches:
- Move code to plda/ directory with no other changes
- Rename structs/functions from mc_* to plda_* with no other changes
- Add PolarFire-specific code
Other general things:
- Capitalize PLDA, IRQ, INTx, MSI, PCIe in commit logs, comments,
dmesg text
- Sort MAINTAINERS entries alphabetically; see
https://git.kernel.org/linus/c192ac735768
Bjorn
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2 2/4] PCI: plda: Get common codes from Microchip PolarFire host
2023-07-27 10:39 ` [PATCH v2 2/4] PCI: plda: Get common codes from Microchip PolarFire host Minda Chen
2023-07-27 12:02 ` Bjorn Helgaas
@ 2023-07-27 15:21 ` Randy Dunlap
2023-08-03 6:44 ` Minda Chen
1 sibling, 1 reply; 19+ messages in thread
From: Randy Dunlap @ 2023-07-27 15:21 UTC (permalink / raw)
To: Minda Chen, Krzysztof Wilczyński, Daire McNamara,
Conor Dooley, Rob Herring, Krzysztof Kozlowski, Bjorn Helgaas,
Lorenzo Pieralisi, Emil Renner Berthing
Cc: devicetree, linux-kernel, linux-pci, Philipp Zabel, Mason Huo,
Leyfoon Tan, Kevin Xie
Hi--
On 7/27/23 03:39, Minda Chen wrote:
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 8e4f9d5dca55..ec59c6d00bf9 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -16170,6 +16170,14 @@ S: Maintained
> F: Documentation/devicetree/bindings/pci/cdns,*
> F: drivers/pci/controller/cadence/
>
This new entry is not in the correct location.
It should be in alphabetical order, so it goes between
PCI DRIVER FOR NXP LAYERSCAPE GEN4 CONTROLLER
and
PCI DRIVER FOR RENESAS R-CAR
Thanks.
> +PCI DRIVER FOR PLDA PCIE IP
> +M: Daire McNamara <daire.mcnamara@microchip.com>
> +M: Kevin Xie <kevin.xie@starfivetech.com>
> +L: linux-pci@vger.kernel.org
> +S: Maintained
> +F: Documentation/devicetree/bindings/pci/plda,*
> +F: drivers/pci/controller/plda/*plda*
> +
> PCI DRIVER FOR FREESCALE LAYERSCAPE
> M: Minghuan Lian <minghuan.Lian@nxp.com>
> M: Mingkai Hu <mingkai.hu@nxp.com>
--
~Randy
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2 2/4] PCI: plda: Get common codes from Microchip PolarFire host
2023-07-27 12:02 ` Bjorn Helgaas
@ 2023-07-28 8:46 ` Minda Chen
0 siblings, 0 replies; 19+ messages in thread
From: Minda Chen @ 2023-07-28 8:46 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Krzysztof Wilczyński, Daire McNamara, Conor Dooley,
Rob Herring, Krzysztof Kozlowski, Bjorn Helgaas,
Lorenzo Pieralisi, Emil Renner Berthing, devicetree,
linux-kernel, linux-pci, Philipp Zabel, Mason Huo, Leyfoon Tan,
Kevin Xie
On 2023/7/27 20:02, Bjorn Helgaas wrote:
> On Thu, Jul 27, 2023 at 06:39:47PM +0800, Minda Chen wrote:
>> Add PLDA PCIe controller driver codes, Move them from Microchip
>> PolarFire PCIe host driver codes. And move pcie-microchip-host.c
>> to plda directory.
>>
>> The change includes:
>> - copy the IP register marcos.
>> - Add related data structures of PCIe host instance.
>> mc_pcie --> plda_pcie (Get most of data members)
>> mc_msi --> plda_msi
>> add plda_pcie_ops and plda_evt data structures.
>> - function rename list:
>> mc_pcie_enable_msi --> plda_pcie_enable_msi
>> mc_pcie_setup_window --> plda_pcie_setup_window
>> mc_pcie_setup_windows --> plda_pcie_setup_iomems
>> mc_pcie_init_irq_domains --> plda_pcie_init_irq_domains
>> mc_allocate_msi_domains --> plda_allocate_msi_domains
>> mc_init_interrupts --> plda_pcie_init_irq
>> msi interrupts related functions and irq domain
>> (primary function is mc_handle_msi):
>> mc_handle_msi --> plda_handle_msi
>> intx interrupts related functions and irq domain
>> (primary function is mc_handle_intx):
>> mc_handle_intx --> plda_handle_intx
>> event interrupts:
>> mc_handle_event --> plda_handle_event
>> - For PolarFire implements non-plda local interrupt events, most of
>> event interrupt process codes can not be re-used. PLDA implements
>> new codes and irq domain ops like PolarFire.
>> New event functions:
>> plda_event_handler
>> plda_pcie_event_map
>> plda_ack_event_irq
>> plda_mask_event_irq
>> plda_unmask_event_irq
>> plda_hwirq_to_mask
>> - plda_handle_event adds a new irqnum to event num mapping codes for
>> PLDA local event except DMA engine interrupt events. The DMA engine
>> interrupt events are implemented by vendors. So do not add these
>> events. PolarFire PCIe uses get_events function pointer to get
>> their events num.
>
> There's a lot going on here, which makes this hard to review. If
> possible, I suggest splitting this into multiple patches:
>
> - Move code to plda/ directory with no other changes
> - Rename structs/functions from mc_* to plda_* with no other changes
> - Add PolarFire-specific code
>
Yeah, This is a lot modification. I will try to split more patches to get it easier
to review. maybe split IP register macros first, second rename structs/function only.
third add the new event mapping codes, at last add PolarFire-specific codes.
> Other general things:
>
> - Capitalize PLDA, IRQ, INTx, MSI, PCIe in commit logs, comments,
> dmesg text
> - Sort MAINTAINERS entries alphabetically; see
> https://git.kernel.org/linus/c192ac735768
>
ok
> Bjorn
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2 2/4] PCI: plda: Get common codes from Microchip PolarFire host
2023-07-27 15:21 ` Randy Dunlap
@ 2023-08-03 6:44 ` Minda Chen
0 siblings, 0 replies; 19+ messages in thread
From: Minda Chen @ 2023-08-03 6:44 UTC (permalink / raw)
To: Randy Dunlap, Krzysztof Wilczyński, Daire McNamara,
Conor Dooley, Rob Herring, Krzysztof Kozlowski, Bjorn Helgaas,
Lorenzo Pieralisi, Emil Renner Berthing
Cc: devicetree, linux-kernel, linux-pci, Philipp Zabel, Mason Huo,
Leyfoon Tan, Kevin Xie
On 2023/7/27 23:21, Randy Dunlap wrote:
> Hi--
>
> On 7/27/23 03:39, Minda Chen wrote:
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 8e4f9d5dca55..ec59c6d00bf9 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -16170,6 +16170,14 @@ S: Maintained
>> F: Documentation/devicetree/bindings/pci/cdns,*
>> F: drivers/pci/controller/cadence/
>>
>
> This new entry is not in the correct location.
> It should be in alphabetical order, so it goes between
>
> PCI DRIVER FOR NXP LAYERSCAPE GEN4 CONTROLLER
> and
> PCI DRIVER FOR RENESAS R-CAR
>
> Thanks.
>
Got it. Thanks
>> +PCI DRIVER FOR PLDA PCIE IP
>> +M: Daire McNamara <daire.mcnamara@microchip.com>
>> +M: Kevin Xie <kevin.xie@starfivetech.com>
>> +L: linux-pci@vger.kernel.org
>> +S: Maintained
>> +F: Documentation/devicetree/bindings/pci/plda,*
>> +F: drivers/pci/controller/plda/*plda*
>> +
>> PCI DRIVER FOR FREESCALE LAYERSCAPE
>> M: Minghuan Lian <minghuan.Lian@nxp.com>
>> M: Mingkai Hu <mingkai.hu@nxp.com>
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2 0/4] Refactoring Microchip PCIe driver and add StarFive PCIe
2023-07-27 10:39 [PATCH v2 0/4] Refactoring Microchip PCIe driver and add StarFive PCIe Minda Chen
` (3 preceding siblings ...)
2023-07-27 10:39 ` [PATCH v2 4/4] PCI: starfive: Add " Minda Chen
@ 2023-08-04 1:46 ` Minda Chen
2023-08-04 6:23 ` Conor Dooley
2023-08-05 13:05 ` Emil Renner Berthing
5 siblings, 1 reply; 19+ messages in thread
From: Minda Chen @ 2023-08-04 1:46 UTC (permalink / raw)
To: Krzysztof Wilczyński, Daire McNamara, Conor Dooley,
Rob Herring, Krzysztof Kozlowski, Bjorn Helgaas,
Lorenzo Pieralisi, Emil Renner Berthing
Cc: devicetree, linux-kernel, linux-pci, Philipp Zabel, Mason Huo,
Leyfoon Tan, Kevin Xie
On 2023/7/27 18:39, Minda Chen wrote:
> 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.
>
> So first step is extract the PLDA common codes from microchip, and
> refactoring the microchip codes.(patch1 - 2)
> Then, add Starfive codes. (patch3 - 4)
>
> This patchset is base on v6.5-rc1
>
> patch1 is move PLDA XpressRICH PCIe host common properties dt-binding
> docs from microchip,pcie-host.yaml
> patch2 is extracting the PLDA common codes from microchip Polarfire PCIe
> codes. The change list in the commit message.
> patch3 is add StarFive JH7110 PCIe dt-binding doc.
> patch4 is add StarFive JH7110 Soc PCIe codes.
>
Hi Rob, Krzysztof(K.K) and Conor
Do you have any comments for dts-binding doc patch? (patch 1 and patch3) Thanks.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2 0/4] Refactoring Microchip PCIe driver and add StarFive PCIe
2023-08-04 1:46 ` [PATCH v2 0/4] Refactoring Microchip PCIe driver and add StarFive PCIe Minda Chen
@ 2023-08-04 6:23 ` Conor Dooley
0 siblings, 0 replies; 19+ messages in thread
From: Conor Dooley @ 2023-08-04 6:23 UTC (permalink / raw)
To: Minda Chen
Cc: Krzysztof Wilczyński, Daire McNamara, Conor Dooley,
Rob Herring, Krzysztof Kozlowski, Bjorn Helgaas,
Lorenzo Pieralisi, Emil Renner Berthing, devicetree,
linux-kernel, linux-pci, Philipp Zabel, Mason Huo, Leyfoon Tan,
Kevin Xie
[-- Attachment #1: Type: text/plain, Size: 1493 bytes --]
Hey Minda,
On Fri, Aug 04, 2023 at 09:46:30AM +0800, Minda Chen wrote:
> On 2023/7/27 18:39, Minda Chen wrote:
> > 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.
> >
> > So first step is extract the PLDA common codes from microchip, and
> > refactoring the microchip codes.(patch1 - 2)
> > Then, add Starfive codes. (patch3 - 4)
> >
> > This patchset is base on v6.5-rc1
> >
> > patch1 is move PLDA XpressRICH PCIe host common properties dt-binding
> > docs from microchip,pcie-host.yaml
> > patch2 is extracting the PLDA common codes from microchip Polarfire PCIe
> > codes. The change list in the commit message.
> > patch3 is add StarFive JH7110 PCIe dt-binding doc.
> > patch4 is add StarFive JH7110 Soc PCIe codes.
> >
> Hi Rob, Krzysztof(K.K) and Conor
> Do you have any comments for dts-binding doc patch? (patch 1 and patch3) Thanks.
Yeah, I do intend looking at this! I think, because I am wearing more
than one hat for this series, it ended up not in my dt-binding review
queue. I'll make sure to have a look today.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2 3/4] dt-bindings: PCI: Add StarFive JH7110 PCIe controller
2023-07-27 10:39 ` [PATCH v2 3/4] dt-bindings: PCI: Add StarFive JH7110 PCIe controller Minda Chen
@ 2023-08-04 7:10 ` Conor Dooley
2023-08-07 6:54 ` Minda Chen
2023-08-10 22:47 ` Rob Herring
1 sibling, 1 reply; 19+ messages in thread
From: Conor Dooley @ 2023-08-04 7:10 UTC (permalink / raw)
To: Minda Chen
Cc: Krzysztof Wilczyński, Daire McNamara, Conor Dooley,
Rob Herring, Krzysztof Kozlowski, Bjorn Helgaas,
Lorenzo Pieralisi, Emil Renner Berthing, devicetree,
linux-kernel, linux-pci, Philipp Zabel, Mason Huo, Leyfoon Tan,
Kevin Xie
[-- Attachment #1: Type: text/plain, Size: 6077 bytes --]
On Thu, Jul 27, 2023 at 06:39:48PM +0800, Minda Chen wrote:
> Add StarFive JH7110 SoC PCIe controller dt-bindings.
> JH7110 using PLDA XpressRICH PCIe host controller IP.
>
> Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
> Reviewed-by: Hal Feng <hal.feng@starfivetech.com>
> ---
> .../bindings/pci/starfive,jh7110-pcie.yaml | 133 ++++++++++++++++++
> 1 file changed, 133 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml
>
> diff --git a/Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml b/Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml
> new file mode 100644
> index 000000000000..9273e029fb20
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml
> @@ -0,0 +1,133 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/pci/starfive,jh7110-pcie.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: StarFive JH7110 PCIe host controller
> +
> +maintainers:
> + - Kevin Xie <kevin.xie@starfivetech.com>
> +
> +allOf:
> + - $ref: /schemas/pci/pci-bus.yaml#
> + - $ref: plda,xpressrich3-axi-common.yaml#
> + - $ref: /schemas/interrupt-controller/msi-controller.yaml#
> + - $ref: /schemas/gpio/gpio-consumer-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
> + items:
> + - items:
> + - description: phandle to System Register Controller stg_syscon node.
> + - description: register0 offset of STG_SYSCONSAIF__SYSCFG register for PCIe.
> + - description: register1 offset of STG_SYSCONSAIF__SYSCFG register for PCIe.
> + - description: register2 offset of STG_SYSCONSAIF__SYSCFG register for PCIe.
> + - description: register3 offset of STG_SYSCONSAIF__SYSCFG register for PCIe.
> + description:
> + The phandle to System Register Controller syscon node and the offset
> + of STG_SYSCONSAIF__SYSCFG register for PCIe. Total 4 regsisters offset
> + for PCIe.
These property names tie them closely with naming on the jh7110, but
there's little value in specifying all of these offsets when you have
one implementation where they are all fixed.
Do you know what the jh81xx stuff is going to do yet w.r.t. PCI and if
so, how could you reuse this property?
Particularly, saying "register 0" seems unlikely to transfer well
between SoCs.
I'd be inclined to drop the offsets entirely & rely on match data to
provide them if needed in the future.
> +
> + phys:
> + description:
> + Specified PHY is attached to PCIe controller.
> + maxItems: 1
> +
> +required:
> + - compatible
> + - clocks
> + - resets
> + - starfive,stg-syscon
> + - "#interrupt-cells"
> + - interrupt-map-mask
> + - interrupt-map
> +
> +unevaluatedProperties: false
> +
> +examples:
> + - |
> + #include <dt-bindings/gpio/gpio.h>
> + soc {
> + #address-cells = <2>;
> + #size-cells = <2>;
> +
> + pcie0: pcie@2b000000 {
nit: you don't need labels in examples if they are not referenced
anywhere.
Otherwise, this looks good to me.
Thanks,
Conor.
> + 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 0xc0 0xc4 0x130 0x1b8>;
> + 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-parent = <&pcie0>;
> + 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>;
> + reset-gpios = <&gpios 26 GPIO_ACTIVE_LOW>;
> + phys = <&pciephy0>;
> +
> + pcie_intc0: interrupt-controller {
> + #address-cells = <0>;
> + #interrupt-cells = <1>;
> + interrupt-controller;
> + };
> + };
> + };
> --
> 2.17.1
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2 1/4] dt-bindings: PCI: Add PLDA XpressRICH PCIe host common properties
2023-07-27 10:39 ` [PATCH v2 1/4] dt-bindings: PCI: Add PLDA XpressRICH PCIe host common properties Minda Chen
@ 2023-08-04 7:12 ` Conor Dooley
0 siblings, 0 replies; 19+ messages in thread
From: Conor Dooley @ 2023-08-04 7:12 UTC (permalink / raw)
To: Minda Chen
Cc: Krzysztof Wilczyński, Daire McNamara, Conor Dooley,
Rob Herring, Krzysztof Kozlowski, Bjorn Helgaas,
Lorenzo Pieralisi, Emil Renner Berthing, devicetree,
linux-kernel, linux-pci, Philipp Zabel, Mason Huo, Leyfoon Tan,
Kevin Xie
[-- Attachment #1: Type: text/plain, Size: 477 bytes --]
On Thu, Jul 27, 2023 at 06:39:46PM +0800, Minda Chen wrote:
> Add PLDA XpressRICH PCIe host common properties dt-binding doc.
> Microchip PolarFire PCIe host using PLDA IP.
> Move common properties from Microchip PolarFire PCIe host
> to PLDA files.
>
> Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
> Reviewed-by: Hal Feng <hal.feng@starfivetech.com>
This also seems okay to me.
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
Thanks,
Conor.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2 0/4] Refactoring Microchip PCIe driver and add StarFive PCIe
2023-07-27 10:39 [PATCH v2 0/4] Refactoring Microchip PCIe driver and add StarFive PCIe Minda Chen
` (4 preceding siblings ...)
2023-08-04 1:46 ` [PATCH v2 0/4] Refactoring Microchip PCIe driver and add StarFive PCIe Minda Chen
@ 2023-08-05 13:05 ` Emil Renner Berthing
2023-08-07 6:59 ` Minda Chen
5 siblings, 1 reply; 19+ messages in thread
From: Emil Renner Berthing @ 2023-08-05 13:05 UTC (permalink / raw)
To: Minda Chen
Cc: Krzysztof Wilczyński, Daire McNamara, Conor Dooley,
Rob Herring, Krzysztof Kozlowski, Bjorn Helgaas,
Lorenzo Pieralisi, devicetree, linux-kernel, linux-pci,
Philipp Zabel, Mason Huo, Leyfoon Tan, Kevin Xie
On Thu, 27 Jul 2023 at 12:40, Minda Chen <minda.chen@starfivetech.com> wrote:
>
> 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.
>
> So first step is extract the PLDA common codes from microchip, and
> refactoring the microchip codes.(patch1 - 2)
> Then, add Starfive codes. (patch3 - 4)
>
> This patchset is base on v6.5-rc1
>
> patch1 is move PLDA XpressRICH PCIe host common properties dt-binding
> docs from microchip,pcie-host.yaml
> patch2 is extracting the PLDA common codes from microchip Polarfire PCIe
> codes. The change list in the commit message.
> patch3 is add StarFive JH7110 PCIe dt-binding doc.
> patch4 is add StarFive JH7110 Soc PCIe codes.
Hi Minda,
To test this series properly it needs matching nodes in the VisionFive
2 device trees, but it seems to be missing from this version of the
patch series. If I apply the device tree patch from v1 I get errors
like this:
pcie-starfive 2b000000.pcie: invalid resource (null)
pcie-starfive 2b000000.pcie: error -EINVAL: failed to map reg memory
It would be great if you included the device tree patch in the next
series so this can actually be tested.
/Emil
> I have noticed that Daire have changed microchip's codes.
> https://patchwork.kernel.org/project/linux-pci/cover/20230630154859.2049521-1-daire.mcnamara@microchip.com/
> I have changed patch2 base on their commits. StarFive
> PCIe driver still can work. But their codes is under reviewed and
> maybe changing. Do not base on their changes first.
> I will base on their commit to change patch2 as soon as
> their commits are accepted.
>
> previous version:
> v1:https://patchwork.kernel.org/project/linux-pci/cover/20230719102057.22329-1-minda.chen@starfivetech.com/
>
> change:
> v2:
> patch1:
> - squash dt-bindings patches to patch1
> - add 'required' list.
> - plda doc rename to plda,xpressrich-axi-common.yaml
> patch2:
> - squash the microchip modification patch to patch 2.
> patch3:
> - remove the plda common required property.
> patch4:
> - Sync the hide rc bar ops with config read function.
> - Revert the T_PVPERL to 100ms and add comments for the source.
> - Replace the link check function by the standard link ops.
> - Convert to new pm ops marcos.
> - Some formats modification.
> - pcie-plda-host modification merge to patch4.
> other:
> - remove the pcie-plda-plat.c
> - remove the starfive dts patch first. for it depends on
> stg clock and syscon setting.
>
> Minda Chen (4):
> dt-bindings: PCI: Add PLDA XpressRICH PCIe host common properties
> PCI: plda: Get common codes from Microchip PolarFire host
> dt-bindings: PCI: Add StarFive JH7110 PCIe controller
> PCI: starfive: Add JH7110 PCIe controller
>
> .../bindings/pci/microchip,pcie-host.yaml | 49 +-
> .../pci/plda,xpressrich3-axi-common.yaml | 69 ++
> .../bindings/pci/starfive,jh7110-pcie.yaml | 133 ++++
> MAINTAINERS | 19 +-
> drivers/pci/controller/Kconfig | 9 +-
> drivers/pci/controller/Makefile | 2 +-
> drivers/pci/controller/plda/Kconfig | 31 +
> drivers/pci/controller/plda/Makefile | 4 +
> .../{ => plda}/pcie-microchip-host.c | 594 ++--------------
> drivers/pci/controller/plda/pcie-plda-host.c | 665 ++++++++++++++++++
> drivers/pci/controller/plda/pcie-plda.h | 242 +++++++
> drivers/pci/controller/plda/pcie-starfive.c | 438 ++++++++++++
> 12 files changed, 1645 insertions(+), 610 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 (50%)
> 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.c
>
>
> base-commit: 06c2afb862f9da8dc5efa4b6076a0e48c3fbaaa5
> --
> 2.17.1
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2 3/4] dt-bindings: PCI: Add StarFive JH7110 PCIe controller
2023-08-04 7:10 ` Conor Dooley
@ 2023-08-07 6:54 ` Minda Chen
2023-08-07 7:45 ` Conor Dooley
0 siblings, 1 reply; 19+ messages in thread
From: Minda Chen @ 2023-08-07 6:54 UTC (permalink / raw)
To: Conor Dooley
Cc: Krzysztof Wilczyński, Daire McNamara, Conor Dooley,
Rob Herring, Krzysztof Kozlowski, Bjorn Helgaas,
Lorenzo Pieralisi, Emil Renner Berthing, devicetree,
linux-kernel, linux-pci, Philipp Zabel, Mason Huo, Leyfoon Tan,
Kevin Xie
On 2023/8/4 15:10, Conor Dooley wrote:
> On Thu, Jul 27, 2023 at 06:39:48PM +0800, Minda Chen wrote:
>> Add StarFive JH7110 SoC PCIe controller dt-bindings.
>> JH7110 using PLDA XpressRICH PCIe host controller IP.
>>
>> Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
>> Reviewed-by: Hal Feng <hal.feng@starfivetech.com>
>> ---
>> .../bindings/pci/starfive,jh7110-pcie.yaml | 133 ++++++++++++++++++
>> 1 file changed, 133 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml b/Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml
>> new file mode 100644
>> index 000000000000..9273e029fb20
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml
>> @@ -0,0 +1,133 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/pci/starfive,jh7110-pcie.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: StarFive JH7110 PCIe host controller
>> +
>> +maintainers:
>> + - Kevin Xie <kevin.xie@starfivetech.com>
>> +
>> +allOf:
>> + - $ref: /schemas/pci/pci-bus.yaml#
>> + - $ref: plda,xpressrich3-axi-common.yaml#
>> + - $ref: /schemas/interrupt-controller/msi-controller.yaml#
>> + - $ref: /schemas/gpio/gpio-consumer-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
>> + items:
>> + - items:
>> + - description: phandle to System Register Controller stg_syscon node.
>> + - description: register0 offset of STG_SYSCONSAIF__SYSCFG register for PCIe.
>> + - description: register1 offset of STG_SYSCONSAIF__SYSCFG register for PCIe.
>> + - description: register2 offset of STG_SYSCONSAIF__SYSCFG register for PCIe.
>> + - description: register3 offset of STG_SYSCONSAIF__SYSCFG register for PCIe.
>> + description:
>> + The phandle to System Register Controller syscon node and the offset
>> + of STG_SYSCONSAIF__SYSCFG register for PCIe. Total 4 regsisters offset
>> + for PCIe.
>
> These property names tie them closely with naming on the jh7110, but
> there's little value in specifying all of these offsets when you have
> one implementation where they are all fixed.
Yes, the offset value is tied to SoC.
> Do you know what the jh81xx stuff is going to do yet w.r.t. PCI and if
> so, how could you reuse this property?
I do not participate in jh8100. But I heard sys-syscon is exist in 81xx.
But I think stg-syscon and sys-syscon can be move to a common dt-binding doc.
Bot 71x0 and 81x0 driver can use this.
> Particularly, saying "register 0" seems unlikely to transfer well
> between SoCs.
> I'd be inclined to drop the offsets entirely & rely on match data to
> provide them if needed in the future.
That's ok. The dts can change to starfive,stg-syscon = <&stg_syscon>;
I will try to move the offset to driver match data.
>> +
>> + phys:
>> + description:
>> + Specified PHY is attached to PCIe controller.
>> + maxItems: 1
>> +
>> +required:
>> + - compatible
>> + - clocks
>> + - resets
>> + - starfive,stg-syscon
>> + - "#interrupt-cells"
>> + - interrupt-map-mask
>> + - interrupt-map
>> +
>> +unevaluatedProperties: false
>> +
>> +examples:
>> + - |
>> + #include <dt-bindings/gpio/gpio.h>
>> + soc {
>> + #address-cells = <2>;
>> + #size-cells = <2>;
>> +
>> + pcie0: pcie@2b000000 {
>
> nit: you don't need labels in examples if they are not referenced
> anywhere.
>
> Otherwise, this looks good to me.
>
> Thanks,
> Conor.
>
ok, thanks.
>> + 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 0xc0 0xc4 0x130 0x1b8>;
>> + 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-parent = <&pcie0>;
>> + 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>;
>> + reset-gpios = <&gpios 26 GPIO_ACTIVE_LOW>;
>> + phys = <&pciephy0>;
>> +
>> + pcie_intc0: interrupt-controller {
>> + #address-cells = <0>;
>> + #interrupt-cells = <1>;
>> + interrupt-controller;
>> + };
>> + };
>> + };
>> --
>> 2.17.1
>>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2 0/4] Refactoring Microchip PCIe driver and add StarFive PCIe
2023-08-05 13:05 ` Emil Renner Berthing
@ 2023-08-07 6:59 ` Minda Chen
0 siblings, 0 replies; 19+ messages in thread
From: Minda Chen @ 2023-08-07 6:59 UTC (permalink / raw)
To: Emil Renner Berthing
Cc: Krzysztof Wilczyński, Daire McNamara, Conor Dooley,
Rob Herring, Krzysztof Kozlowski, Bjorn Helgaas,
Lorenzo Pieralisi, devicetree, linux-kernel, linux-pci,
Philipp Zabel, Mason Huo, Leyfoon Tan, Kevin Xie
On 2023/8/5 21:05, Emil Renner Berthing wrote:
> On Thu, 27 Jul 2023 at 12:40, Minda Chen <minda.chen@starfivetech.com> wrote:
>>
>> 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.
>>
>> So first step is extract the PLDA common codes from microchip, and
>> refactoring the microchip codes.(patch1 - 2)
>> Then, add Starfive codes. (patch3 - 4)
>>
>> This patchset is base on v6.5-rc1
>>
>> patch1 is move PLDA XpressRICH PCIe host common properties dt-binding
>> docs from microchip,pcie-host.yaml
>> patch2 is extracting the PLDA common codes from microchip Polarfire PCIe
>> codes. The change list in the commit message.
>> patch3 is add StarFive JH7110 PCIe dt-binding doc.
>> patch4 is add StarFive JH7110 Soc PCIe codes.
>
> Hi Minda,
>
> To test this series properly it needs matching nodes in the VisionFive
> 2 device trees, but it seems to be missing from this version of the
> patch series. If I apply the device tree patch from v1 I get errors
> like this:
>
> pcie-starfive 2b000000.pcie: invalid resource (null)
> pcie-starfive 2b000000.pcie: error -EINVAL: failed to map reg memory
>
> It would be great if you included the device tree patch in the next
> series so this can actually be tested.
>
> /Emil
>
ok. thanks.
>> I have noticed that Daire have changed microchip's codes.
>> https://patchwork.kernel.org/project/linux-pci/cover/20230630154859.2049521-1-daire.mcnamara@microchip.com/
>> I have changed patch2 base on their commits. StarFive
>> PCIe driver still can work. But their codes is under reviewed and
>> maybe changing. Do not base on their changes first.
>> I will base on their commit to change patch2 as soon as
>> their commits are accepted.
>>
>> previous version:
>> v1:https://patchwork.kernel.org/project/linux-pci/cover/20230719102057.22329-1-minda.chen@starfivetech.com/
>>
>> change:
>> v2:
>> patch1:
>> - squash dt-bindings patches to patch1
>> - add 'required' list.
>> - plda doc rename to plda,xpressrich-axi-common.yaml
>> patch2:
>> - squash the microchip modification patch to patch 2.
>> patch3:
>> - remove the plda common required property.
>> patch4:
>> - Sync the hide rc bar ops with config read function.
>> - Revert the T_PVPERL to 100ms and add comments for the source.
>> - Replace the link check function by the standard link ops.
>> - Convert to new pm ops marcos.
>> - Some formats modification.
>> - pcie-plda-host modification merge to patch4.
>> other:
>> - remove the pcie-plda-plat.c
>> - remove the starfive dts patch first. for it depends on
>> stg clock and syscon setting.
>>
>> Minda Chen (4):
>> dt-bindings: PCI: Add PLDA XpressRICH PCIe host common properties
>> PCI: plda: Get common codes from Microchip PolarFire host
>> dt-bindings: PCI: Add StarFive JH7110 PCIe controller
>> PCI: starfive: Add JH7110 PCIe controller
>>
>> .../bindings/pci/microchip,pcie-host.yaml | 49 +-
>> .../pci/plda,xpressrich3-axi-common.yaml | 69 ++
>> .../bindings/pci/starfive,jh7110-pcie.yaml | 133 ++++
>> MAINTAINERS | 19 +-
>> drivers/pci/controller/Kconfig | 9 +-
>> drivers/pci/controller/Makefile | 2 +-
>> drivers/pci/controller/plda/Kconfig | 31 +
>> drivers/pci/controller/plda/Makefile | 4 +
>> .../{ => plda}/pcie-microchip-host.c | 594 ++--------------
>> drivers/pci/controller/plda/pcie-plda-host.c | 665 ++++++++++++++++++
>> drivers/pci/controller/plda/pcie-plda.h | 242 +++++++
>> drivers/pci/controller/plda/pcie-starfive.c | 438 ++++++++++++
>> 12 files changed, 1645 insertions(+), 610 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 (50%)
>> 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.c
>>
>>
>> base-commit: 06c2afb862f9da8dc5efa4b6076a0e48c3fbaaa5
>> --
>> 2.17.1
>>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2 3/4] dt-bindings: PCI: Add StarFive JH7110 PCIe controller
2023-08-07 6:54 ` Minda Chen
@ 2023-08-07 7:45 ` Conor Dooley
0 siblings, 0 replies; 19+ messages in thread
From: Conor Dooley @ 2023-08-07 7:45 UTC (permalink / raw)
To: Minda Chen
Cc: Conor Dooley, Krzysztof Wilczyński, Daire McNamara,
Rob Herring, Krzysztof Kozlowski, Bjorn Helgaas,
Lorenzo Pieralisi, Emil Renner Berthing, devicetree,
linux-kernel, linux-pci, Philipp Zabel, Mason Huo, Leyfoon Tan,
Kevin Xie
[-- Attachment #1: Type: text/plain, Size: 2082 bytes --]
On Mon, Aug 07, 2023 at 02:54:50PM +0800, Minda Chen wrote:
> On 2023/8/4 15:10, Conor Dooley wrote:
> > On Thu, Jul 27, 2023 at 06:39:48PM +0800, Minda Chen wrote:
> >> + starfive,stg-syscon:
> >> + $ref: /schemas/types.yaml#/definitions/phandle-array
> >> + items:
> >> + - items:
> >> + - description: phandle to System Register Controller stg_syscon node.
> >> + - description: register0 offset of STG_SYSCONSAIF__SYSCFG register for PCIe.
> >> + - description: register1 offset of STG_SYSCONSAIF__SYSCFG register for PCIe.
> >> + - description: register2 offset of STG_SYSCONSAIF__SYSCFG register for PCIe.
> >> + - description: register3 offset of STG_SYSCONSAIF__SYSCFG register for PCIe.
> >> + description:
> >> + The phandle to System Register Controller syscon node and the offset
> >> + of STG_SYSCONSAIF__SYSCFG register for PCIe. Total 4 regsisters offset
> >> + for PCIe.
> >
> > These property names tie them closely with naming on the jh7110, but
> > there's little value in specifying all of these offsets when you have
> > one implementation where they are all fixed.
> Yes, the offset value is tied to SoC.
> > Do you know what the jh81xx stuff is going to do yet w.r.t. PCI and if
> > so, how could you reuse this property?
> I do not participate in jh8100. But I heard sys-syscon is exist in 81xx.
> But I think stg-syscon and sys-syscon can be move to a common dt-binding doc.
> Bot 71x0 and 81x0 driver can use this.
> > Particularly, saying "register 0" seems unlikely to transfer well
> > between SoCs.
> > I'd be inclined to drop the offsets entirely & rely on match data to
> > provide them if needed in the future.
> That's ok. The dts can change to starfive,stg-syscon = <&stg_syscon>;
> I will try to move the offset to driver match data.
To be clear, you don't need match data now, only when the jh8100 stuff
shows up. Until then the values can be hard coded in the driver as there
is only one device it works for.
Thanks,
Conor.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2 3/4] dt-bindings: PCI: Add StarFive JH7110 PCIe controller
2023-07-27 10:39 ` [PATCH v2 3/4] dt-bindings: PCI: Add StarFive JH7110 PCIe controller Minda Chen
2023-08-04 7:10 ` Conor Dooley
@ 2023-08-10 22:47 ` Rob Herring
2023-08-14 8:11 ` Minda Chen
1 sibling, 1 reply; 19+ messages in thread
From: Rob Herring @ 2023-08-10 22:47 UTC (permalink / raw)
To: Minda Chen
Cc: Krzysztof Wilczyński, Daire McNamara, Conor Dooley,
Krzysztof Kozlowski, Bjorn Helgaas, Lorenzo Pieralisi,
Emil Renner Berthing, devicetree, linux-kernel, linux-pci,
Philipp Zabel, Mason Huo, Leyfoon Tan, Kevin Xie
On Thu, Jul 27, 2023 at 06:39:48PM +0800, Minda Chen wrote:
> Add StarFive JH7110 SoC PCIe controller dt-bindings.
> JH7110 using PLDA XpressRICH PCIe host controller IP.
>
> Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
> Reviewed-by: Hal Feng <hal.feng@starfivetech.com>
> ---
> .../bindings/pci/starfive,jh7110-pcie.yaml | 133 ++++++++++++++++++
> 1 file changed, 133 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml
>
> diff --git a/Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml b/Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml
> new file mode 100644
> index 000000000000..9273e029fb20
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml
> @@ -0,0 +1,133 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/pci/starfive,jh7110-pcie.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: StarFive JH7110 PCIe host controller
> +
> +maintainers:
> + - Kevin Xie <kevin.xie@starfivetech.com>
> +
> +allOf:
> + - $ref: /schemas/pci/pci-bus.yaml#
Can go in common schema. Unless endpoint mode is or is going to be
supported?
> + - $ref: plda,xpressrich3-axi-common.yaml#
> + - $ref: /schemas/interrupt-controller/msi-controller.yaml#
This is a bit odd. Do you really need to define the host bridge as an
msi-controller? Many host bridges are, but they don't need to be defined
as one in DT because PCIe spec defines its own way to do MSIs.
> + - $ref: /schemas/gpio/gpio-consumer-common.yaml#
No, you don't need to reference this. You need to define what properties
from it you use (reset-gpios).
Though if this is for PERST#, then I'd use "perst-gpios" instead.
And why is that not common? It's board specific, not SoC, whether or
not there's GPIO control of it.
> +
> +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
> + items:
> + - items:
> + - description: phandle to System Register Controller stg_syscon node.
> + - description: register0 offset of STG_SYSCONSAIF__SYSCFG register for PCIe.
> + - description: register1 offset of STG_SYSCONSAIF__SYSCFG register for PCIe.
> + - description: register2 offset of STG_SYSCONSAIF__SYSCFG register for PCIe.
> + - description: register3 offset of STG_SYSCONSAIF__SYSCFG register for PCIe.
> + description:
> + The phandle to System Register Controller syscon node and the offset
> + of STG_SYSCONSAIF__SYSCFG register for PCIe. Total 4 regsisters offset
> + for PCIe.
Perhaps somewhere in here state what these registers are for.
> +
> + phys:
> + description:
> + Specified PHY is attached to PCIe controller.
> + maxItems: 1
> +
> +required:
> + - compatible
> + - clocks
> + - resets
> + - starfive,stg-syscon
> + - "#interrupt-cells"
> + - interrupt-map-mask
> + - interrupt-map
These can all be common.
So could 'compatible' though it is implicitly required anyways as
without it, the schema is never applied.
> +
> +unevaluatedProperties: false
> +
> +examples:
> + - |
> + #include <dt-bindings/gpio/gpio.h>
> + soc {
> + #address-cells = <2>;
> + #size-cells = <2>;
> +
> + pcie0: pcie@2b000000 {
> + 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 0xc0 0xc4 0x130 0x1b8>;
> + 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-parent = <&pcie0>;
Weird!?
> + 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>;
> + reset-gpios = <&gpios 26 GPIO_ACTIVE_LOW>;
> + phys = <&pciephy0>;
> +
> + pcie_intc0: interrupt-controller {
> + #address-cells = <0>;
> + #interrupt-cells = <1>;
> + interrupt-controller;
> + };
> + };
> + };
> --
> 2.17.1
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2 3/4] dt-bindings: PCI: Add StarFive JH7110 PCIe controller
2023-08-10 22:47 ` Rob Herring
@ 2023-08-14 8:11 ` Minda Chen
0 siblings, 0 replies; 19+ messages in thread
From: Minda Chen @ 2023-08-14 8:11 UTC (permalink / raw)
To: Rob Herring
Cc: Krzysztof Wilczyński, Daire McNamara, Conor Dooley,
Krzysztof Kozlowski, Bjorn Helgaas, Lorenzo Pieralisi,
Emil Renner Berthing, devicetree, linux-kernel, linux-pci,
Philipp Zabel, Mason Huo, Leyfoon Tan, Kevin Xie
On 2023/8/11 6:47, Rob Herring wrote:
> On Thu, Jul 27, 2023 at 06:39:48PM +0800, Minda Chen wrote:
>> Add StarFive JH7110 SoC PCIe controller dt-bindings.
>> JH7110 using PLDA XpressRICH PCIe host controller IP.
>>
>> Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
>> Reviewed-by: Hal Feng <hal.feng@starfivetech.com>
>> ---
>> .../bindings/pci/starfive,jh7110-pcie.yaml | 133 ++++++++++++++++++
>> 1 file changed, 133 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml b/Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml
>> new file mode 100644
>> index 000000000000..9273e029fb20
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml
>> @@ -0,0 +1,133 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/pci/starfive,jh7110-pcie.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: StarFive JH7110 PCIe host controller
>> +
>> +maintainers:
>> + - Kevin Xie <kevin.xie@starfivetech.com>
>> +
>> +allOf:
>> + - $ref: /schemas/pci/pci-bus.yaml#
>
> Can go in common schema. Unless endpoint mode is or is going to be
> supported?
>
>> + - $ref: plda,xpressrich3-axi-common.yaml#
>> + - $ref: /schemas/interrupt-controller/msi-controller.yaml#
>
> This is a bit odd. Do you really need to define the host bridge as an
> msi-controller? Many host bridges are, but they don't need to be defined
> as one in DT because PCIe spec defines its own way to do MSIs.
>
Ok, I will delete this.
>> + - $ref: /schemas/gpio/gpio-consumer-common.yaml#
>
> No, you don't need to reference this. You need to define what properties
> from it you use (reset-gpios).
>
> Though if this is for PERST#, then I'd use "perst-gpios" instead.
>
> And why is that not common? It's board specific, not SoC, whether or
> not there's GPIO control of it.
>
OK
>> +
>> +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
>> + items:
>> + - items:
>> + - description: phandle to System Register Controller stg_syscon node.
>> + - description: register0 offset of STG_SYSCONSAIF__SYSCFG register for PCIe.
>> + - description: register1 offset of STG_SYSCONSAIF__SYSCFG register for PCIe.
>> + - description: register2 offset of STG_SYSCONSAIF__SYSCFG register for PCIe.
>> + - description: register3 offset of STG_SYSCONSAIF__SYSCFG register for PCIe.
>> + description:
>> + The phandle to System Register Controller syscon node and the offset
>> + of STG_SYSCONSAIF__SYSCFG register for PCIe. Total 4 regsisters offset
>> + for PCIe.
>
> Perhaps somewhere in here state what these registers are for.
>
The offsets will be removed.
>> +
>> + phys:
>> + description:
>> + Specified PHY is attached to PCIe controller.
>> + maxItems: 1
>> +
>> +required:
>> + - compatible
>> + - clocks
>> + - resets
>> + - starfive,stg-syscon
>
>> + - "#interrupt-cells"
>> + - interrupt-map-mask
>> + - interrupt-map
>
> These can all be common.
>
> So could 'compatible' though it is implicitly required anyways as
> without it, the schema is never applied.
>
OK, Thanks.
>> +
>> +unevaluatedProperties: false
>> +
>> +examples:
>> + - |
>> + #include <dt-bindings/gpio/gpio.h>
>> + soc {
>> + #address-cells = <2>;
>> + #size-cells = <2>;
>> +
>> + pcie0: pcie@2b000000 {
>> + 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 0xc0 0xc4 0x130 0x1b8>;
>> + 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-parent = <&pcie0>;
>
> Weird!?
>
I will delete this.
>> + 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>;
>> + reset-gpios = <&gpios 26 GPIO_ACTIVE_LOW>;
>> + phys = <&pciephy0>;
>> +
>> + pcie_intc0: interrupt-controller {
>> + #address-cells = <0>;
>> + #interrupt-cells = <1>;
>> + interrupt-controller;
>> + };
>> + };
>> + };
>> --
>> 2.17.1
>>
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2023-08-14 8:12 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-07-27 10:39 [PATCH v2 0/4] Refactoring Microchip PCIe driver and add StarFive PCIe Minda Chen
2023-07-27 10:39 ` [PATCH v2 1/4] dt-bindings: PCI: Add PLDA XpressRICH PCIe host common properties Minda Chen
2023-08-04 7:12 ` Conor Dooley
2023-07-27 10:39 ` [PATCH v2 2/4] PCI: plda: Get common codes from Microchip PolarFire host Minda Chen
2023-07-27 12:02 ` Bjorn Helgaas
2023-07-28 8:46 ` Minda Chen
2023-07-27 15:21 ` Randy Dunlap
2023-08-03 6:44 ` Minda Chen
2023-07-27 10:39 ` [PATCH v2 3/4] dt-bindings: PCI: Add StarFive JH7110 PCIe controller Minda Chen
2023-08-04 7:10 ` Conor Dooley
2023-08-07 6:54 ` Minda Chen
2023-08-07 7:45 ` Conor Dooley
2023-08-10 22:47 ` Rob Herring
2023-08-14 8:11 ` Minda Chen
2023-07-27 10:39 ` [PATCH v2 4/4] PCI: starfive: Add " Minda Chen
2023-08-04 1:46 ` [PATCH v2 0/4] Refactoring Microchip PCIe driver and add StarFive PCIe Minda Chen
2023-08-04 6:23 ` Conor Dooley
2023-08-05 13:05 ` Emil Renner Berthing
2023-08-07 6:59 ` Minda Chen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).