From 31fc0978c540c1efae230a405308697e2eeeb698 Mon Sep 17 00:00:00 2001 From: Han Gao Date: Mon, 1 Sep 2025 13:10:06 +0800 Subject: [PATCH 01/13] Revert "AOSCOS: PCI: sg2042: fix dependency for PCIE_SG2042" This reverts commit f2b1a963167357e399989415fd1c8ce635d62437. --- drivers/pci/controller/cadence/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/controller/cadence/Kconfig b/drivers/pci/controller/cadence/Kconfig index dab54411beb282..e322894b52b026 100644 --- a/drivers/pci/controller/cadence/Kconfig +++ b/drivers/pci/controller/cadence/Kconfig @@ -46,8 +46,8 @@ config PCIE_SG2042 bool "Sophgo SG2042 PCIe controller (host mode)" depends on ARCH_SOPHGO || COMPILE_TEST depends on OF - depends on PCI_MSI select IRQ_MSI_LIB + select PCI_MSI select PCIE_CADENCE_HOST help Say Y here if you want to support the Sophgo SG2042 PCIe platform From 466f1b381cf28548381252310f8a81c15fda2de9 Mon Sep 17 00:00:00 2001 From: Han Gao Date: Mon, 1 Sep 2025 13:10:09 +0800 Subject: [PATCH 02/13] Revert "FROMLIST: riscv: sophgo: dts: enable pcie for PioneerBox" This reverts commit 6a1113b934dff6ad04a826be5ebff95c12bbbd86. --- arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts b/arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts index 2f8333ad7c9691..554ec14d58453a 100644 --- a/arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts +++ b/arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts @@ -128,18 +128,6 @@ }; }; -&pcie_rc0 { - status = "okay"; -}; - -&pcie_rc1 { - status = "okay"; -}; - -&pcie_rc2 { - status = "okay"; -}; - &sd { pinctrl-0 = <&sd_cfg>; pinctrl-names = "default"; From a38162429477270edaaaf5ad4c245f648da6571f Mon Sep 17 00:00:00 2001 From: Han Gao Date: Mon, 1 Sep 2025 13:10:11 +0800 Subject: [PATCH 03/13] Revert "FROMLIST: riscv: sophgo: dts: add pcie controllers for SG2042" This reverts commit 423379bb5144256925c0db1cf61c0754e5edbb27. --- arch/riscv/boot/dts/sophgo/sg2042.dtsi | 89 -------------------------- 1 file changed, 89 deletions(-) diff --git a/arch/riscv/boot/dts/sophgo/sg2042.dtsi b/arch/riscv/boot/dts/sophgo/sg2042.dtsi index b8691ca3e0e6a7..0f7d8a3743c350 100644 --- a/arch/riscv/boot/dts/sophgo/sg2042.dtsi +++ b/arch/riscv/boot/dts/sophgo/sg2042.dtsi @@ -244,95 +244,6 @@ #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>; - sophgo,link-id = <0>; - sophgo,syscon-pcie-ctrl = <&cdns_pcie0_ctrl>; - msi-parent = <&msi>; - status = "disabled"; - }; - - cdns_pcie0_ctrl: syscon@7061800000 { - compatible = "sophgo,sg2042-pcie-ctrl", "syscon"; - reg = <0x70 0x61800000 0x0 0x800000>; - }; - - 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>; - sophgo,link-id = <0>; - sophgo,syscon-pcie-ctrl = <&cdns_pcie1_ctrl>; - msi-parent = <&msi_pcie>; - status = "disabled"; - msi_pcie: msi { - compatible = "sophgo,sg2042-pcie-msi"; - msi-controller; - interrupt-parent = <&intc>; - interrupts = <123 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "msi"; - }; - }; - - 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>; - sophgo,link-id = <1>; - sophgo,syscon-pcie-ctrl = <&cdns_pcie1_ctrl>; - msi-parent = <&msi>; - status = "disabled"; - }; - - cdns_pcie1_ctrl: syscon@7063800000 { - compatible = "sophgo,sg2042-pcie-ctrl", "syscon"; - reg = <0x70 0x63800000 0x0 0x800000>; - }; - clint_mswi: interrupt-controller@7094000000 { compatible = "sophgo,sg2042-aclint-mswi", "thead,c900-aclint-mswi"; reg = <0x00000070 0x94000000 0x00000000 0x00004000>; From 9f20b6496d1c88829f45bb1768a1d0352d38f178 Mon Sep 17 00:00:00 2001 From: Han Gao Date: Mon, 1 Sep 2025 13:10:13 +0800 Subject: [PATCH 04/13] Revert "FROMLIST: dt-bindings: mfd: syscon: Add sg2042 pcie ctrl compatible" This reverts commit 4f3fe6aca90a3ea61eebabe27c91e2a0b71caf2f. --- Documentation/devicetree/bindings/mfd/syscon.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/Documentation/devicetree/bindings/mfd/syscon.yaml b/Documentation/devicetree/bindings/mfd/syscon.yaml index be73c5bbb8e985..27672adeb1fedb 100644 --- a/Documentation/devicetree/bindings/mfd/syscon.yaml +++ b/Documentation/devicetree/bindings/mfd/syscon.yaml @@ -115,7 +115,6 @@ select: - rockchip,rk3576-qos - rockchip,rk3588-qos - rockchip,rv1126-qos - - sophgo,sg2042-pcie-ctrl - st,spear1340-misc - stericsson,nomadik-pmu - starfive,jh7100-sysmain @@ -223,7 +222,6 @@ properties: - rockchip,rk3576-qos - rockchip,rk3588-qos - rockchip,rv1126-qos - - sophgo,sg2042-pcie-ctrl - st,spear1340-misc - stericsson,nomadik-pmu - starfive,jh7100-sysmain From 12fc66384969667009d83c7123ac542b8cf16a47 Mon Sep 17 00:00:00 2001 From: Han Gao Date: Mon, 1 Sep 2025 13:10:14 +0800 Subject: [PATCH 05/13] Revert "FROMLIST: PCI: sg2042: Add Sophgo SG2042 PCIe driver" This reverts commit 2df4d58947d91a8ae3bbcfe28c0a2587df5b7be9. --- drivers/pci/controller/cadence/Kconfig | 13 - drivers/pci/controller/cadence/Makefile | 1 - drivers/pci/controller/cadence/pcie-sg2042.c | 528 ------------------- 3 files changed, 542 deletions(-) delete mode 100644 drivers/pci/controller/cadence/pcie-sg2042.c diff --git a/drivers/pci/controller/cadence/Kconfig b/drivers/pci/controller/cadence/Kconfig index e322894b52b026..666e16b6367f14 100644 --- a/drivers/pci/controller/cadence/Kconfig +++ b/drivers/pci/controller/cadence/Kconfig @@ -42,18 +42,6 @@ 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 - select IRQ_MSI_LIB - select 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 @@ -79,5 +67,4 @@ 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 diff --git a/drivers/pci/controller/cadence/Makefile b/drivers/pci/controller/cadence/Makefile index 4df4456d953942..9bac5fb2f13dad 100644 --- a/drivers/pci/controller/cadence/Makefile +++ b/drivers/pci/controller/cadence/Makefile @@ -4,4 +4,3 @@ 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 diff --git a/drivers/pci/controller/cadence/pcie-sg2042.c b/drivers/pci/controller/cadence/pcie-sg2042.c deleted file mode 100644 index 0978e1c238282d..00000000000000 --- a/drivers/pci/controller/cadence/pcie-sg2042.c +++ /dev/null @@ -1,528 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * pcie-sg2042 - PCIe controller driver for Sophgo SG2042 SoC - * - * Copyright (C) 2024 Sophgo Technology Inc. - * Copyright (C) 2024 Chen Wang - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "pcie-cadence.h" - -/* - * SG2042 PCIe controller supports two ways to report MSI: - * - * - Method A, the PCIe controller implements an MSI interrupt controller - * inside, and connect to PLIC upward through one interrupt line. - * Provides memory-mapped MSI address, and by programming the upper 32 - * bits of the address to zero, it can be compatible with old PCIe devices - * that only support 32-bit MSI address. - * - * - Method B, the PCIe controller connects to PLIC upward through an - * independent MSI controller "sophgo,sg2042-msi" on the SOC. The MSI - * controller provides multiple(up to 32) interrupt sources to PLIC. - * Compared with the first method, the advantage is that the interrupt - * source is expanded, but because for SG2042, the MSI address provided by - * the MSI controller is fixed and only supports 64-bit address(> 2^32), - * it is not compatible with old PCIe devices that only support 32-bit MSI - * address. - * - * Method A & B can be configured in DTS, default is Method B. - */ - -#define MAX_MSI_IRQS 8 -#define MAX_MSI_IRQS_PER_CTRL 1 -#define MAX_MSI_CTRLS (MAX_MSI_IRQS / MAX_MSI_IRQS_PER_CTRL) -#define MSI_DEF_NUM_VECTORS MAX_MSI_IRQS -#define BYTE_NUM_PER_MSI_VEC 4 - -#define REG_CLEAR 0x0804 -#define REG_STATUS 0x0810 -#define REG_LINK0_MSI_ADDR_SIZE 0x085C -#define REG_LINK1_MSI_ADDR_SIZE 0x080C -#define REG_LINK0_MSI_ADDR_LOW 0x0860 -#define REG_LINK0_MSI_ADDR_HIGH 0x0864 -#define REG_LINK1_MSI_ADDR_LOW 0x0868 -#define REG_LINK1_MSI_ADDR_HIGH 0x086C - -#define REG_CLEAR_LINK0_BIT 2 -#define REG_CLEAR_LINK1_BIT 3 -#define REG_STATUS_LINK0_BIT 2 -#define REG_STATUS_LINK1_BIT 3 - -#define REG_LINK0_MSI_ADDR_SIZE_MASK GENMASK(15, 0) -#define REG_LINK1_MSI_ADDR_SIZE_MASK GENMASK(31, 16) - -struct sg2042_pcie { - struct cdns_pcie *cdns_pcie; - - struct regmap *syscon; - - u32 link_id; - - struct irq_domain *msi_domain; - - int msi_irq; - - dma_addr_t msi_phys; - void *msi_virt; - - u32 num_applied_vecs; /* used to speed up ISR */ - - raw_spinlock_t msi_lock; - DECLARE_BITMAP(msi_irq_in_use, MAX_MSI_IRQS); -}; - -static void sg2042_pcie_msi_clear_status(struct sg2042_pcie *pcie) -{ - u32 status, clr_msi_in_bit; - - if (pcie->link_id == 1) - clr_msi_in_bit = BIT(REG_CLEAR_LINK1_BIT); - else - clr_msi_in_bit = BIT(REG_CLEAR_LINK0_BIT); - - regmap_read(pcie->syscon, REG_CLEAR, &status); - status |= clr_msi_in_bit; - regmap_write(pcie->syscon, REG_CLEAR, status); - - /* need write 0 to reset, hardware can not reset automatically */ - status &= ~clr_msi_in_bit; - regmap_write(pcie->syscon, REG_CLEAR, status); -} - -static int sg2042_pcie_msi_irq_set_affinity(struct irq_data *d, - const struct cpumask *mask, - bool force) -{ - if (d->parent_data) - return irq_chip_set_affinity_parent(d, mask, force); - - return -EINVAL; -} - -static void sg2042_pcie_msi_irq_compose_msi_msg(struct irq_data *d, - struct msi_msg *msg) -{ - struct sg2042_pcie *pcie = irq_data_get_irq_chip_data(d); - struct device *dev = pcie->cdns_pcie->dev; - - msg->address_lo = lower_32_bits(pcie->msi_phys) + BYTE_NUM_PER_MSI_VEC * d->hwirq; - msg->address_hi = upper_32_bits(pcie->msi_phys); - msg->data = 1; - - if (d->hwirq > pcie->num_applied_vecs) - pcie->num_applied_vecs = d->hwirq; - - dev_dbg(dev, "compose MSI msg hwirq[%ld] address_hi[%#x] address_lo[%#x]\n", - d->hwirq, msg->address_hi, msg->address_lo); -} - -static void sg2042_pcie_msi_irq_ack(struct irq_data *d) -{ - struct sg2042_pcie *pcie = irq_data_get_irq_chip_data(d); - - sg2042_pcie_msi_clear_status(pcie); -} - -static struct irq_chip sg2042_pcie_msi_bottom_chip = { - .name = "SG2042 PCIe PLIC-MSI translator", - .irq_ack = sg2042_pcie_msi_irq_ack, - .irq_compose_msi_msg = sg2042_pcie_msi_irq_compose_msi_msg, - .irq_set_affinity = sg2042_pcie_msi_irq_set_affinity, -}; - -static int sg2042_pcie_irq_domain_alloc(struct irq_domain *domain, - unsigned int virq, unsigned int nr_irqs, - void *args) -{ - struct sg2042_pcie *pcie = domain->host_data; - unsigned long flags; - u32 i; - int bit; - - raw_spin_lock_irqsave(&pcie->msi_lock, flags); - - bit = bitmap_find_free_region(pcie->msi_irq_in_use, MSI_DEF_NUM_VECTORS, - order_base_2(nr_irqs)); - - raw_spin_unlock_irqrestore(&pcie->msi_lock, flags); - - if (bit < 0) - return -ENOSPC; - - for (i = 0; i < nr_irqs; i++) - irq_domain_set_info(domain, virq + i, bit + i, - &sg2042_pcie_msi_bottom_chip, - pcie, handle_edge_irq, - NULL, NULL); - - return 0; -} - -static void sg2042_pcie_irq_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 sg2042_pcie *pcie = irq_data_get_irq_chip_data(d); - unsigned long flags; - - raw_spin_lock_irqsave(&pcie->msi_lock, flags); - - bitmap_release_region(pcie->msi_irq_in_use, d->hwirq, - order_base_2(nr_irqs)); - - raw_spin_unlock_irqrestore(&pcie->msi_lock, flags); -} - -static const struct irq_domain_ops sg2042_pcie_msi_domain_ops = { - .alloc = sg2042_pcie_irq_domain_alloc, - .free = sg2042_pcie_irq_domain_free, -}; - -static int sg2042_pcie_init_msi_data(struct sg2042_pcie *pcie) -{ - struct device *dev = pcie->cdns_pcie->dev; - u32 value; - int ret; - - raw_spin_lock_init(&pcie->msi_lock); - - /* - * Though the PCIe controller can address >32-bit address space, to - * facilitate endpoints that support only 32-bit MSI target address, - * the mask is set to 32-bit to make sure that MSI target address is - * always a 32-bit address - */ - ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); - if (ret < 0) - return ret; - - pcie->msi_virt = dma_alloc_coherent(dev, BYTE_NUM_PER_MSI_VEC * MAX_MSI_IRQS, - &pcie->msi_phys, GFP_KERNEL); - if (!pcie->msi_virt) - return -ENOMEM; - - /* Program the MSI address and size */ - if (pcie->link_id == 1) { - regmap_write(pcie->syscon, REG_LINK1_MSI_ADDR_LOW, - lower_32_bits(pcie->msi_phys)); - regmap_write(pcie->syscon, REG_LINK1_MSI_ADDR_HIGH, - upper_32_bits(pcie->msi_phys)); - - regmap_read(pcie->syscon, REG_LINK1_MSI_ADDR_SIZE, &value); - value = (value & REG_LINK1_MSI_ADDR_SIZE_MASK) | MAX_MSI_IRQS; - regmap_write(pcie->syscon, REG_LINK1_MSI_ADDR_SIZE, value); - } else { - regmap_write(pcie->syscon, REG_LINK0_MSI_ADDR_LOW, - lower_32_bits(pcie->msi_phys)); - regmap_write(pcie->syscon, REG_LINK0_MSI_ADDR_HIGH, - upper_32_bits(pcie->msi_phys)); - - regmap_read(pcie->syscon, REG_LINK0_MSI_ADDR_SIZE, &value); - value = (value & REG_LINK0_MSI_ADDR_SIZE_MASK) | (MAX_MSI_IRQS << 16); - regmap_write(pcie->syscon, REG_LINK0_MSI_ADDR_SIZE, value); - } - - return 0; -} - -static irqreturn_t sg2042_pcie_msi_handle_irq(struct sg2042_pcie *pcie) -{ - u32 i, pos; - unsigned long val; - u32 status, num_vectors; - irqreturn_t ret = IRQ_NONE; - - num_vectors = pcie->num_applied_vecs; - for (i = 0; i <= num_vectors; i++) { - status = readl((void *)(pcie->msi_virt + i * BYTE_NUM_PER_MSI_VEC)); - if (!status) - continue; - - ret = IRQ_HANDLED; - val = status; - pos = 0; - while ((pos = find_next_bit(&val, MAX_MSI_IRQS_PER_CTRL, - pos)) != MAX_MSI_IRQS_PER_CTRL) { - generic_handle_domain_irq(pcie->msi_domain, - (i * MAX_MSI_IRQS_PER_CTRL) + - pos); - pos++; - } - writel(0, ((void *)(pcie->msi_virt) + i * BYTE_NUM_PER_MSI_VEC)); - } - return ret; -} - -static void sg2042_pcie_msi_chained_isr(struct irq_desc *desc) -{ - struct irq_chip *chip = irq_desc_get_chip(desc); - u32 status, st_msi_in_bit; - struct sg2042_pcie *pcie; - - chained_irq_enter(chip, desc); - - pcie = irq_desc_get_handler_data(desc); - if (pcie->link_id == 1) - st_msi_in_bit = REG_STATUS_LINK1_BIT; - else - st_msi_in_bit = REG_STATUS_LINK0_BIT; - - regmap_read(pcie->syscon, REG_STATUS, &status); - if ((status >> st_msi_in_bit) & 0x1) { - sg2042_pcie_msi_clear_status(pcie); - - sg2042_pcie_msi_handle_irq(pcie); - } - - chained_irq_exit(chip, desc); -} - -#define SG2042_PCIE_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \ - MSI_FLAG_USE_DEF_CHIP_OPS) - -#define SG2042_PCIE_MSI_FLAGS_SUPPORTED MSI_GENERIC_FLAGS_MASK - -static struct msi_parent_ops sg2042_pcie_msi_parent_ops = { - .required_flags = SG2042_PCIE_MSI_FLAGS_REQUIRED, - .supported_flags = SG2042_PCIE_MSI_FLAGS_SUPPORTED, - .bus_select_mask = MATCH_PCI_MSI, - .bus_select_token = DOMAIN_BUS_NEXUS, - .prefix = "SG2042-", - .init_dev_msi_info = msi_lib_init_dev_msi_info, -}; - -static int sg2042_pcie_setup_msi(struct sg2042_pcie *pcie, - struct device_node *msi_node) -{ - struct device *dev = pcie->cdns_pcie->dev; - struct fwnode_handle *fwnode = of_node_to_fwnode(dev->of_node); - struct irq_domain *parent_domain; - int ret = 0; - - if (!of_property_read_bool(msi_node, "msi-controller")) - return -ENODEV; - - ret = of_irq_get_byname(msi_node, "msi"); - if (ret <= 0) { - dev_err(dev, "%pOF: failed to get MSI irq\n", msi_node); - return ret; - } - pcie->msi_irq = ret; - - irq_set_chained_handler_and_data(pcie->msi_irq, - sg2042_pcie_msi_chained_isr, pcie); - - parent_domain = irq_domain_create_linear(fwnode, MSI_DEF_NUM_VECTORS, - &sg2042_pcie_msi_domain_ops, pcie); - if (!parent_domain) { - dev_err(dev, "%pfw: Failed to create IRQ domain\n", fwnode); - return -ENOMEM; - } - irq_domain_update_bus_token(parent_domain, DOMAIN_BUS_NEXUS); - - parent_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT; - parent_domain->msi_parent_ops = &sg2042_pcie_msi_parent_ops; - - pcie->msi_domain = parent_domain; - - ret = sg2042_pcie_init_msi_data(pcie); - if (ret) { - dev_err(dev, "Failed to initialize MSI data!\n"); - return ret; - } - - return 0; -} - -static void sg2042_pcie_free_msi(struct sg2042_pcie *pcie) -{ - struct device *dev = pcie->cdns_pcie->dev; - - if (pcie->msi_irq) - irq_set_chained_handler_and_data(pcie->msi_irq, NULL, NULL); - - if (pcie->msi_virt) - dma_free_coherent(dev, BYTE_NUM_PER_MSI_VEC * MAX_MSI_IRQS, - pcie->msi_virt, pcie->msi_phys); -} - -/* - * 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, -}; - -/* Dummy ops which will be assigned to cdns_pcie.ops, which must be !NULL. */ -static const struct cdns_pcie_ops sg2042_cdns_pcie_ops = {}; - -static int sg2042_pcie_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct device_node *np = dev->of_node; - struct pci_host_bridge *bridge; - struct device_node *np_syscon; - struct device_node *msi_node; - struct cdns_pcie *cdns_pcie; - struct sg2042_pcie *pcie; - struct cdns_pcie_rc *rc; - struct regmap *syscon; - 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); - cdns_pcie = &rc->pcie; - cdns_pcie->dev = dev; - cdns_pcie->ops = &sg2042_cdns_pcie_ops; - pcie->cdns_pcie = cdns_pcie; - - np_syscon = of_parse_phandle(np, "sophgo,syscon-pcie-ctrl", 0); - if (!np_syscon) { - dev_err(dev, "Failed to get syscon node\n"); - return -ENOMEM; - } - syscon = syscon_node_to_regmap(np_syscon); - if (IS_ERR(syscon)) { - dev_err(dev, "Failed to get regmap for syscon\n"); - return -ENOMEM; - } - pcie->syscon = syscon; - - if (of_property_read_u32(np, "sophgo,link-id", &pcie->link_id)) { - dev_err(dev, "Unable to parse sophgo,link-id\n"); - return -EINVAL; - } - - 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; - } - - msi_node = of_parse_phandle(dev->of_node, "msi-parent", 0); - if (!msi_node) { - dev_err(dev, "Failed to get msi-parent!\n"); - return -1; - } - - if (of_device_is_compatible(msi_node, "sophgo,sg2042-pcie-msi")) { - ret = sg2042_pcie_setup_msi(pcie, msi_node); - if (ret < 0) - goto err_setup_msi; - } - - ret = cdns_pcie_init_phy(dev, cdns_pcie); - if (ret) { - dev_err(dev, "Failed to init phy!\n"); - goto err_setup_msi; - } - - 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(cdns_pcie); - -err_setup_msi: - sg2042_pcie_free_msi(pcie); - -err_get_sync: - pm_runtime_put(dev); - pm_runtime_disable(dev); - - return ret; -} - -static void sg2042_pcie_shutdown(struct platform_device *pdev) -{ - struct sg2042_pcie *pcie = platform_get_drvdata(pdev); - struct cdns_pcie *cdns_pcie = pcie->cdns_pcie; - struct device *dev = &pdev->dev; - - sg2042_pcie_free_msi(pcie); - - cdns_pcie_disable_phy(cdns_pcie); - - pm_runtime_put(dev); - pm_runtime_disable(dev); -} - -static const struct of_device_id sg2042_pcie_of_match[] = { - { .compatible = "sophgo,sg2042-pcie-host" }, - {}, -}; - -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); From 39b99d4f0d94c8ca17beb22c421652393041ebb2 Mon Sep 17 00:00:00 2001 From: Han Gao Date: Mon, 1 Sep 2025 13:10:16 +0800 Subject: [PATCH 06/13] Revert "FROMLIST: dt-bindings: pci: Add Sophgo SG2042 PCIe host" This reverts commit 18ea5520afd6dbd3040ca70e2af7699c611ca157. --- .../bindings/pci/sophgo,sg2042-pcie-host.yaml | 147 ------------------ 1 file changed, 147 deletions(-) delete mode 100644 Documentation/devicetree/bindings/pci/sophgo,sg2042-pcie-host.yaml diff --git a/Documentation/devicetree/bindings/pci/sophgo,sg2042-pcie-host.yaml b/Documentation/devicetree/bindings/pci/sophgo,sg2042-pcie-host.yaml deleted file mode 100644 index f98e7182214428..00000000000000 --- a/Documentation/devicetree/bindings/pci/sophgo,sg2042-pcie-host.yaml +++ /dev/null @@ -1,147 +0,0 @@ -# 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 - -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: - type: object - $ref: /schemas/interrupt-controller/msi-controller.yaml# - unevaluatedProperties: false - - properties: - compatible: - items: - - const: sophgo,sg2042-pcie-msi - - interrupts: - maxItems: 1 - - interrupt-names: - const: msi - - msi-parent: true - - sophgo,link-id: - $ref: /schemas/types.yaml#/definitions/uint32 - description: | - SG2042 uses Cadence IP, every IP is composed of 2 cores (called link0 - & link1 as Cadence's term). Each core corresponds to a host bridge, - and each host bridge has only one root port. Their configuration - registers are completely independent. SG2042 integrates two Cadence IPs, - so there can actually be up to four host bridges. "sophgo,link-id" is - used to identify which core/link the PCIe host bridge node corresponds to. - - The Cadence IP has two modes of operation, selected by a strap pin. - - In the single-link mode, the Cadence PCIe core instance associated - with Link0 is connected to all the lanes and the Cadence PCIe core - instance associated with Link1 is inactive. - - In the dual-link mode, the Cadence PCIe core instance associated - with Link0 is connected to the lower half of the lanes and the - Cadence PCIe core instance associated with Link1 is connected to - the upper half of the lanes. - - SG2042 contains 2 Cadence IPs and configures the Cores as below: - - +-- Core (Link0) <---> pcie_rc0 +-----------------+ - | | | - Cadence IP 1 --+ | cdns_pcie0_ctrl | - | | | - +-- Core (Link1) <---> disabled +-----------------+ - - +-- Core (Link0) <---> pcie_rc1 +-----------------+ - | | | - Cadence IP 2 --+ | cdns_pcie1_ctrl | - | | | - +-- Core (Link1) <---> pcie_rc2 +-----------------+ - - pcie_rcX is PCIe node ("sophgo,sg2042-pcie-host") defined in DTS. - - Sophgo defines some new register files to add support for their MSI - controller inside PCIe. These new register files are defined in DTS as - syscon node ("sophgo,sg2042-pcie-ctrl"), i.e. "cdns_pcie0_ctrl" / - "cdns_pcie1_ctrl". cdns_pcieX_ctrl contains some registers shared by - pcie_rcX, even two RC (Link)s may share different bits of the same - register. For example, cdns_pcie1_ctrl contains registers shared by - link0 & link1 for Cadence IP 2. - - "sophgo,link-id" is defined to distinguish the two RC's in one Cadence IP, - so we can know what registers (bits) we should use. - - sophgo,syscon-pcie-ctrl: - $ref: /schemas/types.yaml#/definitions/phandle - description: - Phandle to the PCIe System Controller DT node. It's required to - access some MSI operation registers shared by PCIe RCs. - -allOf: - - $ref: cdns-pcie-host.yaml# - -required: - - compatible - - reg - - reg-names - - vendor-id - - device-id - - sophgo,link-id - - sophgo,syscon-pcie-ctrl - -unevaluatedProperties: false - -examples: - - | - #include - - 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>; - sophgo,link-id = <0>; - sophgo,syscon-pcie-ctrl = <&cdns_pcie1_ctrl>; - msi-parent = <&msi_pcie>; - msi_pcie: msi { - compatible = "sophgo,sg2042-pcie-msi"; - msi-controller; - interrupt-parent = <&intc>; - interrupts = <123 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "msi"; - }; - }; From 07fa150657d8b4d8d798ebd1f9b32b4e1ba863e7 Mon Sep 17 00:00:00 2001 From: Chen Wang Date: Thu, 28 Aug 2025 10:16:54 +0800 Subject: [PATCH 07/13] FROMLIST: dt-bindings: pci: Add Sophgo SG2042 PCIe host Add binding for Sophgo SG2042 PCIe host controller. Signed-off-by: Chen Wang Reviewed-by: Rob Herring (Arm) Link: https://lore.kernel.org/r/c9362bb49e4d48647db85d85c06040de8f38cb83.1756344464.git.unicorn_wang@outlook.com Signed-off-by: Han Gao --- .../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 diff --git a/Documentation/devicetree/bindings/pci/sophgo,sg2042-pcie-host.yaml b/Documentation/devicetree/bindings/pci/sophgo,sg2042-pcie-host.yaml new file mode 100644 index 00000000000000..2cca3d113d112f --- /dev/null +++ b/Documentation/devicetree/bindings/pci/sophgo,sg2042-pcie-host.yaml @@ -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 + +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 + + 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>; + }; From 9de9b831bd9129304de81202628556077d4dc3cf Mon Sep 17 00:00:00 2001 From: Chen Wang Date: Thu, 28 Aug 2025 10:17:17 +0800 Subject: [PATCH 08/13] FROMLIST: PCI: cadence: Fix NULL pointer error for ops 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") Signed-off-by: Chen Wang Link: https://lore.kernel.org/r/fca633eb6d667a90f875cdf1263fcea2bcc2c969.1756344464.git.unicorn_wang@outlook.com Signed-off-by: Han Gao --- 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(-) diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c b/drivers/pci/controller/cadence/pcie-cadence-host.c index 59a4631de79fe8..fffd63d6665e81 100644 --- a/drivers/pci/controller/cadence/pcie-cadence-host.c +++ b/drivers/pci/controller/cadence/pcie-cadence-host.c @@ -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) | diff --git a/drivers/pci/controller/cadence/pcie-cadence.c b/drivers/pci/controller/cadence/pcie-cadence.c index 70a19573440ee9..61806bbd8aa326 100644 --- a/drivers/pci/controller/cadence/pcie-cadence.c +++ b/drivers/pci/controller/cadence/pcie-cadence.c @@ -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) | diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h index a149845d341ae4..3b23ab8cf89f7e 100644 --- a/drivers/pci/controller/cadence/pcie-cadence.h +++ b/drivers/pci/controller/cadence/pcie-cadence.h @@ -488,7 +488,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; @@ -496,13 +496,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; From cf810c36b254437891782ab936b78322b5b3fa45 Mon Sep 17 00:00:00 2001 From: Chen Wang Date: Thu, 28 Aug 2025 10:17:40 +0800 Subject: [PATCH 09/13] FROMLIST: PCI: sg2042: Add Sophgo SG2042 PCIe driver 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. Signed-off-by: Chen Wang Link: https://lore.kernel.org/r/1df25b33f0ea90a81c34c18cadedd38526a30f01.1756344464.git.unicorn_wang@outlook.com Signed-off-by: Han Gao --- 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 diff --git a/drivers/pci/controller/cadence/Kconfig b/drivers/pci/controller/cadence/Kconfig index 666e16b6367f14..b1f1941d5208b1 100644 --- a/drivers/pci/controller/cadence/Kconfig +++ b/drivers/pci/controller/cadence/Kconfig @@ -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 diff --git a/drivers/pci/controller/cadence/Makefile b/drivers/pci/controller/cadence/Makefile index 9bac5fb2f13dad..4df4456d953942 100644 --- a/drivers/pci/controller/cadence/Makefile +++ b/drivers/pci/controller/cadence/Makefile @@ -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 diff --git a/drivers/pci/controller/cadence/pcie-sg2042.c b/drivers/pci/controller/cadence/pcie-sg2042.c new file mode 100644 index 00000000000000..fe434dc2967e6c --- /dev/null +++ b/drivers/pci/controller/cadence/pcie-sg2042.c @@ -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 + */ + +#include +#include +#include +#include +#include + +#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; + 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" }, + {}, +}; + +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); From fd82a6e2402bf7004d43aca8e5cd8a7fdc3e98c0 Mon Sep 17 00:00:00 2001 From: Chen Wang Date: Thu, 28 Aug 2025 10:18:00 +0800 Subject: [PATCH 10/13] FROMLIST: riscv: sophgo: dts: add pcie controllers for SG2042 Add PCIe controller nodes in DTS for Sophgo SG2042. Default they are disabled. Signed-off-by: Chen Wang Link: https://lore.kernel.org/r/96df911a622547c6c987895fefde9110f3fcac03.1756344464.git.unicorn_wang@outlook.com Signed-off-by: Han Gao --- arch/riscv/boot/dts/sophgo/sg2042.dtsi | 66 ++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/arch/riscv/boot/dts/sophgo/sg2042.dtsi b/arch/riscv/boot/dts/sophgo/sg2042.dtsi index 0f7d8a3743c350..11ec70dabc316d 100644 --- a/arch/riscv/boot/dts/sophgo/sg2042.dtsi +++ b/arch/riscv/boot/dts/sophgo/sg2042.dtsi @@ -244,6 +244,72 @@ #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>; From 983da91de48f0f8379a299b9a54c29c96b1ea385 Mon Sep 17 00:00:00 2001 From: Chen Wang Date: Thu, 28 Aug 2025 10:18:21 +0800 Subject: [PATCH 11/13] FROMLIST: riscv: sophgo: dts: enable pcie for PioneerBox Enable pcie controllers for PioneerBox, which uses SG2042 SoC. Signed-off-by: Chen Wang Link: https://lore.kernel.org/r/3c2fef69e80a3e4dde47a9449b49f679211a0c2e.1756344464.git.unicorn_wang@outlook.com Signed-off-by: Han Gao --- arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts b/arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts index 554ec14d58453a..2f8333ad7c9691 100644 --- a/arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts +++ b/arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts @@ -128,6 +128,18 @@ }; }; +&pcie_rc0 { + status = "okay"; +}; + +&pcie_rc1 { + status = "okay"; +}; + +&pcie_rc2 { + status = "okay"; +}; + &sd { pinctrl-0 = <&sd_cfg>; pinctrl-names = "default"; From 9171b6146896009e276a995fc9be51f75bf84709 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Sat, 29 Jun 2024 13:22:46 +0800 Subject: [PATCH 12/13] FROMLIST: drm/ttm: save the device's DMA coherency status in ttm_device Currently TTM utilizes cached memory regardless of whether the device have full DMA coherency (can snoop CPU cache). Save the device's DMA coherency status in struct ttm_device, to allow further support of devices w/o snooping capability (the capability missing on at least one part of the transmission between the CPU and the device). Signed-off-by: Icenowy Zheng Link: https://lore.kernel.org/r/20240629052247.2653363-2-uwu@icenowy.me Signed-off-by: Han Gao --- drivers/gpu/drm/ttm/ttm_device.c | 2 ++ include/drm/ttm/ttm_device.h | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/drivers/gpu/drm/ttm/ttm_device.c b/drivers/gpu/drm/ttm/ttm_device.c index 02e797fd1891ac..b777a63c896a12 100644 --- a/drivers/gpu/drm/ttm/ttm_device.c +++ b/drivers/gpu/drm/ttm/ttm_device.c @@ -222,6 +222,8 @@ int ttm_device_init(struct ttm_device *bdev, const struct ttm_device_funcs *func list_add_tail(&bdev->device_list, &glob->device_list); mutex_unlock(&ttm_global_mutex); + bdev->dma_coherent = dev->dma_coherent; + return 0; } EXPORT_SYMBOL(ttm_device_init); diff --git a/include/drm/ttm/ttm_device.h b/include/drm/ttm/ttm_device.h index 07594b72de6366..0f4276f07e6e5f 100644 --- a/include/drm/ttm/ttm_device.h +++ b/include/drm/ttm/ttm_device.h @@ -225,6 +225,11 @@ struct ttm_device { */ const struct ttm_device_funcs *funcs; + /** + * @dma_coherent: if the device backed is dma-coherent. + */ + bool dma_coherent; + /** * @sysman: Resource manager for the system domain. * Access via ttm_manager_type. From 3396d1d2c2d6d564941326ce679ecd7c297bf48f Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Sat, 29 Jun 2024 13:22:47 +0800 Subject: [PATCH 13/13] FROMLIST: drm/ttm: downgrade cached to write_combined when snooping not available As we can now acquire the presence of the full DMA coherency (snooping capability) from ttm_device, we can now map the CPU side memory as write-combined when cached is requested and snooping is not avilable. Signed-off-by: Icenowy Zheng Link: https://lore.kernel.org/r/20240629052247.2653363-3-uwu@icenowy.me Signed-off-by: Han Gao --- drivers/gpu/drm/ttm/ttm_bo_util.c | 4 ++++ drivers/gpu/drm/ttm/ttm_tt.c | 4 ++++ include/drm/ttm/ttm_caching.h | 3 ++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index bd90404ea609ca..ee700175298ca4 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -303,6 +303,10 @@ pgprot_t ttm_io_prot(struct ttm_buffer_object *bo, struct ttm_resource *res, caching = res->bus.caching; } + /* Downgrade cached mapping for non-snooping devices */ + if (!bo->bdev->dma_coherent && caching == ttm_cached) + caching = ttm_write_combined; + return ttm_prot_from_caching(caching, tmp); } EXPORT_SYMBOL(ttm_io_prot); diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index 698cd4bf5e4648..609bdfbd7491d8 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c @@ -153,6 +153,10 @@ static void ttm_tt_init_fields(struct ttm_tt *ttm, enum ttm_caching caching, unsigned long extra_pages) { + /* Downgrade cached mapping for non-snooping devices */ + if (!bo->bdev->dma_coherent && caching == ttm_cached) + caching = ttm_write_combined; + ttm->num_pages = (PAGE_ALIGN(bo->base.size) >> PAGE_SHIFT) + extra_pages; ttm->page_flags = page_flags; ttm->dma_address = NULL; diff --git a/include/drm/ttm/ttm_caching.h b/include/drm/ttm/ttm_caching.h index a18f43e93abab4..f92d7911f50e4d 100644 --- a/include/drm/ttm/ttm_caching.h +++ b/include/drm/ttm/ttm_caching.h @@ -47,7 +47,8 @@ enum ttm_caching { /** * @ttm_cached: Fully cached like normal system memory, requires that - * devices snoop the CPU cache on accesses. + * devices snoop the CPU cache on accesses. Downgraded to + * ttm_write_combined when the snooping capaiblity is missing. */ ttm_cached };