Skip to contentSkip to conversation

Add PCIe support to Sophgo SG2042 SoC

PATCH In review Chen Wang 6 participants 17 messages Aug 28, 2025 – Sep 1, 2025

Subsystems (6)
lore
Share & tools
lore

Chen Wang

author
#0 lore raw

cover Add PCIe support to Sophgo SG2042 SoC

From: Chen Wang <[email protected]>

Sophgo's SG2042 SoC uses Cadence PCIe core to implement RC mode.

This is a completely rewritten PCIe driver for SG2042. It inherits some previously submitted patch codes (not merged into the upstream mainline), but the biggest difference is that the support for compatibility with old 32-bit PCIe devices has been removed in this new version. This is because after discussing with community users, we felt that there was not much demand for support for old devices, so we made a new design based on the simplified design and practical needs. If someone really needs to play with old devices, we can provide them with some necessary hack patches in the downstream repository.

Since the new design is quite different from the old code, I will release it as a new patch series. The old patch series can be found in here [old-series].

Note, regarding [2/5] of this patchset, this fix is introduced because the pcie->ops pointer is not filled in SG2042 PCIe driver. This is not a must-have parameter, if we use it w/o checking will cause a null pointer access error during runtime.

This patchset is based on v6.17-rc1.

Thanks,
Chen

---

Chen Wang (5):
dt-bindings: pci: Add Sophgo SG2042 PCIe host
PCI: cadence: Fix NULL pointer error for ops
PCI: sg2042: Add Sophgo SG2042 PCIe driver
riscv: sophgo: dts: add pcie controllers for SG2042
riscv: sophgo: dts: enable pcie for PioneerBox

 .../bindings/pci/sophgo,sg2042-pcie-host.yaml |  66 +++++++++
 .../boot/dts/sophgo/sg2042-milkv-pioneer.dts  |  12 ++
 arch/riscv/boot/dts/sophgo/sg2042.dtsi        |  66 +++++++++
 drivers/pci/controller/cadence/Kconfig        |  12 ++
 drivers/pci/controller/cadence/Makefile       |   1 +
 .../controller/cadence/pcie-cadence-host.c    |   2 +-
 drivers/pci/controller/cadence/pcie-cadence.c |   4 +-
 drivers/pci/controller/cadence/pcie-cadence.h |   6 +-
 drivers/pci/controller/cadence/pcie-sg2042.c  | 134 ++++++++++++++++++
 9 files changed, 297 insertions(+), 6 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pci/sophgo,sg2042-pcie-host.yaml
 create mode 100644 drivers/pci/controller/cadence/pcie-sg2042.c

base-commit: 8f5ae30d69d7543eee0d70083daf4de8fe15d585

Signature · 1 line
2.34.1
author
#1 lore raw

PATCH 1/5 dt-bindings: pci: Add Sophgo SG2042 PCIe host

From: Chen Wang <[email protected]>

Add binding for Sophgo SG2042 PCIe host controller.

---
 .../bindings/pci/sophgo,sg2042-pcie-host.yaml | 66 +++++++++++++++++++
 1 file changed, 66 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/sophgo,sg2042-pcie-host.yaml
Documentation/devicetree/bindings/pci/sophgo,sg2042-pcie-host.yaml new file +66 -0
new file mode 100644
index 000000000000..2cca3d113d11
@@ -0,0 +1,66 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/sophgo,sg2042-pcie-host.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Sophgo SG2042 PCIe Host (Cadence PCIe Wrapper)
+
+description:
+  Sophgo SG2042 PCIe host controller is based on the Cadence PCIe core.
+
+maintainers:
+  - Chen Wang <[email protected]>
+
+properties:
+  compatible:
+    const: sophgo,sg2042-pcie-host
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: reg
+      - const: cfg
+
+  vendor-id:
+    const: 0x1f1c
+
+  device-id:
+    const: 0x2042
+
+  msi-parent: true
+
+allOf:
+  - $ref: cdns-pcie-host.yaml#
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - vendor-id
+  - device-id
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    pcie@62000000 {
+      compatible = "sophgo,sg2042-pcie-host";
+      device_type = "pci";
+      reg = <0x62000000  0x00800000>,
+            <0x48000000  0x00001000>;
+      reg-names = "reg", "cfg";
+      #address-cells = <3>;
+      #size-cells = <2>;
+      ranges = <0x81000000 0 0x00000000 0xde000000 0 0x00010000>,
+               <0x82000000 0 0xd0400000 0xd0400000 0 0x0d000000>;
+      bus-range = <0x00 0xff>;
+      vendor-id = <0x1f1c>;
+      device-id = <0x2042>;
+      cdns,no-bar-match-nbits = <48>;
+      msi-parent = <&msi>;
+    };
Signature · 1 line
2.34.1
maintainer Reviewed-by on v1 1/5
#2 lore raw

Re: [PATCH 1/5] dt-bindings: pci: Add Sophgo SG2042 PCIe host

Quoted 10 lines · Chen Wang

From: Chen Wang <[email protected]>

Add binding for Sophgo SG2042 PCIe host controller.

---
 .../bindings/pci/sophgo,sg2042-pcie-host.yaml | 66 +++++++++++++++++++
 1 file changed, 66 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/sophgo,sg2042-pcie-host.yaml
#3 lore raw

Re: [PATCH 1/5] dt-bindings: pci: Add Sophgo SG2042 PCIe host

In reply to Chen Wang
Quoted 49 lines · Chen Wang

From: Chen Wang <[email protected]>

Add binding for Sophgo SG2042 PCIe host controller.

---
 .../bindings/pci/sophgo,sg2042-pcie-host.yaml | 66 +++++++++++++++++++
 1 file changed, 66 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/sophgo,sg2042-pcie-host.yaml
Documentation/devicetree/bindings/pci/sophgo,sg2042-pcie-host.yaml new file +33 -0
new file mode 100644
index 000000000000..2cca3d113d11
@@ -0,0 +1,66 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/sophgo,sg2042-pcie-host.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Sophgo SG2042 PCIe Host (Cadence PCIe Wrapper)
+
+description:
+  Sophgo SG2042 PCIe host controller is based on the Cadence PCIe core.
+
+maintainers:
+  - Chen Wang <[email protected]>
+
+properties:
+  compatible:
+    const: sophgo,sg2042-pcie-host
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: reg
+      - const: cfg
+
+  vendor-id:
+    const: 0x1f1c
+
+  device-id:
+    const: 0x2042
+
+  msi-parent: true

Documentation/devicetree/bindings/pci/sophgo,sg2042-pcie-host.yaml line 43

Quoted 10 lines
Documentation/devicetree/bindings/pci/sophgo,sg2042-pcie-host.yaml new file +10 -0
+
+allOf:
+  - $ref: cdns-pcie-host.yaml#
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - vendor-id
+  - device-id

Why are these IDs 'required'? The default IDs are invalid?

- Mani

Signature · 1 line
மணிவண்ணன் சதாசிவம்
#4 lore raw

Re: [PATCH 1/5] dt-bindings: pci: Add Sophgo SG2042 PCIe host

Quoted 53 lines · Manivannan Sadhasivam
Quoted 52 lines · Chen Wang

From: Chen Wang <[email protected]>

Add binding for Sophgo SG2042 PCIe host controller.

---
  .../bindings/pci/sophgo,sg2042-pcie-host.yaml | 66 +++++++++++++++++++
  1 file changed, 66 insertions(+)

create mode 100644 Documentation/devicetree/bindings/pci/sophgo,sg2042-pcie-host.yaml

Documentation/devicetree/bindings/pci/sophgo,sg2042-pcie-host.yaml new file +36 -0
new file mode 100644
index 000000000000..2cca3d113d11
@@ -0,0 +1,66 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/sophgo,sg2042-pcie-host.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Sophgo SG2042 PCIe Host (Cadence PCIe Wrapper)
+
+description:
+  Sophgo SG2042 PCIe host controller is based on the Cadence PCIe core.
+
+maintainers:
+  - Chen Wang <[email protected]>
+
+properties:
+  compatible:
+    const: sophgo,sg2042-pcie-host
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: reg
+      - const: cfg
+
+  vendor-id:
+    const: 0x1f1c
+
+  device-id:
+    const: 0x2042
+
+  msi-parent: true
+
+allOf:
+  - $ref: cdns-pcie-host.yaml#
Quoted 8 lines

Documentation/devicetree/bindings/pci/sophgo,sg2042-pcie-host.yaml line 43

Quoted 7 lines
Documentation/devicetree/bindings/pci/sophgo,sg2042-pcie-host.yaml new file +7 -0
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - vendor-id
+  - device-id

Why are these IDs 'required'? The default IDs are invalid?

I find the default IDs I read from the SoC is still that for Cadence, it would confused when I run lspci, so I replace the IDs for Sophgo.

Anyway, it's ok for me to remove IDs as "required" in bindings but still set it in DTS.

Thanks,

Chen

Quoted 3 lines

- Mani

author
#5 lore raw

PATCH 2/5 PCI: cadence: Fix NULL pointer error for ops

In reply to Chen Wang

From: Chen Wang <[email protected]>

ops of struct cdns_pcie may be NULL, direct use
will result in a null pointer error.

Add checking of pcie->ops before using it.

Fixes 40d957e6f9eb ("PCI: cadence: Add support to start link and verify link status")
---
 drivers/pci/controller/cadence/pcie-cadence-host.c | 2 +-
 drivers/pci/controller/cadence/pcie-cadence.c      | 4 ++--
 drivers/pci/controller/cadence/pcie-cadence.h      | 6 +++---
 3 files changed, 6 insertions(+), 6 deletions(-)
drivers/pci/controller/cadence/pcie-cadence-host.c +1 -1
index 59a4631de79f..fffd63d6665e 100644
@@ -531,7 +531,7 @@ static int cdns_pcie_host_init_address_translation(struct cdns_pcie_rc *rc)
 	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_PCI_ADDR1(0), addr1);
 	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_DESC1(0), desc1);
 
-	if (pcie->ops->cpu_addr_fixup)
+	if (pcie->ops && pcie->ops->cpu_addr_fixup)
 		cpu_addr = pcie->ops->cpu_addr_fixup(pcie, cpu_addr);
 
 	addr0 = CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS(12) |
drivers/pci/controller/cadence/pcie-cadence.c +2 -2
index 70a19573440e..61806bbd8aa3 100644
@@ -92,7 +92,7 @@ void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, u8 busnr, u8 fn,
 	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_DESC1(r), desc1);
 
 	/* Set the CPU address */
-	if (pcie->ops->cpu_addr_fixup)
+	if (pcie->ops && pcie->ops->cpu_addr_fixup)
 		cpu_addr = pcie->ops->cpu_addr_fixup(pcie, cpu_addr);
 
 	addr0 = CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS(nbits) |
@@ -123,7 +123,7 @@ void cdns_pcie_set_outbound_region_for_normal_msg(struct cdns_pcie *pcie,
 	}
 
 	/* Set the CPU address */
-	if (pcie->ops->cpu_addr_fixup)
+	if (pcie->ops && pcie->ops->cpu_addr_fixup)
 		cpu_addr = pcie->ops->cpu_addr_fixup(pcie, cpu_addr);
 
 	addr0 = CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS(17) |
drivers/pci/controller/cadence/pcie-cadence.h +3 -3
index 1d81c4bf6c6d..2f07ba661bda 100644
@@ -468,7 +468,7 @@ static inline u32 cdns_pcie_ep_fn_readl(struct cdns_pcie *pcie, u8 fn, u32 reg)
 
 static inline int cdns_pcie_start_link(struct cdns_pcie *pcie)
 {
-	if (pcie->ops->start_link)
+	if (pcie->ops && pcie->ops->start_link)
 		return pcie->ops->start_link(pcie);
 
 	return 0;
@@ -476,13 +476,13 @@ static inline int cdns_pcie_start_link(struct cdns_pcie *pcie)
 
 static inline void cdns_pcie_stop_link(struct cdns_pcie *pcie)
 {
-	if (pcie->ops->stop_link)
+	if (pcie->ops && pcie->ops->stop_link)
 		pcie->ops->stop_link(pcie);
 }
 
 static inline bool cdns_pcie_link_up(struct cdns_pcie *pcie)
 {
-	if (pcie->ops->link_up)
+	if (pcie->ops && pcie->ops->link_up)
 		return pcie->ops->link_up(pcie);
 
 	return true;
Signature · 1 line
2.34.1
#6 lore raw

Re: [PATCH 2/5] PCI: cadence: Fix NULL pointer error for ops

Quoted 8 lines · Chen Wang

From: Chen Wang <[email protected]>

ops of struct cdns_pcie may be NULL, direct use
will result in a null pointer error.

Add checking of pcie->ops before using it.

Fixes 40d957e6f9eb ("PCI: cadence: Add support to start link and verify link status")

Do you observe this NULL pointer dereference with an existing driver?

If this is only to make it possible to add a new driver that doesn't supply a pcie->ops pointer, it doesn't need a Fixes: tag because there's not a problem with existing drivers and this change would not need to be backported.

If it *is* a problem with an existing driver, please point out which one.

Quoted 74 lines
---
 drivers/pci/controller/cadence/pcie-cadence-host.c | 2 +-
 drivers/pci/controller/cadence/pcie-cadence.c      | 4 ++--
 drivers/pci/controller/cadence/pcie-cadence.h      | 6 +++---
 3 files changed, 6 insertions(+), 6 deletions(-)
drivers/pci/controller/cadence/pcie-cadence-host.c +1 -1
index 59a4631de79f..fffd63d6665e 100644
@@ -531,7 +531,7 @@ static int cdns_pcie_host_init_address_translation(struct cdns_pcie_rc *rc)
 	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_PCI_ADDR1(0), addr1);
 	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_DESC1(0), desc1);
 
-	if (pcie->ops->cpu_addr_fixup)
+	if (pcie->ops && pcie->ops->cpu_addr_fixup)
 		cpu_addr = pcie->ops->cpu_addr_fixup(pcie, cpu_addr);
 
 	addr0 = CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS(12) |
drivers/pci/controller/cadence/pcie-cadence.c +2 -2
index 70a19573440e..61806bbd8aa3 100644
@@ -92,7 +92,7 @@ void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, u8 busnr, u8 fn,
 	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_DESC1(r), desc1);
 
 	/* Set the CPU address */
-	if (pcie->ops->cpu_addr_fixup)
+	if (pcie->ops && pcie->ops->cpu_addr_fixup)
 		cpu_addr = pcie->ops->cpu_addr_fixup(pcie, cpu_addr);
 
 	addr0 = CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS(nbits) |
@@ -123,7 +123,7 @@ void cdns_pcie_set_outbound_region_for_normal_msg(struct cdns_pcie *pcie,
 	}
 
 	/* Set the CPU address */
-	if (pcie->ops->cpu_addr_fixup)
+	if (pcie->ops && pcie->ops->cpu_addr_fixup)
 		cpu_addr = pcie->ops->cpu_addr_fixup(pcie, cpu_addr);
 
 	addr0 = CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS(17) |
drivers/pci/controller/cadence/pcie-cadence.h +3 -3
index 1d81c4bf6c6d..2f07ba661bda 100644
@@ -468,7 +468,7 @@ static inline u32 cdns_pcie_ep_fn_readl(struct cdns_pcie *pcie, u8 fn, u32 reg)
 
 static inline int cdns_pcie_start_link(struct cdns_pcie *pcie)
 {
-	if (pcie->ops->start_link)
+	if (pcie->ops && pcie->ops->start_link)
 		return pcie->ops->start_link(pcie);
 
 	return 0;
@@ -476,13 +476,13 @@ static inline int cdns_pcie_start_link(struct cdns_pcie *pcie)
 
 static inline void cdns_pcie_stop_link(struct cdns_pcie *pcie)
 {
-	if (pcie->ops->stop_link)
+	if (pcie->ops && pcie->ops->stop_link)
 		pcie->ops->stop_link(pcie);
 }
 
 static inline bool cdns_pcie_link_up(struct cdns_pcie *pcie)
 {
-	if (pcie->ops->link_up)
+	if (pcie->ops && pcie->ops->link_up)
 		return pcie->ops->link_up(pcie);
 
 	return true;
Signature · 1 line
2.34.1
#7 lore raw

Re: [PATCH 2/5] PCI: cadence: Fix NULL pointer error for ops

Quoted 11 lines · Bjorn Helgaas
Quoted 8 lines · Chen Wang

From: Chen Wang <[email protected]>

ops of struct cdns_pcie may be NULL, direct use
will result in a null pointer error.

Add checking of pcie->ops before using it.

Fixes 40d957e6f9eb ("PCI: cadence: Add support to start link and verify link status")

Do you observe this NULL pointer dereference with an existing driver?

Quoted 7 lines

If this is only to make it possible to add a new driver that doesn't supply a pcie->ops pointer, it doesn't need a Fixes: tag because there's not a problem with existing drivers and this change would not need to be backported.

If it *is* a problem with an existing driver, please point out which one.

No, the existing driver does not have this problem. Only my newly added driver doesn't supply a pcie->ops pointer.

I will remove this Fixes tag in next revision.

Thanks,

Chen

[......]

author
#8 lore raw

PATCH 3/5 PCI: sg2042: Add Sophgo SG2042 PCIe driver

In reply to Chen Wang

From: Chen Wang <[email protected]>

Add support for PCIe controller in SG2042 SoC. The controller uses the Cadence PCIe core programmed by pcie-cadence*.c. The PCIe controller will work in host mode only.

---
 drivers/pci/controller/cadence/Kconfig       |  12 ++
 drivers/pci/controller/cadence/Makefile      |   1 +
 drivers/pci/controller/cadence/pcie-sg2042.c | 134 +++++++++++++++++++
 3 files changed, 147 insertions(+)
 create mode 100644 drivers/pci/controller/cadence/pcie-sg2042.c
drivers/pci/controller/cadence/Kconfig +12 -0
index 666e16b6367f..b1f1941d5208 100644
@@ -42,6 +42,17 @@ config PCIE_CADENCE_PLAT_EP
 	  endpoint mode. This PCIe controller may be embedded into many
 	  different vendors SoCs.
 
+config PCIE_SG2042
+	bool "Sophgo SG2042 PCIe controller (host mode)"
+	depends on ARCH_SOPHGO || COMPILE_TEST
+	depends on OF
+	depends on PCI_MSI
+	select PCIE_CADENCE_HOST
+	help
+	  Say Y here if you want to support the Sophgo SG2042 PCIe platform
+	  controller in host mode. Sophgo SG2042 PCIe controller uses Cadence
+	  PCIe core.
+
 config PCI_J721E
 	tristate
 	select PCIE_CADENCE_HOST if PCI_J721E_HOST != n
@@ -67,4 +78,5 @@ config PCI_J721E_EP
 	  Say Y here if you want to support the TI J721E PCIe platform
 	  controller in endpoint mode. TI J721E PCIe controller uses Cadence PCIe
 	  core.
+
 endmenu
drivers/pci/controller/cadence/Makefile +1 -0
index 9bac5fb2f13d..4df4456d9539 100644
@@ -4,3 +4,4 @@ obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host.o
 obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep.o
 obj-$(CONFIG_PCIE_CADENCE_PLAT) += pcie-cadence-plat.o
 obj-$(CONFIG_PCI_J721E) += pci-j721e.o
+obj-$(CONFIG_PCIE_SG2042) += pcie-sg2042.o
drivers/pci/controller/cadence/pcie-sg2042.c new file +134 -0

134 lines not on this page · raw message

Signature · 1 line
2.34.1
#9 lore raw

Re: [PATCH 3/5] PCI: sg2042: Add Sophgo SG2042 PCIe driver

Quoted 65 lines · Chen Wang

From: Chen Wang <[email protected]>

Add support for PCIe controller in SG2042 SoC. The controller uses the Cadence PCIe core programmed by pcie-cadence*.c. The PCIe controller will work in host mode only.

---
  drivers/pci/controller/cadence/Kconfig       |  12 ++
  drivers/pci/controller/cadence/Makefile      |   1 +
  drivers/pci/controller/cadence/pcie-sg2042.c | 134 +++++++++++++++++++
  3 files changed, 147 insertions(+)

create mode 100644 drivers/pci/controller/cadence/pcie-sg2042.c

drivers/pci/controller/cadence/Kconfig +12 -0
index 666e16b6367f..b1f1941d5208 100644
@@ -42,6 +42,17 @@ config PCIE_CADENCE_PLAT_EP
  	  endpoint mode. This PCIe controller may be embedded into many
  	  different vendors SoCs.
 
+config PCIE_SG2042
+	bool "Sophgo SG2042 PCIe controller (host mode)"
+	depends on ARCH_SOPHGO || COMPILE_TEST
+	depends on OF
+	depends on PCI_MSI
+	select PCIE_CADENCE_HOST
+	help
+	  Say Y here if you want to support the Sophgo SG2042 PCIe platform
+	  controller in host mode. Sophgo SG2042 PCIe controller uses Cadence
+	  PCIe core.
+
  config PCI_J721E
  	tristate
  	select PCIE_CADENCE_HOST if PCI_J721E_HOST != n
@@ -67,4 +78,5 @@ config PCI_J721E_EP
  	  Say Y here if you want to support the TI J721E PCIe platform
  	  controller in endpoint mode. TI J721E PCIe controller uses Cadence PCIe
  	  core.
+
  endmenu
drivers/pci/controller/cadence/Makefile +1 -0
index 9bac5fb2f13d..4df4456d9539 100644
@@ -4,3 +4,4 @@ obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host.o
  obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep.o
  obj-$(CONFIG_PCIE_CADENCE_PLAT) += pcie-cadence-plat.o
  obj-$(CONFIG_PCI_J721E) += pci-j721e.o
+obj-$(CONFIG_PCIE_SG2042) += pcie-sg2042.o
drivers/pci/controller/cadence/pcie-sg2042.c new file +8 -0
new file mode 100644
index 000000000000..fe434dc2967e
@@ -0,0 +1,134 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * pcie-sg2042 - PCIe controller driver for Sophgo SG2042 SoC
+ *
+ * Copyright (C) 2025 Sophgo Technology Inc.
+ * Copyright (C) 2025 Chen Wang <[email protected]>
+ */
+

drivers/pci/controller/cadence/pcie-sg2042.c line 18

Quoted 10 lines
drivers/pci/controller/cadence/pcie-sg2042.c new file +10 -0
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+
+#include "pcie-cadence.h"
+
+/*
+ * SG2042 only support 4-byte aligned access, so for the rootbus (i.e. to read

support -> supports

drivers/pci/controller/cadence/pcie-sg2042.c line 23

Quoted 5 lines
drivers/pci/controller/cadence/pcie-sg2042.c new file +5 -0
+ * the Root Port itself, read32 is required. For non-rootbus (i.e. to read
+ * the PCIe peripheral registers, supports 1/2/4 byte aligned access, so
+ * directly using read should be fine.
+ *
+ * The same is true for write.

[clip]

Quoted 12 lines
drivers/pci/controller/cadence/pcie-sg2042.c new file +12 -0
+static int sg2042_pcie_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct pci_host_bridge *bridge;
+	struct cdns_pcie *pcie;
+	struct cdns_pcie_rc *rc;
+	int ret;
+
+	pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
+	if (!pcie)
+		return -ENOMEM;
+

drivers/pci/controller/cadence/pcie-sg2042.c line 72

Quoted 10 lines
drivers/pci/controller/cadence/pcie-sg2042.c new file +10 -0
+	bridge = devm_pci_alloc_host_bridge(dev, sizeof(*rc));
+	if (!bridge) {
+		dev_err(dev, "Failed to alloc host bridge!\n");
+		return -ENOMEM;
+	}
+
+	bridge->ops = &sg2042_pcie_host_ops;
+
+	rc = pci_host_bridge_priv(bridge);
+	pcie = &rc->pcie;

First, pcie is allocated and then reassigned to &rc->pcie, which makes the initial allocation effectively leaked and unnecessary.

Quoted 25 lines
drivers/pci/controller/cadence/pcie-sg2042.c new file +25 -0
+	pcie->dev = dev;
+
+	platform_set_drvdata(pdev, pcie);
+
+	pm_runtime_enable(dev);
+
+	ret = pm_runtime_get_sync(dev);
+	if (ret < 0) {
+		dev_err(dev, "pm_runtime_get_sync failed\n");
+		goto err_get_sync;
+	}
+
+	ret = cdns_pcie_init_phy(dev, pcie);
+	if (ret) {
+		dev_err(dev, "Failed to init phy!\n");
+		goto err_get_sync;
+	}
+
+	ret = cdns_pcie_host_setup(rc);
+	if (ret < 0) {
+		dev_err(dev, "Failed to setup host!\n");
+		goto err_host_setup;
+	}
+
+	return 0;

drivers/pci/controller/cadence/pcie-sg2042.c line 107

Quoted 10 lines
drivers/pci/controller/cadence/pcie-sg2042.c new file +10 -0
+
+err_host_setup:
+	cdns_pcie_disable_phy(pcie);
+
+err_get_sync:
+	pm_runtime_put(dev);
+	pm_runtime_disable(dev);
+
+	return ret;
+}

Thanks,
Alok

#10 lore raw

Re: [PATCH 3/5] PCI: sg2042: Add Sophgo SG2042 PCIe driver

Quoted 5 lines · ALOK TIWARI
Quoted 2 lines · Chen Wang

From: Chen Wang <[email protected]>

[......]

Quoted 6 lines
Quoted 6 lines
drivers/pci/controller/cadence/pcie-sg2042.c new file +6 -0
+
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
Quoted 8 lines
Quoted 6 lines
drivers/pci/controller/cadence/pcie-sg2042.c new file +5 -0
+
+#include "pcie-cadence.h"
+
+/*
+ * SG2042 only support 4-byte aligned access, so for the rootbus 

(i.e. to read

support -> supports

Nice catch!

Quoted 25 lines
Quoted 8 lines

+ * the Root Port itself, read32 is required. For non-rootbus (i.e. to read
+ * the PCIe peripheral registers, supports 1/2/4 byte aligned access, so
+ * directly using read should be fine.
+ *
+ * The same is true for write.

[clip]

Quoted 16 lines
drivers/pci/controller/cadence/pcie-sg2042.c new file +16 -0
+static int sg2042_pcie_probe(struct platform_device *pdev)
+{
+    struct device *dev = &pdev->dev;
+    struct pci_host_bridge *bridge;
+    struct cdns_pcie *pcie;
+    struct cdns_pcie_rc *rc;
+    int ret;
+
+    pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
+    if (!pcie)
+        return -ENOMEM;
+
+    bridge = devm_pci_alloc_host_bridge(dev, sizeof(*rc));
+    if (!bridge) {
+        dev_err(dev, "Failed to alloc host bridge!\n");
+        return -ENOMEM;
Quoted 8 lines

drivers/pci/controller/cadence/pcie-sg2042.c line 72

Quoted 6 lines

+    }

drivers/pci/controller/cadence/pcie-sg2042.c new file +5 -0
+
+    bridge->ops = &sg2042_pcie_host_ops;
+
+    rc = pci_host_bridge_priv(bridge);
+    pcie = &rc->pcie;

First, pcie is allocated and then reassigned to &rc->pcie, which makes the initial allocation effectively leaked and unnecessary.

My fault.

Thanks,

Chen

[......]

Quoted 3 lines

Thanks,
Alok

maintainer
#11 lore raw

Re: [PATCH 3/5] PCI: sg2042: Add Sophgo SG2042 PCIe driver

In reply to Chen Wang
Quoted 57 lines · Chen Wang

From: Chen Wang <[email protected]>

Add support for PCIe controller in SG2042 SoC. The controller uses the Cadence PCIe core programmed by pcie-cadence*.c. The PCIe controller will work in host mode only.

---
 drivers/pci/controller/cadence/Kconfig       |  12 ++
 drivers/pci/controller/cadence/Makefile      |   1 +
 drivers/pci/controller/cadence/pcie-sg2042.c | 134 +++++++++++++++++++
 3 files changed, 147 insertions(+)
 create mode 100644 drivers/pci/controller/cadence/pcie-sg2042.c
drivers/pci/controller/cadence/Kconfig +12 -0
index 666e16b6367f..b1f1941d5208 100644
@@ -42,6 +42,17 @@ config PCIE_CADENCE_PLAT_EP
 	  endpoint mode. This PCIe controller may be embedded into many
 	  different vendors SoCs.
 
+config PCIE_SG2042
+	bool "Sophgo SG2042 PCIe controller (host mode)"
+	depends on ARCH_SOPHGO || COMPILE_TEST
+	depends on OF
+	depends on PCI_MSI
+	select PCIE_CADENCE_HOST
+	help
+	  Say Y here if you want to support the Sophgo SG2042 PCIe platform
+	  controller in host mode. Sophgo SG2042 PCIe controller uses Cadence
+	  PCIe core.
+
 config PCI_J721E
 	tristate
 	select PCIE_CADENCE_HOST if PCI_J721E_HOST != n
@@ -67,4 +78,5 @@ config PCI_J721E_EP
 	  Say Y here if you want to support the TI J721E PCIe platform
 	  controller in endpoint mode. TI J721E PCIe controller uses Cadence PCIe
 	  core.
+
 endmenu
drivers/pci/controller/cadence/Makefile +1 -0
index 9bac5fb2f13d..4df4456d9539 100644
@@ -4,3 +4,4 @@ obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host.o
 obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep.o
 obj-$(CONFIG_PCIE_CADENCE_PLAT) += pcie-cadence-plat.o
 obj-$(CONFIG_PCI_J721E) += pci-j721e.o
+obj-$(CONFIG_PCIE_SG2042) += pcie-sg2042.o
drivers/pci/controller/cadence/pcie-sg2042.c new file +0 -0
new file mode 100644
index 000000000000..fe434dc2967e

drivers/pci/controller/cadence/pcie-sg2042.c line 10

Quoted 10 lines
drivers/pci/controller/cadence/pcie-sg2042.c new file +10 -0
@@ -0,0 +1,134 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * pcie-sg2042 - PCIe controller driver for Sophgo SG2042 SoC
+ *
+ * Copyright (C) 2025 Sophgo Technology Inc.
+ * Copyright (C) 2025 Chen Wang <[email protected]>
+ */
+
+#include <linux/kernel.h>
+#include <linux/of.h>

Looks like you just need mod_devicetable.h instead.

Quoted 8 lines
drivers/pci/controller/cadence/pcie-sg2042.c new file +8 -0
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+
+#include "pcie-cadence.h"
+
+/*
+ * SG2042 only support 4-byte aligned access, so for the rootbus (i.e. to read

drivers/pci/controller/cadence/pcie-sg2042.c line 28

Quoted 10 lines
drivers/pci/controller/cadence/pcie-sg2042.c new file +10 -0
+ * the Root Port itself, read32 is required. For non-rootbus (i.e. to read
+ * the PCIe peripheral registers, supports 1/2/4 byte aligned access, so
+ * directly using read should be fine.
+ *
+ * The same is true for write.
+ */
+static int sg2042_pcie_config_read(struct pci_bus *bus, unsigned int devfn,
+				   int where, int size, u32 *value)
+{
+	if (pci_is_root_bus(bus))

You can have separate pci_ops for the root bus and child buses. Do that and then sg2042_pcie_config_read() goes away. IIRC, there's examples in the tree of your exact issue (root bus being 32-bit only).

Quoted 96 lines
drivers/pci/controller/cadence/pcie-sg2042.c new file +96 -0
+		return pci_generic_config_read32(bus, devfn, where, size,
+						 value);
+
+	return pci_generic_config_read(bus, devfn, where, size, value);
+}
+
+static int sg2042_pcie_config_write(struct pci_bus *bus, unsigned int devfn,
+				    int where, int size, u32 value)
+{
+	if (pci_is_root_bus(bus))
+		return pci_generic_config_write32(bus, devfn, where, size,
+						  value);
+
+	return pci_generic_config_write(bus, devfn, where, size, value);
+}
+
+static struct pci_ops sg2042_pcie_host_ops = {
+	.map_bus	= cdns_pci_map_bus,
+	.read		= sg2042_pcie_config_read,
+	.write		= sg2042_pcie_config_write,
+};
+
+static int sg2042_pcie_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct pci_host_bridge *bridge;
+	struct cdns_pcie *pcie;
+	struct cdns_pcie_rc *rc;
+	int ret;
+
+	pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
+	if (!pcie)
+		return -ENOMEM;
+
+	bridge = devm_pci_alloc_host_bridge(dev, sizeof(*rc));
+	if (!bridge) {
+		dev_err(dev, "Failed to alloc host bridge!\n");
+		return -ENOMEM;
+	}
+
+	bridge->ops = &sg2042_pcie_host_ops;
+
+	rc = pci_host_bridge_priv(bridge);
+	pcie = &rc->pcie;
+	pcie->dev = dev;
+
+	platform_set_drvdata(pdev, pcie);
+
+	pm_runtime_enable(dev);
+
+	ret = pm_runtime_get_sync(dev);
+	if (ret < 0) {
+		dev_err(dev, "pm_runtime_get_sync failed\n");
+		goto err_get_sync;
+	}
+
+	ret = cdns_pcie_init_phy(dev, pcie);
+	if (ret) {
+		dev_err(dev, "Failed to init phy!\n");
+		goto err_get_sync;
+	}
+
+	ret = cdns_pcie_host_setup(rc);
+	if (ret < 0) {
+		dev_err(dev, "Failed to setup host!\n");
+		goto err_host_setup;
+	}
+
+	return 0;
+
+err_host_setup:
+	cdns_pcie_disable_phy(pcie);
+
+err_get_sync:
+	pm_runtime_put(dev);
+	pm_runtime_disable(dev);
+
+	return ret;
+}
+
+static void sg2042_pcie_shutdown(struct platform_device *pdev)
+{
+	struct cdns_pcie *pcie = platform_get_drvdata(pdev);
+	struct device *dev = &pdev->dev;
+
+	cdns_pcie_disable_phy(pcie);
+
+	pm_runtime_put(dev);
+	pm_runtime_disable(dev);
+}
+
+static const struct of_device_id sg2042_pcie_of_match[] = {
+	{ .compatible = "sophgo,sg2042-pcie-host" },
+	{},
+};
+

drivers/pci/controller/cadence/pcie-sg2042.c line 134

Quoted 10 lines
drivers/pci/controller/cadence/pcie-sg2042.c new file +10 -0
+static struct platform_driver sg2042_pcie_driver = {
+	.driver = {
+		.name		= "sg2042-pcie",
+		.of_match_table	= sg2042_pcie_of_match,
+		.pm		= &cdns_pcie_pm_ops,
+	},
+	.probe		= sg2042_pcie_probe,
+	.shutdown	= sg2042_pcie_shutdown,
+};
+builtin_platform_driver(sg2042_pcie_driver);

What prevents this from being a module?

Rob

#12 lore raw

Re: [PATCH 3/5] PCI: sg2042: Add Sophgo SG2042 PCIe driver

Quoted 1 line · Rob Herring

On Thu, Aug 28, 2025 at 10:17:40AM +0800, Chen Wang wrote:

[......]

Quoted 9 lines
Quoted 9 lines
drivers/pci/controller/cadence/pcie-sg2042.c new file +3 -0
new file mode 100644
index 000000000000..fe434dc2967e
@@ -0,0 +1,134 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * pcie-sg2042 - PCIe controller driver for Sophgo SG2042 SoC
Quoted 8 lines

drivers/pci/controller/cadence/pcie-sg2042.c line 10

Quoted 7 lines
drivers/pci/controller/cadence/pcie-sg2042.c new file +7 -0
+ *
+ * Copyright (C) 2025 Sophgo Technology Inc.
+ * Copyright (C) 2025 Chen Wang <[email protected]>
+ */
+
+#include <linux/kernel.h>
+#include <linux/of.h>

Looks like you just need mod_devicetable.h instead.

Thanks, I tried and seems just mod_devicetable.h does work.

To be honest, I am more curious about how to know which header files should be included. Is it just based on experience, because sometimes including these or those header files will compile without any problems.

Quoted 13 lines
Quoted 13 lines
drivers/pci/controller/cadence/pcie-sg2042.c new file +13 -0
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+
+#include "pcie-cadence.h"
+
+/*
+ * SG2042 only support 4-byte aligned access, so for the rootbus (i.e. to read
+ * the Root Port itself, read32 is required. For non-rootbus (i.e. to read
+ * the PCIe peripheral registers, supports 1/2/4 byte aligned access, so
+ * directly using read should be fine.
+ *
+ * The same is true for write.
Quoted 8 lines

drivers/pci/controller/cadence/pcie-sg2042.c line 28

Quoted 5 lines
drivers/pci/controller/cadence/pcie-sg2042.c new file +5 -0
+ */
+static int sg2042_pcie_config_read(struct pci_bus *bus, unsigned int devfn,
+				   int where, int size, u32 *value)
+{
+	if (pci_is_root_bus(bus))

You can have separate pci_ops for the root bus and child buses. Do that and then sg2042_pcie_config_read() goes away. IIRC, there's examples in the tree of your exact issue (root bus being 32-bit only).

Yes, you're right, I learned it. Thanks,

Quoted 22 lines
Quoted 22 lines
drivers/pci/controller/cadence/pcie-sg2042.c new file +22 -0
+		return pci_generic_config_read32(bus, devfn, where, size,
+						 value);
+
+	return pci_generic_config_read(bus, devfn, where, size, value);
+}
+
+static int sg2042_pcie_config_write(struct pci_bus *bus, unsigned int devfn,
+				    int where, int size, u32 value)
+{
+	if (pci_is_root_bus(bus))
+		return pci_generic_config_write32(bus, devfn, where, size,
+						  value);
+
+	return pci_generic_config_write(bus, devfn, where, size, value);
+}
+
+static struct pci_ops sg2042_pcie_host_ops = {
+	.map_bus	= cdns_pci_map_bus,
+	.read		= sg2042_pcie_config_read,
+	.write		= sg2042_pcie_config_write,
+};
+

[......]

Quoted 4 lines
Quoted 4 lines
drivers/pci/controller/cadence/pcie-sg2042.c new file +4 -0
+
+static struct platform_driver sg2042_pcie_driver = {
+	.driver = {
+		.name		= "sg2042-pcie",
Quoted 8 lines

drivers/pci/controller/cadence/pcie-sg2042.c line 134

Quoted 7 lines
drivers/pci/controller/cadence/pcie-sg2042.c new file +7 -0
+		.of_match_table	= sg2042_pcie_of_match,
+		.pm		= &cdns_pcie_pm_ops,
+	},
+	.probe		= sg2042_pcie_probe,
+	.shutdown	= sg2042_pcie_shutdown,
+};
+builtin_platform_driver(sg2042_pcie_driver);

What prevents this from being a module?

Well, I'll check again.

Thanks.

Chen

Quoted 2 lines

Rob

#13 lore raw

Re: [PATCH 3/5] PCI: sg2042: Add Sophgo SG2042 PCIe driver

In reply to Chen Wang
Quoted 6 lines · Chen Wang

From: Chen Wang <[email protected]>

Add support for PCIe controller in SG2042 SoC. The controller uses the Cadence PCIe core programmed by pcie-cadence*.c. The PCIe controller will work in host mode only.

Supported data rate, lanes etc...

Quoted 13 lines
---
 drivers/pci/controller/cadence/Kconfig       |  12 ++
 drivers/pci/controller/cadence/Makefile      |   1 +
 drivers/pci/controller/cadence/pcie-sg2042.c | 134 +++++++++++++++++++
 3 files changed, 147 insertions(+)
 create mode 100644 drivers/pci/controller/cadence/pcie-sg2042.c
drivers/pci/controller/cadence/Kconfig +0 -0
index 666e16b6367f..b1f1941d5208 100644

drivers/pci/controller/cadence/Kconfig config PCIE_CADENCE_PLAT_EP · line 45

Quoted 4 lines
drivers/pci/controller/cadence/Kconfig +1 -0
@@ -42,6 +42,17 @@ config PCIE_CADENCE_PLAT_EP
 	  endpoint mode. This PCIe controller may be embedded into many
 	  different vendors SoCs.
 
+config PCIE_SG2042

PCIE_SG2042_HOST

drivers/pci/controller/cadence/Kconfig config PCIE_CADENCE_PLAT_EP · line 46

Quoted 1 line
drivers/pci/controller/cadence/Kconfig +1 -0
+	bool "Sophgo SG2042 PCIe controller (host mode)"

Since this driver doesn't implement irqchip, you should make it tristate and as a module.

drivers/pci/controller/cadence/Kconfig config PCIE_CADENCE_PLAT_EP · line 48

Quoted 2 lines
drivers/pci/controller/cadence/Kconfig +2 -0
+	depends on ARCH_SOPHGO || COMPILE_TEST
+	depends on OF
	depends on OF && (ARCH_SOPHGO || COMPILE_TEST)
Quoted 86 lines
drivers/pci/controller/cadence/Kconfig +8 -0
+	depends on PCI_MSI
+	select PCIE_CADENCE_HOST
+	help
+	  Say Y here if you want to support the Sophgo SG2042 PCIe platform
+	  controller in host mode. Sophgo SG2042 PCIe controller uses Cadence
+	  PCIe core.
+
 config PCI_J721E
 	tristate
 	select PCIE_CADENCE_HOST if PCI_J721E_HOST != n
@@ -67,4 +78,5 @@ config PCI_J721E_EP
 	  Say Y here if you want to support the TI J721E PCIe platform
 	  controller in endpoint mode. TI J721E PCIe controller uses Cadence PCIe
 	  core.
+
 endmenu
drivers/pci/controller/cadence/Makefile +1 -0
index 9bac5fb2f13d..4df4456d9539 100644
@@ -4,3 +4,4 @@ obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host.o
 obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep.o
 obj-$(CONFIG_PCIE_CADENCE_PLAT) += pcie-cadence-plat.o
 obj-$(CONFIG_PCI_J721E) += pci-j721e.o
+obj-$(CONFIG_PCIE_SG2042) += pcie-sg2042.o
drivers/pci/controller/cadence/pcie-sg2042.c new file +55 -0
new file mode 100644
index 000000000000..fe434dc2967e
@@ -0,0 +1,134 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * pcie-sg2042 - PCIe controller driver for Sophgo SG2042 SoC
+ *
+ * Copyright (C) 2025 Sophgo Technology Inc.
+ * Copyright (C) 2025 Chen Wang <[email protected]>
+ */
+
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+
+#include "pcie-cadence.h"
+
+/*
+ * SG2042 only support 4-byte aligned access, so for the rootbus (i.e. to read
+ * the Root Port itself, read32 is required. For non-rootbus (i.e. to read
+ * the PCIe peripheral registers, supports 1/2/4 byte aligned access, so
+ * directly using read should be fine.
+ *
+ * The same is true for write.
+ */
+static int sg2042_pcie_config_read(struct pci_bus *bus, unsigned int devfn,
+				   int where, int size, u32 *value)
+{
+	if (pci_is_root_bus(bus))
+		return pci_generic_config_read32(bus, devfn, where, size,
+						 value);
+
+	return pci_generic_config_read(bus, devfn, where, size, value);
+}
+
+static int sg2042_pcie_config_write(struct pci_bus *bus, unsigned int devfn,
+				    int where, int size, u32 value)
+{
+	if (pci_is_root_bus(bus))
+		return pci_generic_config_write32(bus, devfn, where, size,
+						  value);
+
+	return pci_generic_config_write(bus, devfn, where, size, value);
+}
+
+static struct pci_ops sg2042_pcie_host_ops = {
+	.map_bus	= cdns_pci_map_bus,
+	.read		= sg2042_pcie_config_read,
+	.write		= sg2042_pcie_config_write,
+};
+
+static int sg2042_pcie_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct pci_host_bridge *bridge;
+	struct cdns_pcie *pcie;

drivers/pci/controller/cadence/pcie-sg2042.c line 65

Quoted 10 lines
drivers/pci/controller/cadence/pcie-sg2042.c new file +10 -0
+	struct cdns_pcie_rc *rc;
+	int ret;
+
+	pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
+	if (!pcie)
+		return -ENOMEM;
+
+	bridge = devm_pci_alloc_host_bridge(dev, sizeof(*rc));
+	if (!bridge) {
+		dev_err(dev, "Failed to alloc host bridge!\n");

Use dev_err_probe() here and below.

drivers/pci/controller/cadence/pcie-sg2042.c line 72

Quoted 7 lines
drivers/pci/controller/cadence/pcie-sg2042.c new file +7 -0
+		return -ENOMEM;
+	}
+
+	bridge->ops = &sg2042_pcie_host_ops;
+
+	rc = pci_host_bridge_priv(bridge);
+	pcie = &rc->pcie;

You are setting drvdata only below.

drivers/pci/controller/cadence/pcie-sg2042.c line 84

Quoted 12 lines
drivers/pci/controller/cadence/pcie-sg2042.c new file +12 -0
+	pcie->dev = dev;
+
+	platform_set_drvdata(pdev, pcie);
+
+	pm_runtime_enable(dev);
+
+	ret = pm_runtime_get_sync(dev);
+	if (ret < 0) {
+		dev_err(dev, "pm_runtime_get_sync failed\n");
+		goto err_get_sync;
+	}
+

Why do you need pm_runtime_get_sync()? DT binding doesn't provide a power-domain, so you just need:

pm_runtime_set_active()
pm_runtime_no_callbacks()
devm_pm_runtime_enable()

Quoted 23 lines
drivers/pci/controller/cadence/pcie-sg2042.c new file +23 -0
+	ret = cdns_pcie_init_phy(dev, pcie);
+	if (ret) {
+		dev_err(dev, "Failed to init phy!\n");
+		goto err_get_sync;
+	}
+
+	ret = cdns_pcie_host_setup(rc);
+	if (ret < 0) {
+		dev_err(dev, "Failed to setup host!\n");
+		goto err_host_setup;
+	}
+
+	return 0;
+
+err_host_setup:
+	cdns_pcie_disable_phy(pcie);
+
+err_get_sync:
+	pm_runtime_put(dev);
+	pm_runtime_disable(dev);
+
+	return ret;
+}

drivers/pci/controller/cadence/pcie-sg2042.c line 117

Quoted 10 lines
drivers/pci/controller/cadence/pcie-sg2042.c new file +10 -0
+
+static void sg2042_pcie_shutdown(struct platform_device *pdev)
+{
+	struct cdns_pcie *pcie = platform_get_drvdata(pdev);
+	struct device *dev = &pdev->dev;
+
+	cdns_pcie_disable_phy(pcie);
+
+	pm_runtime_put(dev);
+	pm_runtime_disable(dev);

You don't need these as per my above suggestion.

Quoted 4 lines
drivers/pci/controller/cadence/pcie-sg2042.c new file +4 -0
+}
+
+static const struct of_device_id sg2042_pcie_of_match[] = {
+	{ .compatible = "sophgo,sg2042-pcie-host" },

drivers/pci/controller/cadence/pcie-sg2042.c line 131

Quoted 10 lines
drivers/pci/controller/cadence/pcie-sg2042.c new file +10 -0
+	{},
+};
+
+static struct platform_driver sg2042_pcie_driver = {
+	.driver = {
+		.name		= "sg2042-pcie",
+		.of_match_table	= sg2042_pcie_of_match,
+		.pm		= &cdns_pcie_pm_ops,
+	},
+	.probe		= sg2042_pcie_probe,

Why no remove()?

- Mani

Signature · 1 line
மணிவண்ணன் சதாசிவம்
#14 lore raw

Re: [PATCH 3/5] PCI: sg2042: Add Sophgo SG2042 PCIe driver

Quoted 8 lines · Manivannan Sadhasivam
Quoted 6 lines · Chen Wang

From: Chen Wang <[email protected]>

Add support for PCIe controller in SG2042 SoC. The controller uses the Cadence PCIe core programmed by pcie-cadence*.c. The PCIe controller will work in host mode only.

Supported data rate, lanes etc...

OK, I will add these descriptions in next revision.

Quoted 16 lines
Quoted 16 lines
---
  drivers/pci/controller/cadence/Kconfig       |  12 ++
  drivers/pci/controller/cadence/Makefile      |   1 +
  drivers/pci/controller/cadence/pcie-sg2042.c | 134 +++++++++++++++++++
  3 files changed, 147 insertions(+)

create mode 100644 drivers/pci/controller/cadence/pcie-sg2042.c

drivers/pci/controller/cadence/Kconfig +0 -0
index 666e16b6367f..b1f1941d5208 100644
@@ -42,6 +42,17 @@ config PCIE_CADENCE_PLAT_EP
  	  endpoint mode. This PCIe controller may be embedded into many
  	  different vendors SoCs.
 
Quoted 2 lines

drivers/pci/controller/cadence/Kconfig config PCIE_CADENCE_PLAT_EP · line 45

Quoted 1 line
drivers/pci/controller/cadence/Kconfig +1 -0
+config PCIE_SG2042

PCIE_SG2042_HOST

ok

Quoted 4 lines

drivers/pci/controller/cadence/Kconfig config PCIE_CADENCE_PLAT_EP · line 46

Quoted 2 lines
drivers/pci/controller/cadence/Kconfig +1 -0
+	bool "Sophgo SG2042 PCIe controller (host mode)"

Since this driver doesn't implement irqchip, you should make it tristate and as a module.

Yes, I will implement it as a module.

Quoted 4 lines

drivers/pci/controller/cadence/Kconfig config PCIE_CADENCE_PLAT_EP · line 48

Quoted 3 lines
drivers/pci/controller/cadence/Kconfig +2 -0
+	depends on ARCH_SOPHGO || COMPILE_TEST
+	depends on OF
	depends on OF && (ARCH_SOPHGO || COMPILE_TEST)

OK

[......]

Quoted 5 lines

drivers/pci/controller/cadence/Kconfig config PCIE_CADENCE_PLAT_EP · line 52

Quoted 4 lines
drivers/pci/controller/cadence/Kconfig +4 -0
+
+	bridge = devm_pci_alloc_host_bridge(dev, sizeof(*rc));
+	if (!bridge) {
+		dev_err(dev, "Failed to alloc host bridge!\n");

Use dev_err_probe() here and below.

OK

Quoted 8 lines

drivers/pci/controller/cadence/Kconfig config PCIE_CADENCE_PLAT_EP

Quoted 7 lines
drivers/pci/controller/cadence/Kconfig +7 -0
+		return -ENOMEM;
+	}
+
+	bridge->ops = &sg2042_pcie_host_ops;
+
+	rc = pci_host_bridge_priv(bridge);
+	pcie = &rc->pcie;

You are setting drvdata only below.

Sorry, I don't understand your question here. I guess you are confused about the statement platform_set_drvdata(pdev, pcie);. Let me explain why we need to do like this.

Originally, I defined a drvdata stucture:

struct sg2042_pcie {
    struct cdns_pcie    *cdns_pcie;

    // other properties
};

But after code cleanup, I find there is only "cdns_pcie" left, so I remove the struct sg2042_pcie and directy set cdns_pcie (in new version, it is renamed to pcie) as drvdata.

Quoted 15 lines

drivers/pci/controller/cadence/Kconfig

Quoted 12 lines
drivers/pci/controller/cadence/Kconfig +12 -0
+	pcie->dev = dev;
+
+	platform_set_drvdata(pdev, pcie);
+
+	pm_runtime_enable(dev);
+
+	ret = pm_runtime_get_sync(dev);
+	if (ret < 0) {
+		dev_err(dev, "pm_runtime_get_sync failed\n");
+		goto err_get_sync;
+	}
+

Why do you need pm_runtime_get_sync()? DT binding doesn't provide a power-domain, so you just need:

Quoted 3 lines

pm_runtime_set_active()
pm_runtime_no_callbacks()
devm_pm_runtime_enable()

OK, I will improve this.

Quoted 26 lines
Quoted 26 lines
drivers/pci/controller/cadence/Kconfig +26 -0
+	ret = cdns_pcie_init_phy(dev, pcie);
+	if (ret) {
+		dev_err(dev, "Failed to init phy!\n");
+		goto err_get_sync;
+	}
+
+	ret = cdns_pcie_host_setup(rc);
+	if (ret < 0) {
+		dev_err(dev, "Failed to setup host!\n");
+		goto err_host_setup;
+	}
+
+	return 0;
+
+err_host_setup:
+	cdns_pcie_disable_phy(pcie);
+
+err_get_sync:
+	pm_runtime_put(dev);
+	pm_runtime_disable(dev);
+
+	return ret;
+}
+
+static void sg2042_pcie_shutdown(struct platform_device *pdev)
+{
Quoted 8 lines

drivers/pci/controller/cadence/Kconfig

Quoted 7 lines
drivers/pci/controller/cadence/Kconfig +7 -0
+	struct cdns_pcie *pcie = platform_get_drvdata(pdev);
+	struct device *dev = &pdev->dev;
+
+	cdns_pcie_disable_phy(pcie);
+
+	pm_runtime_put(dev);
+	pm_runtime_disable(dev);

You don't need these as per my above suggestion.

OK.

Quoted 7 lines
Quoted 7 lines
drivers/pci/controller/cadence/Kconfig +7 -0
+}
+
+static const struct of_device_id sg2042_pcie_of_match[] = {
+	{ .compatible = "sophgo,sg2042-pcie-host" },
+	{},
+};
+
Quoted 8 lines

drivers/pci/controller/cadence/Kconfig

Quoted 7 lines
drivers/pci/controller/cadence/Kconfig +7 -0
+static struct platform_driver sg2042_pcie_driver = {
+	.driver = {
+		.name		= "sg2042-pcie",
+		.of_match_table	= sg2042_pcie_of_match,
+		.pm		= &cdns_pcie_pm_ops,
+	},
+	.probe		= sg2042_pcie_probe,

Why no remove()?

OK, I will replace shutdown with remove when I implement it as a module in next revision.

Thanks,

Chen

Quoted 3 lines

- Mani

author
#15 lore raw

PATCH 4/5 riscv: sophgo: dts: add pcie controllers for SG2042

In reply to Chen Wang

From: Chen Wang <[email protected]>

Add PCIe controller nodes in DTS for Sophgo SG2042. Default they are disabled.

---
 arch/riscv/boot/dts/sophgo/sg2042.dtsi | 66 ++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)
arch/riscv/boot/dts/sophgo/sg2042.dtsi +66 -0
index b3e4d3c18fdc..346aba5bd9bf 100644
@@ -220,6 +220,72 @@ clkgen: clock-controller@7030012000 {
 			#clock-cells = <1>;
 		};
 
+		pcie_rc0: pcie@7060000000 {
+			compatible = "sophgo,sg2042-pcie-host";
+			device_type = "pci";
+			reg = <0x70 0x60000000  0x0 0x02000000>,
+			      <0x40 0x00000000  0x0 0x00001000>;
+			reg-names = "reg", "cfg";
+			linux,pci-domain = <0>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+			ranges = <0x01000000 0x0  0xc0000000  0x40 0xc0000000  0x0 0x00400000>,
+				 <0x42000000 0x0  0xd0000000  0x40 0xd0000000  0x0 0x10000000>,
+				 <0x02000000 0x0  0xe0000000  0x40 0xe0000000  0x0 0x20000000>,
+				 <0x43000000 0x42 0x00000000  0x42 0x00000000  0x2 0x00000000>,
+				 <0x03000000 0x41 0x00000000  0x41 0x00000000  0x1 0x00000000>;
+			bus-range = <0x0 0xff>;
+			vendor-id = <0x1f1c>;
+			device-id = <0x2042>;
+			cdns,no-bar-match-nbits = <48>;
+			msi-parent = <&msi>;
+			status = "disabled";
+		};
+
+		pcie_rc1: pcie@7062000000 {
+			compatible = "sophgo,sg2042-pcie-host";
+			device_type = "pci";
+			reg = <0x70 0x62000000  0x0 0x00800000>,
+			      <0x48 0x00000000  0x0 0x00001000>;
+			reg-names = "reg", "cfg";
+			linux,pci-domain = <1>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+			ranges = <0x01000000 0x0  0xc0800000  0x48 0xc0800000  0x0 0x00400000>,
+				 <0x42000000 0x0  0xd0000000  0x48 0xd0000000  0x0 0x10000000>,
+				 <0x02000000 0x0  0xe0000000  0x48 0xe0000000  0x0 0x20000000>,
+				 <0x03000000 0x49 0x00000000  0x49 0x00000000  0x1 0x00000000>,
+				 <0x43000000 0x4a 0x00000000  0x4a 0x00000000  0x2 0x00000000>;
+			bus-range = <0x0 0xff>;
+			vendor-id = <0x1f1c>;
+			device-id = <0x2042>;
+			cdns,no-bar-match-nbits = <48>;
+			msi-parent = <&msi>;
+			status = "disabled";
+		};
+
+		pcie_rc2: pcie@7062800000 {
+			compatible = "sophgo,sg2042-pcie-host";
+			device_type = "pci";
+			reg = <0x70 0x62800000  0x0 0x00800000>,
+			      <0x4c 0x00000000  0x0 0x00001000>;
+			reg-names = "reg", "cfg";
+			linux,pci-domain = <2>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+			ranges = <0x01000000 0x0  0xc0c00000  0x4c 0xc0c00000  0x0 0x00400000>,
+				 <0x42000000 0x0  0xf8000000  0x4c 0xf8000000  0x0 0x04000000>,
+				 <0x02000000 0x0  0xfc000000  0x4c 0xfc000000  0x0 0x04000000>,
+				 <0x43000000 0x4e 0x00000000  0x4e 0x00000000  0x2 0x00000000>,
+				 <0x03000000 0x4d 0x00000000  0x4d 0x00000000  0x1 0x00000000>;
+			bus-range = <0x0 0xff>;
+			vendor-id = <0x1f1c>;
+			device-id = <0x2042>;
+			cdns,no-bar-match-nbits = <48>;
+			msi-parent = <&msi>;
+			status = "disabled";
+		};
+
 		clint_mswi: interrupt-controller@7094000000 {
 			compatible = "sophgo,sg2042-aclint-mswi", "thead,c900-aclint-mswi";
 			reg = <0x00000070 0x94000000 0x00000000 0x00004000>;
Signature · 1 line
2.34.1
author
#16 lore raw

PATCH 5/5 riscv: sophgo: dts: enable pcie for PioneerBox

In reply to Chen Wang

From: Chen Wang <[email protected]>

Enable pcie controllers for PioneerBox, which uses SG2042 SoC.

---
 arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts | 12 ++++++++++++
 1 file changed, 12 insertions(+)
arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts +12 -0
index ef3a602172b1..6574d8e0b369 100644
@@ -128,6 +128,18 @@ uart0-rx-pins {
 	};
 };
 
+&pcie_rc0 {
+	status = "okay";
+};
+
+&pcie_rc1 {
+	status = "okay";
+};
+
+&pcie_rc2 {
+	status = "okay";
+};
+
 &sd {
 	pinctrl-0 = <&sd_cfg>;
 	pinctrl-names = "default";
Signature · 1 line
2.34.1