Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'pci/controller/sophgo'

- Check for existence of struct cdns_pcie.ops before using it to allow
Cadence drivers that don't need to supply ops (Chen Wang)

- Add DT binding and driver for the Sophgo SG2042 PCIe controller (Chen
Wang)

* pci/controller/sophgo:
PCI: sg2042: Add Sophgo SG2042 PCIe driver
PCI: cadence: Check for the existence of cdns_pcie::ops before using it
dt-bindings: pci: Add Sophgo SG2042 PCIe host

+215 -6
+64
Documentation/devicetree/bindings/pci/sophgo,sg2042-pcie-host.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/pci/sophgo,sg2042-pcie-host.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Sophgo SG2042 PCIe Host (Cadence PCIe Wrapper) 8 + 9 + description: 10 + Sophgo SG2042 PCIe host controller is based on the Cadence PCIe core. 11 + 12 + maintainers: 13 + - Chen Wang <unicorn_wang@outlook.com> 14 + 15 + properties: 16 + compatible: 17 + const: sophgo,sg2042-pcie-host 18 + 19 + reg: 20 + maxItems: 2 21 + 22 + reg-names: 23 + items: 24 + - const: reg 25 + - const: cfg 26 + 27 + vendor-id: 28 + const: 0x1f1c 29 + 30 + device-id: 31 + const: 0x2042 32 + 33 + msi-parent: true 34 + 35 + allOf: 36 + - $ref: cdns-pcie-host.yaml# 37 + 38 + required: 39 + - compatible 40 + - reg 41 + - reg-names 42 + 43 + unevaluatedProperties: false 44 + 45 + examples: 46 + - | 47 + #include <dt-bindings/interrupt-controller/irq.h> 48 + 49 + pcie@62000000 { 50 + compatible = "sophgo,sg2042-pcie-host"; 51 + device_type = "pci"; 52 + reg = <0x62000000 0x00800000>, 53 + <0x48000000 0x00001000>; 54 + reg-names = "reg", "cfg"; 55 + #address-cells = <3>; 56 + #size-cells = <2>; 57 + ranges = <0x81000000 0 0x00000000 0xde000000 0 0x00010000>, 58 + <0x82000000 0 0xd0400000 0xd0400000 0 0x0d000000>; 59 + bus-range = <0x00 0xff>; 60 + vendor-id = <0x1f1c>; 61 + device-id = <0x2042>; 62 + cdns,no-bar-match-nbits = <48>; 63 + msi-parent = <&msi>; 64 + };
+10
drivers/pci/controller/cadence/Kconfig
··· 42 42 endpoint mode. This PCIe controller may be embedded into many 43 43 different vendors SoCs. 44 44 45 + config PCIE_SG2042_HOST 46 + tristate "Sophgo SG2042 PCIe controller (host mode)" 47 + depends on OF && (ARCH_SOPHGO || COMPILE_TEST) 48 + select PCIE_CADENCE_HOST 49 + help 50 + Say Y here if you want to support the Sophgo SG2042 PCIe platform 51 + controller in host mode. Sophgo SG2042 PCIe controller uses Cadence 52 + PCIe core. 53 + 45 54 config PCI_J721E 46 55 tristate 47 56 select PCIE_CADENCE_HOST if PCI_J721E_HOST != n ··· 76 67 Say Y here if you want to support the TI J721E PCIe platform 77 68 controller in endpoint mode. TI J721E PCIe controller uses Cadence PCIe 78 69 core. 70 + 79 71 endmenu
+1
drivers/pci/controller/cadence/Makefile
··· 4 4 obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep.o 5 5 obj-$(CONFIG_PCIE_CADENCE_PLAT) += pcie-cadence-plat.o 6 6 obj-$(CONFIG_PCI_J721E) += pci-j721e.o 7 + obj-$(CONFIG_PCIE_SG2042_HOST) += pcie-sg2042.o
+1 -1
drivers/pci/controller/cadence/pcie-cadence-host.c
··· 531 531 cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_PCI_ADDR1(0), addr1); 532 532 cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_DESC1(0), desc1); 533 533 534 - if (pcie->ops->cpu_addr_fixup) 534 + if (pcie->ops && pcie->ops->cpu_addr_fixup) 535 535 cpu_addr = pcie->ops->cpu_addr_fixup(pcie, cpu_addr); 536 536 537 537 addr0 = CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS(12) |
+2 -2
drivers/pci/controller/cadence/pcie-cadence.c
··· 106 106 cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_DESC1(r), desc1); 107 107 108 108 /* Set the CPU address */ 109 - if (pcie->ops->cpu_addr_fixup) 109 + if (pcie->ops && pcie->ops->cpu_addr_fixup) 110 110 cpu_addr = pcie->ops->cpu_addr_fixup(pcie, cpu_addr); 111 111 112 112 addr0 = CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS(nbits) | ··· 137 137 } 138 138 139 139 /* Set the CPU address */ 140 - if (pcie->ops->cpu_addr_fixup) 140 + if (pcie->ops && pcie->ops->cpu_addr_fixup) 141 141 cpu_addr = pcie->ops->cpu_addr_fixup(pcie, cpu_addr); 142 142 143 143 addr0 = CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS(17) |
+3 -3
drivers/pci/controller/cadence/pcie-cadence.h
··· 494 494 495 495 static inline int cdns_pcie_start_link(struct cdns_pcie *pcie) 496 496 { 497 - if (pcie->ops->start_link) 497 + if (pcie->ops && pcie->ops->start_link) 498 498 return pcie->ops->start_link(pcie); 499 499 500 500 return 0; ··· 502 502 503 503 static inline void cdns_pcie_stop_link(struct cdns_pcie *pcie) 504 504 { 505 - if (pcie->ops->stop_link) 505 + if (pcie->ops && pcie->ops->stop_link) 506 506 pcie->ops->stop_link(pcie); 507 507 } 508 508 509 509 static inline bool cdns_pcie_link_up(struct cdns_pcie *pcie) 510 510 { 511 - if (pcie->ops->link_up) 511 + if (pcie->ops && pcie->ops->link_up) 512 512 return pcie->ops->link_up(pcie); 513 513 514 514 return true;
+134
drivers/pci/controller/cadence/pcie-sg2042.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * pcie-sg2042 - PCIe controller driver for Sophgo SG2042 SoC 4 + * 5 + * Copyright (C) 2025 Sophgo Technology Inc. 6 + * Copyright (C) 2025 Chen Wang <unicorn_wang@outlook.com> 7 + */ 8 + 9 + #include <linux/mod_devicetable.h> 10 + #include <linux/pci.h> 11 + #include <linux/platform_device.h> 12 + #include <linux/pm_runtime.h> 13 + 14 + #include "pcie-cadence.h" 15 + 16 + /* 17 + * SG2042 only supports 4-byte aligned access, so for the rootbus (i.e. to 18 + * read/write the Root Port itself, read32/write32 is required. For 19 + * non-rootbus (i.e. to read/write the PCIe peripheral registers, supports 20 + * 1/2/4 byte aligned access, so directly using read/write should be fine. 21 + */ 22 + 23 + static struct pci_ops sg2042_pcie_root_ops = { 24 + .map_bus = cdns_pci_map_bus, 25 + .read = pci_generic_config_read32, 26 + .write = pci_generic_config_write32, 27 + }; 28 + 29 + static struct pci_ops sg2042_pcie_child_ops = { 30 + .map_bus = cdns_pci_map_bus, 31 + .read = pci_generic_config_read, 32 + .write = pci_generic_config_write, 33 + }; 34 + 35 + static int sg2042_pcie_probe(struct platform_device *pdev) 36 + { 37 + struct device *dev = &pdev->dev; 38 + struct pci_host_bridge *bridge; 39 + struct cdns_pcie *pcie; 40 + struct cdns_pcie_rc *rc; 41 + int ret; 42 + 43 + bridge = devm_pci_alloc_host_bridge(dev, sizeof(*rc)); 44 + if (!bridge) 45 + return dev_err_probe(dev, -ENOMEM, "Failed to alloc host bridge!\n"); 46 + 47 + bridge->ops = &sg2042_pcie_root_ops; 48 + bridge->child_ops = &sg2042_pcie_child_ops; 49 + 50 + rc = pci_host_bridge_priv(bridge); 51 + pcie = &rc->pcie; 52 + pcie->dev = dev; 53 + 54 + platform_set_drvdata(pdev, pcie); 55 + 56 + pm_runtime_set_active(dev); 57 + pm_runtime_no_callbacks(dev); 58 + devm_pm_runtime_enable(dev); 59 + 60 + ret = cdns_pcie_init_phy(dev, pcie); 61 + if (ret) 62 + return dev_err_probe(dev, ret, "Failed to init phy!\n"); 63 + 64 + ret = cdns_pcie_host_setup(rc); 65 + if (ret) { 66 + dev_err_probe(dev, ret, "Failed to setup host!\n"); 67 + cdns_pcie_disable_phy(pcie); 68 + return ret; 69 + } 70 + 71 + return 0; 72 + } 73 + 74 + static void sg2042_pcie_remove(struct platform_device *pdev) 75 + { 76 + struct cdns_pcie *pcie = platform_get_drvdata(pdev); 77 + struct device *dev = &pdev->dev; 78 + struct cdns_pcie_rc *rc; 79 + 80 + rc = container_of(pcie, struct cdns_pcie_rc, pcie); 81 + cdns_pcie_host_disable(rc); 82 + 83 + cdns_pcie_disable_phy(pcie); 84 + 85 + pm_runtime_disable(dev); 86 + } 87 + 88 + static int sg2042_pcie_suspend_noirq(struct device *dev) 89 + { 90 + struct cdns_pcie *pcie = dev_get_drvdata(dev); 91 + 92 + cdns_pcie_disable_phy(pcie); 93 + 94 + return 0; 95 + } 96 + 97 + static int sg2042_pcie_resume_noirq(struct device *dev) 98 + { 99 + struct cdns_pcie *pcie = dev_get_drvdata(dev); 100 + int ret; 101 + 102 + ret = cdns_pcie_enable_phy(pcie); 103 + if (ret) { 104 + dev_err(dev, "failed to enable PHY\n"); 105 + return ret; 106 + } 107 + 108 + return 0; 109 + } 110 + 111 + static DEFINE_NOIRQ_DEV_PM_OPS(sg2042_pcie_pm_ops, 112 + sg2042_pcie_suspend_noirq, 113 + sg2042_pcie_resume_noirq); 114 + 115 + static const struct of_device_id sg2042_pcie_of_match[] = { 116 + { .compatible = "sophgo,sg2042-pcie-host" }, 117 + {}, 118 + }; 119 + MODULE_DEVICE_TABLE(of, sg2042_pcie_of_match); 120 + 121 + static struct platform_driver sg2042_pcie_driver = { 122 + .driver = { 123 + .name = "sg2042-pcie", 124 + .of_match_table = sg2042_pcie_of_match, 125 + .pm = pm_sleep_ptr(&sg2042_pcie_pm_ops), 126 + }, 127 + .probe = sg2042_pcie_probe, 128 + .remove = sg2042_pcie_remove, 129 + }; 130 + module_platform_driver(sg2042_pcie_driver); 131 + 132 + MODULE_LICENSE("GPL"); 133 + MODULE_DESCRIPTION("PCIe controller driver for SG2042 SoCs"); 134 + MODULE_AUTHOR("Chen Wang <unicorn_wang@outlook.com>");