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 tag 'pci-v4.21-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci

Pull PCI updates from Bjorn Helgaas:

- Remove unused lists from ASPM pcie_link_state (Frederick Lawler)

- Fix Broadcom CNB20LE host bridge unintended sign extension (Colin Ian
King)

- Expand Kconfig "PF" acronyms (Randy Dunlap)

- Update MAINTAINERS for arch/x86/kernel/early-quirks.c (Bjorn Helgaas)

- Add missing include to drivers/pci.h (Alexandru Gagniuc)

- Override Synopsys USB 3.x HAPS device class so dwc3-haps can claim it
instead of xhci (Thinh Nguyen)

- Clean up P2PDMA documentation (Randy Dunlap)

- Allow runtime PM even if driver doesn't supply callbacks (Jarkko
Nikula)

- Remove status check after submitting Switchtec MRPC Firmware Download
commands to avoid Completion Timeouts (Kelvin Cao)

- Set Switchtec coherent DMA mask to allow 64-bit DMA (Boris Glimcher)

- Fix Switchtec SWITCHTEC_IOCTL_EVENT_IDX_ALL flag overwrite issue
(Joey Zhang)

- Enable write combining for Switchtec MRPC Input buffers (Kelvin Cao)

- Add Switchtec MRPC DMA mode support (Wesley Sheng)

- Skip VF scanning on powerpc, which does this in firmware (Sebastian
Ott)

- Add Amlogic Meson PCIe controller driver and DT bindings (Yue Wang)

- Constify histb dw_pcie_host_ops structure (Julia Lawall)

- Support multiple power domains for imx6 (Leonard Crestez)

- Constify layerscape driver data (Stefan Agner)

- Update imx6 Kconfig to allow imx6 PCIe in imx7 kernel (Trent Piepho)

- Support armada8k GPIO reset (Baruch Siach)

- Support suspend/resume support on imx6 (Leonard Crestez)

- Don't hard-code DesignWare DBI/ATU offst (Stephen Warren)

- Skip i.MX6 PHY setup on i.MX7D (Andrey Smirnov)

- Remove Jianguo Sun from HiSilicon STB maintainers (Lorenzo Pieralisi)

- Mask DesignWare interrupts instead of disabling them to avoid lost
interrupts (Marc Zyngier)

- Add locking when acking DesignWare interrupts (Marc Zyngier)

- Ack DesignWare interrupts in the proper callbacks (Marc Zyngier)

- Use devm resource parser in mediatek (Honghui Zhang)

- Remove unused mediatek "num-lanes" DT property (Honghui Zhang)

- Add UniPhier PCIe controller driver and DT bindings (Kunihiko
Hayashi)

- Enable MSI for imx6 downstream components (Richard Zhu)

* tag 'pci-v4.21-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (40 commits)
PCI: imx: Enable MSI from downstream components
s390/pci: skip VF scanning
PCI/IOV: Add flag so platforms can skip VF scanning
PCI/IOV: Factor out sriov_add_vfs()
PCI: uniphier: Add UniPhier PCIe host controller support
dt-bindings: PCI: Add UniPhier PCIe host controller description
PCI: amlogic: Add the Amlogic Meson PCIe controller driver
dt-bindings: PCI: meson: add DT bindings for Amlogic Meson PCIe controller
arm64: dts: mt7622: Remove un-used property for PCIe
arm: dts: mt7623: Remove un-used property for PCIe
dt-bindings: PCI: MediaTek: Remove un-used property
PCI: mediatek: Remove un-used variant in struct mtk_pcie_port
MAINTAINERS: Remove Jianguo Sun from HiSilicon STB DWC entry
PCI: dwc: Don't hard-code DBI/ATU offset
PCI: imx: Add imx6sx suspend/resume support
PCI: armada8k: Add support for gpio controlled reset signal
PCI: dwc: Adjust Kconfig to allow IMX6 PCIe host on IMX7
PCI: dwc: layerscape: Constify driver data
PCI: imx: Add multi-pd support
PCI: Override Synopsys USB 3.x HAPS device class
...

+1723 -212
+70
Documentation/devicetree/bindings/pci/amlogic,meson-pcie.txt
··· 1 + Amlogic Meson AXG DWC PCIE SoC controller 2 + 3 + Amlogic Meson PCIe host controller is based on the Synopsys DesignWare PCI core. 4 + It shares common functions with the PCIe DesignWare core driver and 5 + inherits common properties defined in 6 + Documentation/devicetree/bindings/pci/designware-pci.txt. 7 + 8 + Additional properties are described here: 9 + 10 + Required properties: 11 + - compatible: 12 + should contain "amlogic,axg-pcie" to identify the core. 13 + - reg: 14 + should contain the configuration address space. 15 + - reg-names: Must be 16 + - "elbi" External local bus interface registers 17 + - "cfg" Meson specific registers 18 + - "phy" Meson PCIE PHY registers 19 + - "config" PCIe configuration space 20 + - reset-gpios: The GPIO to generate PCIe PERST# assert and deassert signal. 21 + - clocks: Must contain an entry for each entry in clock-names. 22 + - clock-names: Must include the following entries: 23 + - "pclk" PCIe GEN 100M PLL clock 24 + - "port" PCIe_x(A or B) RC clock gate 25 + - "general" PCIe Phy clock 26 + - "mipi" PCIe_x(A or B) 100M ref clock gate 27 + - resets: phandle to the reset lines. 28 + - reset-names: must contain "phy" "port" and "apb" 29 + - "phy" Share PHY reset 30 + - "port" Port A or B reset 31 + - "apb" Share APB reset 32 + - device_type: 33 + should be "pci". As specified in designware-pcie.txt 34 + 35 + 36 + Example configuration: 37 + 38 + pcie: pcie@f9800000 { 39 + compatible = "amlogic,axg-pcie", "snps,dw-pcie"; 40 + reg = <0x0 0xf9800000 0x0 0x400000 41 + 0x0 0xff646000 0x0 0x2000 42 + 0x0 0xff644000 0x0 0x2000 43 + 0x0 0xf9f00000 0x0 0x100000>; 44 + reg-names = "elbi", "cfg", "phy", "config"; 45 + reset-gpios = <&gpio GPIOX_19 GPIO_ACTIVE_HIGH>; 46 + interrupts = <GIC_SPI 177 IRQ_TYPE_EDGE_RISING>; 47 + #interrupt-cells = <1>; 48 + interrupt-map-mask = <0 0 0 0>; 49 + interrupt-map = <0 0 0 0 &gic GIC_SPI 179 IRQ_TYPE_EDGE_RISING>; 50 + bus-range = <0x0 0xff>; 51 + #address-cells = <3>; 52 + #size-cells = <2>; 53 + device_type = "pci"; 54 + ranges = <0x82000000 0 0 0x0 0xf9c00000 0 0x00300000>; 55 + 56 + clocks = <&clkc CLKID_USB 57 + &clkc CLKID_MIPI_ENABLE 58 + &clkc CLKID_PCIE_A 59 + &clkc CLKID_PCIE_CML_EN0>; 60 + clock-names = "general", 61 + "mipi", 62 + "pclk", 63 + "port"; 64 + resets = <&reset RESET_PCIE_PHY>, 65 + <&reset RESET_PCIE_A>, 66 + <&reset RESET_PCIE_APB>; 67 + reset-names = "phy", 68 + "port", 69 + "apb"; 70 + };
+3 -1
Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
··· 41 41 Additional required properties for imx6sx-pcie: 42 42 - clock names: Must include the following additional entries: 43 43 - "pcie_inbound_axi" 44 - - power-domains: Must be set to a phandle pointing to the PCIE_PHY power domain 44 + - power-domains: Must be set to phandles pointing to the DISPLAY and 45 + PCIE_PHY power domains 46 + - power-domain-names: Must be "pcie", "pcie_phy" 45 47 46 48 Additional required properties for imx7d-pcie: 47 49 - power-domains: Must be set to a phandle pointing to PCIE_PHY power domain
-8
Documentation/devicetree/bindings/pci/mediatek-pcie.txt
··· 65 65 explanation. 66 66 - ranges: Sub-ranges distributed from the PCIe controller node. An empty 67 67 property is sufficient. 68 - - num-lanes: Number of lanes to use for this port. 69 68 70 69 Examples for MT7623: 71 70 ··· 117 118 interrupt-map-mask = <0 0 0 0>; 118 119 interrupt-map = <0 0 0 0 &sysirq GIC_SPI 193 IRQ_TYPE_LEVEL_LOW>; 119 120 ranges; 120 - num-lanes = <1>; 121 121 }; 122 122 123 123 pcie@1,0 { ··· 127 129 interrupt-map-mask = <0 0 0 0>; 128 130 interrupt-map = <0 0 0 0 &sysirq GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>; 129 131 ranges; 130 - num-lanes = <1>; 131 132 }; 132 133 133 134 pcie@2,0 { ··· 137 140 interrupt-map-mask = <0 0 0 0>; 138 141 interrupt-map = <0 0 0 0 &sysirq GIC_SPI 195 IRQ_TYPE_LEVEL_LOW>; 139 142 ranges; 140 - num-lanes = <1>; 141 143 }; 142 144 }; 143 145 ··· 168 172 #size-cells = <2>; 169 173 #interrupt-cells = <1>; 170 174 ranges; 171 - num-lanes = <1>; 172 175 interrupt-map-mask = <0 0 0 7>; 173 176 interrupt-map = <0 0 0 1 &pcie_intc0 0>, 174 177 <0 0 0 2 &pcie_intc0 1>, ··· 186 191 #size-cells = <2>; 187 192 #interrupt-cells = <1>; 188 193 ranges; 189 - num-lanes = <1>; 190 194 interrupt-map-mask = <0 0 0 7>; 191 195 interrupt-map = <0 0 0 1 &pcie_intc1 0>, 192 196 <0 0 0 2 &pcie_intc1 1>, ··· 239 245 #size-cells = <2>; 240 246 #interrupt-cells = <1>; 241 247 ranges; 242 - num-lanes = <1>; 243 248 interrupt-map-mask = <0 0 0 7>; 244 249 interrupt-map = <0 0 0 1 &pcie_intc0 0>, 245 250 <0 0 0 2 &pcie_intc0 1>, ··· 257 264 #size-cells = <2>; 258 265 #interrupt-cells = <1>; 259 266 ranges; 260 - num-lanes = <1>; 261 267 interrupt-map-mask = <0 0 0 7>; 262 268 interrupt-map = <0 0 0 1 &pcie_intc1 0>, 263 269 <0 0 0 2 &pcie_intc1 1>,
+81
Documentation/devicetree/bindings/pci/uniphier-pcie.txt
··· 1 + Socionext UniPhier PCIe host controller bindings 2 + 3 + This describes the devicetree bindings for PCIe host controller implemented 4 + on Socionext UniPhier SoCs. 5 + 6 + UniPhier PCIe host controller is based on the Synopsys DesignWare PCI core. 7 + It shares common functions with the PCIe DesignWare core driver and inherits 8 + common properties defined in 9 + Documentation/devicetree/bindings/pci/designware-pcie.txt. 10 + 11 + Required properties: 12 + - compatible: Should be "socionext,uniphier-pcie". 13 + - reg: Specifies offset and length of the register set for the device. 14 + According to the reg-names, appropriate register sets are required. 15 + - reg-names: Must include the following entries: 16 + "dbi" - controller configuration registers 17 + "link" - SoC-specific glue layer registers 18 + "config" - PCIe configuration space 19 + - clocks: A phandle to the clock gate for PCIe glue layer including 20 + the host controller. 21 + - resets: A phandle to the reset line for PCIe glue layer including 22 + the host controller. 23 + - interrupts: A list of interrupt specifiers. According to the 24 + interrupt-names, appropriate interrupts are required. 25 + - interrupt-names: Must include the following entries: 26 + "dma" - DMA interrupt 27 + "msi" - MSI interrupt 28 + 29 + Optional properties: 30 + - phys: A phandle to generic PCIe PHY. According to the phy-names, appropriate 31 + phys are required. 32 + - phy-names: Must be "pcie-phy". 33 + 34 + Required sub-node: 35 + - legacy-interrupt-controller: Specifies interrupt controller for legacy PCI 36 + interrupts. 37 + 38 + Required properties for legacy-interrupt-controller: 39 + - interrupt-controller: identifies the node as an interrupt controller. 40 + - #interrupt-cells: specifies the number of cells needed to encode an 41 + interrupt source. The value must be 1. 42 + - interrupt-parent: Phandle to the parent interrupt controller. 43 + - interrupts: An interrupt specifier for legacy interrupt. 44 + 45 + Example: 46 + 47 + pcie: pcie@66000000 { 48 + compatible = "socionext,uniphier-pcie", "snps,dw-pcie"; 49 + status = "disabled"; 50 + reg-names = "dbi", "link", "config"; 51 + reg = <0x66000000 0x1000>, <0x66010000 0x10000>, 52 + <0x2fff0000 0x10000>; 53 + #address-cells = <3>; 54 + #size-cells = <2>; 55 + clocks = <&sys_clk 24>; 56 + resets = <&sys_rst 24>; 57 + num-lanes = <1>; 58 + num-viewport = <1>; 59 + bus-range = <0x0 0xff>; 60 + device_type = "pci"; 61 + ranges = 62 + /* downstream I/O */ 63 + <0x81000000 0 0x00000000 0x2ffe0000 0 0x00010000 64 + /* non-prefetchable memory */ 65 + 0x82000000 0 0x00000000 0x20000000 0 0x0ffe0000>; 66 + #interrupt-cells = <1>; 67 + interrupt-names = "dma", "msi"; 68 + interrupts = <0 224 4>, <0 225 4>; 69 + interrupt-map-mask = <0 0 0 7>; 70 + interrupt-map = <0 0 0 1 &pcie_intc 0>, /* INTA */ 71 + <0 0 0 2 &pcie_intc 1>, /* INTB */ 72 + <0 0 0 3 &pcie_intc 2>, /* INTC */ 73 + <0 0 0 4 &pcie_intc 3>; /* INTD */ 74 + 75 + pcie_intc: legacy-interrupt-controller { 76 + interrupt-controller; 77 + #interrupt-cells = <1>; 78 + interrupt-parent = <&gic>; 79 + interrupts = <0 226 4>; 80 + }; 81 + };
+2 -2
Documentation/driver-api/pci/p2pdma.rst
··· 49 49 in that it exposes any CMB (Controller Memory Buffer) as a P2P memory 50 50 resource (provider), it accepts P2P memory pages as buffers in requests 51 51 to be used directly (client) and it can also make use of the CMB as 52 - submission queue entries (orchastrator). 52 + submission queue entries (orchestrator). 53 53 * The RDMA driver is a client in this arrangement so that an RNIC 54 54 can DMA directly to the memory exposed by the NVMe device. 55 55 * The NVMe Target driver (nvmet) can orchestrate the data from the RNIC ··· 111 111 If more than one provider is supported, the one nearest to all the clients will 112 112 be chosen first. If more than one provider is an equal distance away, the 113 113 one returned will be chosen at random (it is not an arbitrary but 114 - truely random). This function returns the PCI device to use for the provider 114 + truly random). This function returns the PCI device to use for the provider 115 115 with a reference taken and therefore when it's no longer needed it should be 116 116 returned with pci_dev_put(). 117 117
+15 -1
MAINTAINERS
··· 11750 11750 F: lib/pci* 11751 11751 F: arch/x86/pci/ 11752 11752 F: arch/x86/kernel/quirks.c 11753 + F: arch/x86/kernel/early-quirks.c 11753 11754 11754 11755 PCI NATIVE HOST BRIDGE AND ENDPOINT DRIVERS 11755 11756 M: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> ··· 11759 11758 T: git git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/pci.git/ 11760 11759 S: Supported 11761 11760 F: drivers/pci/controller/ 11761 + 11762 + PCIE DRIVER FOR AMLOGIC MESON 11763 + M: Yue Wang <yue.wang@Amlogic.com> 11764 + L: linux-pci@vger.kernel.org 11765 + L: linux-amlogic@lists.infradead.org 11766 + S: Maintained 11767 + F: drivers/pci/controller/dwc/pci-meson.c 11762 11768 11763 11769 PCIE DRIVER FOR AXIS ARTPEC 11764 11770 M: Jesper Nilsson <jesper.nilsson@axis.com> ··· 11799 11791 F: drivers/pci/controller/dwc/pcie-kirin.c 11800 11792 11801 11793 PCIE DRIVER FOR HISILICON STB 11802 - M: Jianguo Sun <sunjianguo1@huawei.com> 11803 11794 M: Shawn Guo <shawn.guo@linaro.org> 11804 11795 L: linux-pci@vger.kernel.org 11805 11796 S: Maintained ··· 11834 11827 S: Maintained 11835 11828 F: Documentation/devicetree/bindings/pci/v3-v360epc-pci.txt 11836 11829 F: drivers/pci/controller/pci-v3-semi.c 11830 + 11831 + PCIE DRIVER FOR SOCIONEXT UNIPHIER 11832 + M: Kunihiko Hayashi <hayashi.kunihiko@socionext.com> 11833 + L: linux-pci@vger.kernel.org 11834 + S: Maintained 11835 + F: Documentation/devicetree/bindings/pci/uniphier-pcie.txt 11836 + F: drivers/pci/controller/dwc/pcie-uniphier.c 11837 11837 11838 11838 PCIE DRIVER FOR ST SPEAR13XX 11839 11839 M: Pratyush Anand <pratyush.anand@gmail.com>
-3
arch/arm/boot/dts/mt7623.dtsi
··· 850 850 interrupt-map-mask = <0 0 0 0>; 851 851 interrupt-map = <0 0 0 0 &sysirq GIC_SPI 193 IRQ_TYPE_LEVEL_LOW>; 852 852 ranges; 853 - num-lanes = <1>; 854 853 status = "disabled"; 855 854 }; 856 855 ··· 861 862 interrupt-map-mask = <0 0 0 0>; 862 863 interrupt-map = <0 0 0 0 &sysirq GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>; 863 864 ranges; 864 - num-lanes = <1>; 865 865 status = "disabled"; 866 866 }; 867 867 ··· 872 874 interrupt-map-mask = <0 0 0 0>; 873 875 interrupt-map = <0 0 0 0 &sysirq GIC_SPI 195 IRQ_TYPE_LEVEL_LOW>; 874 876 ranges; 875 - num-lanes = <1>; 876 877 status = "disabled"; 877 878 }; 878 879 };
-2
arch/arm64/boot/dts/mediatek/mt7622.dtsi
··· 802 802 ranges; 803 803 status = "disabled"; 804 804 805 - num-lanes = <1>; 806 805 interrupt-map-mask = <0 0 0 7>; 807 806 interrupt-map = <0 0 0 1 &pcie_intc0 0>, 808 807 <0 0 0 2 &pcie_intc0 1>, ··· 822 823 ranges; 823 824 status = "disabled"; 824 825 825 - num-lanes = <1>; 826 826 interrupt-map-mask = <0 0 0 7>; 827 827 interrupt-map = <0 0 0 1 &pcie_intc1 0>, 828 828 <0 0 0 2 &pcie_intc1 1>,
+3
arch/s390/pci/pci.c
··· 649 649 struct resource *res; 650 650 int i; 651 651 652 + if (pdev->is_physfn) 653 + pdev->no_vf_scan = 1; 654 + 652 655 pdev->dev.groups = zpci_attr_groups; 653 656 pdev->dev.dma_ops = &s390_pci_dma_ops; 654 657 zpci_map_resources(pdev);
+2 -2
arch/x86/pci/broadcom_bus.c
··· 50 50 word1 = read_pci_config_16(bus, slot, func, 0xc0); 51 51 word2 = read_pci_config_16(bus, slot, func, 0xc2); 52 52 if (word1 != word2) { 53 - res.start = (word1 << 16) | 0x0000; 54 - res.end = (word2 << 16) | 0xffff; 53 + res.start = ((resource_size_t) word1 << 16) | 0x0000; 54 + res.end = ((resource_size_t) word2 << 16) | 0xffff; 55 55 res.flags = IORESOURCE_MEM; 56 56 update_res(info, res.start, res.end, res.flags, 0); 57 57 }
+3 -3
drivers/pci/Kconfig
··· 103 103 depends on PCI_IOV 104 104 help 105 105 Say Y or M here if you want to enable support for devices that 106 - require SR-IOV support, while at the same time the PF itself is 107 - not providing any actual services on the host itself such as 108 - storage or networking. 106 + require SR-IOV support, while at the same time the PF (Physical 107 + Function) itself is not providing any actual services on the 108 + host itself such as storage or networking. 109 109 110 110 When in doubt, say N. 111 111
+22 -2
drivers/pci/controller/dwc/Kconfig
··· 89 89 select PCIE_DW_HOST 90 90 91 91 config PCI_IMX6 92 - bool "Freescale i.MX6 PCIe controller" 93 - depends on SOC_IMX6Q || (ARM && COMPILE_TEST) 92 + bool "Freescale i.MX6/7 PCIe controller" 93 + depends on SOC_IMX6Q || SOC_IMX7D || (ARM && COMPILE_TEST) 94 94 depends on PCI_MSI_IRQ_DOMAIN 95 95 select PCIE_DW_HOST 96 96 ··· 192 192 select PCIE_DW_HOST 193 193 help 194 194 Say Y here if you want PCIe controller support on HiSilicon STB SoCs 195 + 196 + config PCI_MESON 197 + bool "MESON PCIe controller" 198 + depends on PCI_MSI_IRQ_DOMAIN 199 + select PCIE_DW_HOST 200 + help 201 + Say Y here if you want to enable PCI controller support on Amlogic 202 + SoCs. The PCI controller on Amlogic is based on DesignWare hardware 203 + and therefore the driver re-uses the DesignWare core functions to 204 + implement the driver. 205 + 206 + config PCIE_UNIPHIER 207 + bool "Socionext UniPhier PCIe controllers" 208 + depends on ARCH_UNIPHIER || COMPILE_TEST 209 + depends on OF && HAS_IOMEM 210 + depends on PCI_MSI_IRQ_DOMAIN 211 + select PCIE_DW_HOST 212 + help 213 + Say Y here if you want PCIe controller support on UniPhier SoCs. 214 + This driver supports LD20 and PXs3 SoCs. 195 215 196 216 endmenu
+2
drivers/pci/controller/dwc/Makefile
··· 14 14 obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o 15 15 obj-$(CONFIG_PCIE_KIRIN) += pcie-kirin.o 16 16 obj-$(CONFIG_PCIE_HISI_STB) += pcie-histb.o 17 + obj-$(CONFIG_PCI_MESON) += pci-meson.o 18 + obj-$(CONFIG_PCIE_UNIPHIER) += pcie-uniphier.o 17 19 18 20 # The following drivers are for devices that use the generic ACPI 19 21 # pci_root.c driver but don't support standard ECAM config access.
+97 -5
drivers/pci/controller/dwc/pci-imx6.c
··· 27 27 #include <linux/types.h> 28 28 #include <linux/interrupt.h> 29 29 #include <linux/reset.h> 30 + #include <linux/pm_domain.h> 31 + #include <linux/pm_runtime.h> 30 32 31 33 #include "pcie-designware.h" 32 34 ··· 61 59 u32 tx_swing_low; 62 60 int link_gen; 63 61 struct regulator *vpcie; 62 + 63 + /* power domain for pcie */ 64 + struct device *pd_pcie; 65 + /* power domain for pcie phy */ 66 + struct device *pd_pcie_phy; 64 67 }; 65 68 66 69 /* Parameters for the waiting for PCIe PHY PLL to lock on i.MX7 */ ··· 74 67 #define PHY_PLL_LOCK_WAIT_USLEEP_MAX 200 75 68 76 69 /* PCIe Root Complex registers (memory-mapped) */ 70 + #define PCIE_RC_IMX6_MSI_CAP 0x50 77 71 #define PCIE_RC_LCR 0x7c 78 72 #define PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1 0x1 79 73 #define PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN2 0x2 ··· 296 288 } 297 289 298 290 return 1; 291 + } 292 + 293 + static int imx6_pcie_attach_pd(struct device *dev) 294 + { 295 + struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev); 296 + struct device_link *link; 297 + 298 + /* Do nothing when in a single power domain */ 299 + if (dev->pm_domain) 300 + return 0; 301 + 302 + imx6_pcie->pd_pcie = dev_pm_domain_attach_by_name(dev, "pcie"); 303 + if (IS_ERR(imx6_pcie->pd_pcie)) 304 + return PTR_ERR(imx6_pcie->pd_pcie); 305 + link = device_link_add(dev, imx6_pcie->pd_pcie, 306 + DL_FLAG_STATELESS | 307 + DL_FLAG_PM_RUNTIME | 308 + DL_FLAG_RPM_ACTIVE); 309 + if (!link) { 310 + dev_err(dev, "Failed to add device_link to pcie pd.\n"); 311 + return -EINVAL; 312 + } 313 + 314 + imx6_pcie->pd_pcie_phy = dev_pm_domain_attach_by_name(dev, "pcie_phy"); 315 + if (IS_ERR(imx6_pcie->pd_pcie_phy)) 316 + return PTR_ERR(imx6_pcie->pd_pcie_phy); 317 + 318 + device_link_add(dev, imx6_pcie->pd_pcie_phy, 319 + DL_FLAG_STATELESS | 320 + DL_FLAG_PM_RUNTIME | 321 + DL_FLAG_RPM_ACTIVE); 322 + if (IS_ERR(link)) { 323 + dev_err(dev, "Failed to add device_link to pcie_phy pd: %ld\n", PTR_ERR(link)); 324 + return PTR_ERR(link); 325 + } 326 + 327 + return 0; 299 328 } 300 329 301 330 static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie) ··· 810 765 811 766 static void imx6_pcie_pm_turnoff(struct imx6_pcie *imx6_pcie) 812 767 { 813 - reset_control_assert(imx6_pcie->turnoff_reset); 814 - reset_control_deassert(imx6_pcie->turnoff_reset); 768 + struct device *dev = imx6_pcie->pci->dev; 769 + 770 + /* Some variants have a turnoff reset in DT */ 771 + if (imx6_pcie->turnoff_reset) { 772 + reset_control_assert(imx6_pcie->turnoff_reset); 773 + reset_control_deassert(imx6_pcie->turnoff_reset); 774 + goto pm_turnoff_sleep; 775 + } 776 + 777 + /* Others poke directly at IOMUXC registers */ 778 + switch (imx6_pcie->variant) { 779 + case IMX6SX: 780 + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, 781 + IMX6SX_GPR12_PCIE_PM_TURN_OFF, 782 + IMX6SX_GPR12_PCIE_PM_TURN_OFF); 783 + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, 784 + IMX6SX_GPR12_PCIE_PM_TURN_OFF, 0); 785 + break; 786 + default: 787 + dev_err(dev, "PME_Turn_Off not implemented\n"); 788 + return; 789 + } 815 790 816 791 /* 817 792 * Components with an upstream port must respond to ··· 840 775 * The standard recommends a 1-10ms timeout after which to 841 776 * proceed anyway as if acks were received. 842 777 */ 778 + pm_turnoff_sleep: 843 779 usleep_range(1000, 10000); 844 780 } 845 781 ··· 850 784 clk_disable_unprepare(imx6_pcie->pcie_phy); 851 785 clk_disable_unprepare(imx6_pcie->pcie_bus); 852 786 853 - if (imx6_pcie->variant == IMX7D) { 787 + switch (imx6_pcie->variant) { 788 + case IMX6SX: 789 + clk_disable_unprepare(imx6_pcie->pcie_inbound_axi); 790 + break; 791 + case IMX7D: 854 792 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, 855 793 IMX7D_GPR12_PCIE_PHY_REFCLK_SEL, 856 794 IMX7D_GPR12_PCIE_PHY_REFCLK_SEL); 795 + break; 796 + default: 797 + break; 857 798 } 799 + } 800 + 801 + static inline bool imx6_pcie_supports_suspend(struct imx6_pcie *imx6_pcie) 802 + { 803 + return (imx6_pcie->variant == IMX7D || 804 + imx6_pcie->variant == IMX6SX); 858 805 } 859 806 860 807 static int imx6_pcie_suspend_noirq(struct device *dev) 861 808 { 862 809 struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev); 863 810 864 - if (imx6_pcie->variant != IMX7D) 811 + if (!imx6_pcie_supports_suspend(imx6_pcie)) 865 812 return 0; 866 813 867 814 imx6_pcie_pm_turnoff(imx6_pcie); ··· 890 811 struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev); 891 812 struct pcie_port *pp = &imx6_pcie->pci->pp; 892 813 893 - if (imx6_pcie->variant != IMX7D) 814 + if (!imx6_pcie_supports_suspend(imx6_pcie)) 894 815 return 0; 895 816 896 817 imx6_pcie_assert_core_reset(imx6_pcie); ··· 919 840 struct resource *dbi_base; 920 841 struct device_node *node = dev->of_node; 921 842 int ret; 843 + u16 val; 922 844 923 845 imx6_pcie = devm_kzalloc(dev, sizeof(*imx6_pcie), GFP_KERNEL); 924 846 if (!imx6_pcie) ··· 1057 977 1058 978 platform_set_drvdata(pdev, imx6_pcie); 1059 979 980 + ret = imx6_pcie_attach_pd(dev); 981 + if (ret) 982 + return ret; 983 + 1060 984 ret = imx6_add_pcie_port(imx6_pcie, pdev); 1061 985 if (ret < 0) 1062 986 return ret; 987 + 988 + if (pci_msi_enabled()) { 989 + val = dw_pcie_readw_dbi(pci, PCIE_RC_IMX6_MSI_CAP + 990 + PCI_MSI_FLAGS); 991 + val |= PCI_MSI_FLAGS_ENABLE; 992 + dw_pcie_writew_dbi(pci, PCIE_RC_IMX6_MSI_CAP + PCI_MSI_FLAGS, 993 + val); 994 + } 1063 995 1064 996 return 0; 1065 997 }
+5 -5
drivers/pci/controller/dwc/pci-layerscape.c
··· 222 222 .link_up = ls_pcie_link_up, 223 223 }; 224 224 225 - static struct ls_pcie_drvdata ls1021_drvdata = { 225 + static const struct ls_pcie_drvdata ls1021_drvdata = { 226 226 .ops = &ls1021_pcie_host_ops, 227 227 .dw_pcie_ops = &dw_ls1021_pcie_ops, 228 228 }; 229 229 230 - static struct ls_pcie_drvdata ls1043_drvdata = { 230 + static const struct ls_pcie_drvdata ls1043_drvdata = { 231 231 .lut_offset = 0x10000, 232 232 .ltssm_shift = 24, 233 233 .lut_dbg = 0x7fc, ··· 235 235 .dw_pcie_ops = &dw_ls_pcie_ops, 236 236 }; 237 237 238 - static struct ls_pcie_drvdata ls1046_drvdata = { 238 + static const struct ls_pcie_drvdata ls1046_drvdata = { 239 239 .lut_offset = 0x80000, 240 240 .ltssm_shift = 24, 241 241 .lut_dbg = 0x407fc, ··· 243 243 .dw_pcie_ops = &dw_ls_pcie_ops, 244 244 }; 245 245 246 - static struct ls_pcie_drvdata ls2080_drvdata = { 246 + static const struct ls_pcie_drvdata ls2080_drvdata = { 247 247 .lut_offset = 0x80000, 248 248 .ltssm_shift = 0, 249 249 .lut_dbg = 0x7fc, ··· 251 251 .dw_pcie_ops = &dw_ls_pcie_ops, 252 252 }; 253 253 254 - static struct ls_pcie_drvdata ls2088_drvdata = { 254 + static const struct ls_pcie_drvdata ls2088_drvdata = { 255 255 .lut_offset = 0x80000, 256 256 .ltssm_shift = 0, 257 257 .lut_dbg = 0x407fc,
+592
drivers/pci/controller/dwc/pci-meson.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * PCIe host controller driver for Amlogic MESON SoCs 4 + * 5 + * Copyright (c) 2018 Amlogic, inc. 6 + * Author: Yue Wang <yue.wang@amlogic.com> 7 + */ 8 + 9 + #include <linux/clk.h> 10 + #include <linux/delay.h> 11 + #include <linux/of_device.h> 12 + #include <linux/of_gpio.h> 13 + #include <linux/pci.h> 14 + #include <linux/platform_device.h> 15 + #include <linux/reset.h> 16 + #include <linux/resource.h> 17 + #include <linux/types.h> 18 + 19 + #include "pcie-designware.h" 20 + 21 + #define to_meson_pcie(x) dev_get_drvdata((x)->dev) 22 + 23 + /* External local bus interface registers */ 24 + #define PLR_OFFSET 0x700 25 + #define PCIE_PORT_LINK_CTRL_OFF (PLR_OFFSET + 0x10) 26 + #define FAST_LINK_MODE BIT(7) 27 + #define LINK_CAPABLE_MASK GENMASK(21, 16) 28 + #define LINK_CAPABLE_X1 BIT(16) 29 + 30 + #define PCIE_GEN2_CTRL_OFF (PLR_OFFSET + 0x10c) 31 + #define NUM_OF_LANES_MASK GENMASK(12, 8) 32 + #define NUM_OF_LANES_X1 BIT(8) 33 + #define DIRECT_SPEED_CHANGE BIT(17) 34 + 35 + #define TYPE1_HDR_OFFSET 0x0 36 + #define PCIE_STATUS_COMMAND (TYPE1_HDR_OFFSET + 0x04) 37 + #define PCI_IO_EN BIT(0) 38 + #define PCI_MEM_SPACE_EN BIT(1) 39 + #define PCI_BUS_MASTER_EN BIT(2) 40 + 41 + #define PCIE_BASE_ADDR0 (TYPE1_HDR_OFFSET + 0x10) 42 + #define PCIE_BASE_ADDR1 (TYPE1_HDR_OFFSET + 0x14) 43 + 44 + #define PCIE_CAP_OFFSET 0x70 45 + #define PCIE_DEV_CTRL_DEV_STUS (PCIE_CAP_OFFSET + 0x08) 46 + #define PCIE_CAP_MAX_PAYLOAD_MASK GENMASK(7, 5) 47 + #define PCIE_CAP_MAX_PAYLOAD_SIZE(x) ((x) << 5) 48 + #define PCIE_CAP_MAX_READ_REQ_MASK GENMASK(14, 12) 49 + #define PCIE_CAP_MAX_READ_REQ_SIZE(x) ((x) << 12) 50 + 51 + /* PCIe specific config registers */ 52 + #define PCIE_CFG0 0x0 53 + #define APP_LTSSM_ENABLE BIT(7) 54 + 55 + #define PCIE_CFG_STATUS12 0x30 56 + #define IS_SMLH_LINK_UP(x) ((x) & (1 << 6)) 57 + #define IS_RDLH_LINK_UP(x) ((x) & (1 << 16)) 58 + #define IS_LTSSM_UP(x) ((((x) >> 10) & 0x1f) == 0x11) 59 + 60 + #define PCIE_CFG_STATUS17 0x44 61 + #define PM_CURRENT_STATE(x) (((x) >> 7) & 0x1) 62 + 63 + #define WAIT_LINKUP_TIMEOUT 4000 64 + #define PORT_CLK_RATE 100000000UL 65 + #define MAX_PAYLOAD_SIZE 256 66 + #define MAX_READ_REQ_SIZE 256 67 + #define MESON_PCIE_PHY_POWERUP 0x1c 68 + #define PCIE_RESET_DELAY 500 69 + #define PCIE_SHARED_RESET 1 70 + #define PCIE_NORMAL_RESET 0 71 + 72 + enum pcie_data_rate { 73 + PCIE_GEN1, 74 + PCIE_GEN2, 75 + PCIE_GEN3, 76 + PCIE_GEN4 77 + }; 78 + 79 + struct meson_pcie_mem_res { 80 + void __iomem *elbi_base; 81 + void __iomem *cfg_base; 82 + void __iomem *phy_base; 83 + }; 84 + 85 + struct meson_pcie_clk_res { 86 + struct clk *clk; 87 + struct clk *mipi_gate; 88 + struct clk *port_clk; 89 + struct clk *general_clk; 90 + }; 91 + 92 + struct meson_pcie_rc_reset { 93 + struct reset_control *phy; 94 + struct reset_control *port; 95 + struct reset_control *apb; 96 + }; 97 + 98 + struct meson_pcie { 99 + struct dw_pcie pci; 100 + struct meson_pcie_mem_res mem_res; 101 + struct meson_pcie_clk_res clk_res; 102 + struct meson_pcie_rc_reset mrst; 103 + struct gpio_desc *reset_gpio; 104 + }; 105 + 106 + static struct reset_control *meson_pcie_get_reset(struct meson_pcie *mp, 107 + const char *id, 108 + u32 reset_type) 109 + { 110 + struct device *dev = mp->pci.dev; 111 + struct reset_control *reset; 112 + 113 + if (reset_type == PCIE_SHARED_RESET) 114 + reset = devm_reset_control_get_shared(dev, id); 115 + else 116 + reset = devm_reset_control_get(dev, id); 117 + 118 + return reset; 119 + } 120 + 121 + static int meson_pcie_get_resets(struct meson_pcie *mp) 122 + { 123 + struct meson_pcie_rc_reset *mrst = &mp->mrst; 124 + 125 + mrst->phy = meson_pcie_get_reset(mp, "phy", PCIE_SHARED_RESET); 126 + if (IS_ERR(mrst->phy)) 127 + return PTR_ERR(mrst->phy); 128 + reset_control_deassert(mrst->phy); 129 + 130 + mrst->port = meson_pcie_get_reset(mp, "port", PCIE_NORMAL_RESET); 131 + if (IS_ERR(mrst->port)) 132 + return PTR_ERR(mrst->port); 133 + reset_control_deassert(mrst->port); 134 + 135 + mrst->apb = meson_pcie_get_reset(mp, "apb", PCIE_SHARED_RESET); 136 + if (IS_ERR(mrst->apb)) 137 + return PTR_ERR(mrst->apb); 138 + reset_control_deassert(mrst->apb); 139 + 140 + return 0; 141 + } 142 + 143 + static void __iomem *meson_pcie_get_mem(struct platform_device *pdev, 144 + struct meson_pcie *mp, 145 + const char *id) 146 + { 147 + struct device *dev = mp->pci.dev; 148 + struct resource *res; 149 + 150 + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, id); 151 + 152 + return devm_ioremap_resource(dev, res); 153 + } 154 + 155 + static void __iomem *meson_pcie_get_mem_shared(struct platform_device *pdev, 156 + struct meson_pcie *mp, 157 + const char *id) 158 + { 159 + struct device *dev = mp->pci.dev; 160 + struct resource *res; 161 + 162 + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, id); 163 + if (!res) { 164 + dev_err(dev, "No REG resource %s\n", id); 165 + return ERR_PTR(-ENXIO); 166 + } 167 + 168 + return devm_ioremap(dev, res->start, resource_size(res)); 169 + } 170 + 171 + static int meson_pcie_get_mems(struct platform_device *pdev, 172 + struct meson_pcie *mp) 173 + { 174 + mp->mem_res.elbi_base = meson_pcie_get_mem(pdev, mp, "elbi"); 175 + if (IS_ERR(mp->mem_res.elbi_base)) 176 + return PTR_ERR(mp->mem_res.elbi_base); 177 + 178 + mp->mem_res.cfg_base = meson_pcie_get_mem(pdev, mp, "cfg"); 179 + if (IS_ERR(mp->mem_res.cfg_base)) 180 + return PTR_ERR(mp->mem_res.cfg_base); 181 + 182 + /* Meson SoC has two PCI controllers use same phy register*/ 183 + mp->mem_res.phy_base = meson_pcie_get_mem_shared(pdev, mp, "phy"); 184 + if (IS_ERR(mp->mem_res.phy_base)) 185 + return PTR_ERR(mp->mem_res.phy_base); 186 + 187 + return 0; 188 + } 189 + 190 + static void meson_pcie_power_on(struct meson_pcie *mp) 191 + { 192 + writel(MESON_PCIE_PHY_POWERUP, mp->mem_res.phy_base); 193 + } 194 + 195 + static void meson_pcie_reset(struct meson_pcie *mp) 196 + { 197 + struct meson_pcie_rc_reset *mrst = &mp->mrst; 198 + 199 + reset_control_assert(mrst->phy); 200 + udelay(PCIE_RESET_DELAY); 201 + reset_control_deassert(mrst->phy); 202 + udelay(PCIE_RESET_DELAY); 203 + 204 + reset_control_assert(mrst->port); 205 + reset_control_assert(mrst->apb); 206 + udelay(PCIE_RESET_DELAY); 207 + reset_control_deassert(mrst->port); 208 + reset_control_deassert(mrst->apb); 209 + udelay(PCIE_RESET_DELAY); 210 + } 211 + 212 + static inline struct clk *meson_pcie_probe_clock(struct device *dev, 213 + const char *id, u64 rate) 214 + { 215 + struct clk *clk; 216 + int ret; 217 + 218 + clk = devm_clk_get(dev, id); 219 + if (IS_ERR(clk)) 220 + return clk; 221 + 222 + if (rate) { 223 + ret = clk_set_rate(clk, rate); 224 + if (ret) { 225 + dev_err(dev, "set clk rate failed, ret = %d\n", ret); 226 + return ERR_PTR(ret); 227 + } 228 + } 229 + 230 + ret = clk_prepare_enable(clk); 231 + if (ret) { 232 + dev_err(dev, "couldn't enable clk\n"); 233 + return ERR_PTR(ret); 234 + } 235 + 236 + devm_add_action_or_reset(dev, 237 + (void (*) (void *))clk_disable_unprepare, 238 + clk); 239 + 240 + return clk; 241 + } 242 + 243 + static int meson_pcie_probe_clocks(struct meson_pcie *mp) 244 + { 245 + struct device *dev = mp->pci.dev; 246 + struct meson_pcie_clk_res *res = &mp->clk_res; 247 + 248 + res->port_clk = meson_pcie_probe_clock(dev, "port", PORT_CLK_RATE); 249 + if (IS_ERR(res->port_clk)) 250 + return PTR_ERR(res->port_clk); 251 + 252 + res->mipi_gate = meson_pcie_probe_clock(dev, "pcie_mipi_en", 0); 253 + if (IS_ERR(res->mipi_gate)) 254 + return PTR_ERR(res->mipi_gate); 255 + 256 + res->general_clk = meson_pcie_probe_clock(dev, "pcie_general", 0); 257 + if (IS_ERR(res->general_clk)) 258 + return PTR_ERR(res->general_clk); 259 + 260 + res->clk = meson_pcie_probe_clock(dev, "pcie", 0); 261 + if (IS_ERR(res->clk)) 262 + return PTR_ERR(res->clk); 263 + 264 + return 0; 265 + } 266 + 267 + static inline void meson_elb_writel(struct meson_pcie *mp, u32 val, u32 reg) 268 + { 269 + writel(val, mp->mem_res.elbi_base + reg); 270 + } 271 + 272 + static inline u32 meson_elb_readl(struct meson_pcie *mp, u32 reg) 273 + { 274 + return readl(mp->mem_res.elbi_base + reg); 275 + } 276 + 277 + static inline u32 meson_cfg_readl(struct meson_pcie *mp, u32 reg) 278 + { 279 + return readl(mp->mem_res.cfg_base + reg); 280 + } 281 + 282 + static inline void meson_cfg_writel(struct meson_pcie *mp, u32 val, u32 reg) 283 + { 284 + writel(val, mp->mem_res.cfg_base + reg); 285 + } 286 + 287 + static void meson_pcie_assert_reset(struct meson_pcie *mp) 288 + { 289 + gpiod_set_value_cansleep(mp->reset_gpio, 0); 290 + udelay(500); 291 + gpiod_set_value_cansleep(mp->reset_gpio, 1); 292 + } 293 + 294 + static void meson_pcie_init_dw(struct meson_pcie *mp) 295 + { 296 + u32 val; 297 + 298 + val = meson_cfg_readl(mp, PCIE_CFG0); 299 + val |= APP_LTSSM_ENABLE; 300 + meson_cfg_writel(mp, val, PCIE_CFG0); 301 + 302 + val = meson_elb_readl(mp, PCIE_PORT_LINK_CTRL_OFF); 303 + val &= ~LINK_CAPABLE_MASK; 304 + meson_elb_writel(mp, val, PCIE_PORT_LINK_CTRL_OFF); 305 + 306 + val = meson_elb_readl(mp, PCIE_PORT_LINK_CTRL_OFF); 307 + val |= LINK_CAPABLE_X1 | FAST_LINK_MODE; 308 + meson_elb_writel(mp, val, PCIE_PORT_LINK_CTRL_OFF); 309 + 310 + val = meson_elb_readl(mp, PCIE_GEN2_CTRL_OFF); 311 + val &= ~NUM_OF_LANES_MASK; 312 + meson_elb_writel(mp, val, PCIE_GEN2_CTRL_OFF); 313 + 314 + val = meson_elb_readl(mp, PCIE_GEN2_CTRL_OFF); 315 + val |= NUM_OF_LANES_X1 | DIRECT_SPEED_CHANGE; 316 + meson_elb_writel(mp, val, PCIE_GEN2_CTRL_OFF); 317 + 318 + meson_elb_writel(mp, 0x0, PCIE_BASE_ADDR0); 319 + meson_elb_writel(mp, 0x0, PCIE_BASE_ADDR1); 320 + } 321 + 322 + static int meson_size_to_payload(struct meson_pcie *mp, int size) 323 + { 324 + struct device *dev = mp->pci.dev; 325 + 326 + /* 327 + * dwc supports 2^(val+7) payload size, which val is 0~5 default to 1. 328 + * So if input size is not 2^order alignment or less than 2^7 or bigger 329 + * than 2^12, just set to default size 2^(1+7). 330 + */ 331 + if (!is_power_of_2(size) || size < 128 || size > 4096) { 332 + dev_warn(dev, "payload size %d, set to default 256\n", size); 333 + return 1; 334 + } 335 + 336 + return fls(size) - 8; 337 + } 338 + 339 + static void meson_set_max_payload(struct meson_pcie *mp, int size) 340 + { 341 + u32 val; 342 + int max_payload_size = meson_size_to_payload(mp, size); 343 + 344 + val = meson_elb_readl(mp, PCIE_DEV_CTRL_DEV_STUS); 345 + val &= ~PCIE_CAP_MAX_PAYLOAD_MASK; 346 + meson_elb_writel(mp, val, PCIE_DEV_CTRL_DEV_STUS); 347 + 348 + val = meson_elb_readl(mp, PCIE_DEV_CTRL_DEV_STUS); 349 + val |= PCIE_CAP_MAX_PAYLOAD_SIZE(max_payload_size); 350 + meson_elb_writel(mp, val, PCIE_DEV_CTRL_DEV_STUS); 351 + } 352 + 353 + static void meson_set_max_rd_req_size(struct meson_pcie *mp, int size) 354 + { 355 + u32 val; 356 + int max_rd_req_size = meson_size_to_payload(mp, size); 357 + 358 + val = meson_elb_readl(mp, PCIE_DEV_CTRL_DEV_STUS); 359 + val &= ~PCIE_CAP_MAX_READ_REQ_MASK; 360 + meson_elb_writel(mp, val, PCIE_DEV_CTRL_DEV_STUS); 361 + 362 + val = meson_elb_readl(mp, PCIE_DEV_CTRL_DEV_STUS); 363 + val |= PCIE_CAP_MAX_READ_REQ_SIZE(max_rd_req_size); 364 + meson_elb_writel(mp, val, PCIE_DEV_CTRL_DEV_STUS); 365 + } 366 + 367 + static inline void meson_enable_memory_space(struct meson_pcie *mp) 368 + { 369 + /* Set the RC Bus Master, Memory Space and I/O Space enables */ 370 + meson_elb_writel(mp, PCI_IO_EN | PCI_MEM_SPACE_EN | PCI_BUS_MASTER_EN, 371 + PCIE_STATUS_COMMAND); 372 + } 373 + 374 + static int meson_pcie_establish_link(struct meson_pcie *mp) 375 + { 376 + struct dw_pcie *pci = &mp->pci; 377 + struct pcie_port *pp = &pci->pp; 378 + 379 + meson_pcie_init_dw(mp); 380 + meson_set_max_payload(mp, MAX_PAYLOAD_SIZE); 381 + meson_set_max_rd_req_size(mp, MAX_READ_REQ_SIZE); 382 + 383 + dw_pcie_setup_rc(pp); 384 + meson_enable_memory_space(mp); 385 + 386 + meson_pcie_assert_reset(mp); 387 + 388 + return dw_pcie_wait_for_link(pci); 389 + } 390 + 391 + static void meson_pcie_enable_interrupts(struct meson_pcie *mp) 392 + { 393 + if (IS_ENABLED(CONFIG_PCI_MSI)) 394 + dw_pcie_msi_init(&mp->pci.pp); 395 + } 396 + 397 + static int meson_pcie_rd_own_conf(struct pcie_port *pp, int where, int size, 398 + u32 *val) 399 + { 400 + struct dw_pcie *pci = to_dw_pcie_from_pp(pp); 401 + int ret; 402 + 403 + ret = dw_pcie_read(pci->dbi_base + where, size, val); 404 + if (ret != PCIBIOS_SUCCESSFUL) 405 + return ret; 406 + 407 + /* 408 + * There is a bug in the MESON AXG PCIe controller whereby software 409 + * cannot program the PCI_CLASS_DEVICE register, so we must fabricate 410 + * the return value in the config accessors. 411 + */ 412 + if (where == PCI_CLASS_REVISION && size == 4) 413 + *val = (PCI_CLASS_BRIDGE_PCI << 16) | (*val & 0xffff); 414 + else if (where == PCI_CLASS_DEVICE && size == 2) 415 + *val = PCI_CLASS_BRIDGE_PCI; 416 + else if (where == PCI_CLASS_DEVICE && size == 1) 417 + *val = PCI_CLASS_BRIDGE_PCI & 0xff; 418 + else if (where == PCI_CLASS_DEVICE + 1 && size == 1) 419 + *val = (PCI_CLASS_BRIDGE_PCI >> 8) & 0xff; 420 + 421 + return PCIBIOS_SUCCESSFUL; 422 + } 423 + 424 + static int meson_pcie_wr_own_conf(struct pcie_port *pp, int where, 425 + int size, u32 val) 426 + { 427 + struct dw_pcie *pci = to_dw_pcie_from_pp(pp); 428 + 429 + return dw_pcie_write(pci->dbi_base + where, size, val); 430 + } 431 + 432 + static int meson_pcie_link_up(struct dw_pcie *pci) 433 + { 434 + struct meson_pcie *mp = to_meson_pcie(pci); 435 + struct device *dev = pci->dev; 436 + u32 speed_okay = 0; 437 + u32 cnt = 0; 438 + u32 state12, state17, smlh_up, ltssm_up, rdlh_up; 439 + 440 + do { 441 + state12 = meson_cfg_readl(mp, PCIE_CFG_STATUS12); 442 + state17 = meson_cfg_readl(mp, PCIE_CFG_STATUS17); 443 + smlh_up = IS_SMLH_LINK_UP(state12); 444 + rdlh_up = IS_RDLH_LINK_UP(state12); 445 + ltssm_up = IS_LTSSM_UP(state12); 446 + 447 + if (PM_CURRENT_STATE(state17) < PCIE_GEN3) 448 + speed_okay = 1; 449 + 450 + if (smlh_up) 451 + dev_dbg(dev, "smlh_link_up is on\n"); 452 + if (rdlh_up) 453 + dev_dbg(dev, "rdlh_link_up is on\n"); 454 + if (ltssm_up) 455 + dev_dbg(dev, "ltssm_up is on\n"); 456 + if (speed_okay) 457 + dev_dbg(dev, "speed_okay\n"); 458 + 459 + if (smlh_up && rdlh_up && ltssm_up && speed_okay) 460 + return 1; 461 + 462 + cnt++; 463 + 464 + udelay(10); 465 + } while (cnt < WAIT_LINKUP_TIMEOUT); 466 + 467 + dev_err(dev, "error: wait linkup timeout\n"); 468 + return 0; 469 + } 470 + 471 + static int meson_pcie_host_init(struct pcie_port *pp) 472 + { 473 + struct dw_pcie *pci = to_dw_pcie_from_pp(pp); 474 + struct meson_pcie *mp = to_meson_pcie(pci); 475 + int ret; 476 + 477 + ret = meson_pcie_establish_link(mp); 478 + if (ret) 479 + return ret; 480 + 481 + meson_pcie_enable_interrupts(mp); 482 + 483 + return 0; 484 + } 485 + 486 + static const struct dw_pcie_host_ops meson_pcie_host_ops = { 487 + .rd_own_conf = meson_pcie_rd_own_conf, 488 + .wr_own_conf = meson_pcie_wr_own_conf, 489 + .host_init = meson_pcie_host_init, 490 + }; 491 + 492 + static int meson_add_pcie_port(struct meson_pcie *mp, 493 + struct platform_device *pdev) 494 + { 495 + struct dw_pcie *pci = &mp->pci; 496 + struct pcie_port *pp = &pci->pp; 497 + struct device *dev = &pdev->dev; 498 + int ret; 499 + 500 + if (IS_ENABLED(CONFIG_PCI_MSI)) { 501 + pp->msi_irq = platform_get_irq(pdev, 0); 502 + if (pp->msi_irq < 0) { 503 + dev_err(dev, "failed to get MSI IRQ\n"); 504 + return pp->msi_irq; 505 + } 506 + } 507 + 508 + pp->ops = &meson_pcie_host_ops; 509 + pci->dbi_base = mp->mem_res.elbi_base; 510 + 511 + ret = dw_pcie_host_init(pp); 512 + if (ret) { 513 + dev_err(dev, "failed to initialize host\n"); 514 + return ret; 515 + } 516 + 517 + return 0; 518 + } 519 + 520 + static const struct dw_pcie_ops dw_pcie_ops = { 521 + .link_up = meson_pcie_link_up, 522 + }; 523 + 524 + static int meson_pcie_probe(struct platform_device *pdev) 525 + { 526 + struct device *dev = &pdev->dev; 527 + struct dw_pcie *pci; 528 + struct meson_pcie *mp; 529 + int ret; 530 + 531 + mp = devm_kzalloc(dev, sizeof(*mp), GFP_KERNEL); 532 + if (!mp) 533 + return -ENOMEM; 534 + 535 + pci = &mp->pci; 536 + pci->dev = dev; 537 + pci->ops = &dw_pcie_ops; 538 + 539 + mp->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); 540 + if (IS_ERR(mp->reset_gpio)) { 541 + dev_err(dev, "get reset gpio failed\n"); 542 + return PTR_ERR(mp->reset_gpio); 543 + } 544 + 545 + ret = meson_pcie_get_resets(mp); 546 + if (ret) { 547 + dev_err(dev, "get reset resource failed, %d\n", ret); 548 + return ret; 549 + } 550 + 551 + ret = meson_pcie_get_mems(pdev, mp); 552 + if (ret) { 553 + dev_err(dev, "get memory resource failed, %d\n", ret); 554 + return ret; 555 + } 556 + 557 + meson_pcie_power_on(mp); 558 + meson_pcie_reset(mp); 559 + 560 + ret = meson_pcie_probe_clocks(mp); 561 + if (ret) { 562 + dev_err(dev, "init clock resources failed, %d\n", ret); 563 + return ret; 564 + } 565 + 566 + platform_set_drvdata(pdev, mp); 567 + 568 + ret = meson_add_pcie_port(mp, pdev); 569 + if (ret < 0) { 570 + dev_err(dev, "Add PCIe port failed, %d\n", ret); 571 + return ret; 572 + } 573 + 574 + return 0; 575 + } 576 + 577 + static const struct of_device_id meson_pcie_of_match[] = { 578 + { 579 + .compatible = "amlogic,axg-pcie", 580 + }, 581 + {}, 582 + }; 583 + 584 + static struct platform_driver meson_pcie_driver = { 585 + .probe = meson_pcie_probe, 586 + .driver = { 587 + .name = "meson-pcie", 588 + .of_match_table = meson_pcie_of_match, 589 + }, 590 + }; 591 + 592 + builtin_platform_driver(meson_pcie_driver);
+16
drivers/pci/controller/dwc/pcie-armada8k.c
··· 22 22 #include <linux/resource.h> 23 23 #include <linux/of_pci.h> 24 24 #include <linux/of_irq.h> 25 + #include <linux/gpio/consumer.h> 25 26 26 27 #include "pcie-designware.h" 27 28 ··· 30 29 struct dw_pcie *pci; 31 30 struct clk *clk; 32 31 struct clk *clk_reg; 32 + struct gpio_desc *reset_gpio; 33 33 }; 34 34 35 35 #define PCIE_VENDOR_REGS_OFFSET 0x8000 ··· 139 137 struct dw_pcie *pci = to_dw_pcie_from_pp(pp); 140 138 struct armada8k_pcie *pcie = to_armada8k_pcie(pci); 141 139 140 + if (pcie->reset_gpio) { 141 + /* assert and then deassert the reset signal */ 142 + gpiod_set_value_cansleep(pcie->reset_gpio, 1); 143 + msleep(100); 144 + gpiod_set_value_cansleep(pcie->reset_gpio, 0); 145 + } 142 146 dw_pcie_setup_rc(pp); 143 147 armada8k_pcie_establish_link(pcie); 144 148 ··· 254 246 if (IS_ERR(pci->dbi_base)) { 255 247 dev_err(dev, "couldn't remap regs base %p\n", base); 256 248 ret = PTR_ERR(pci->dbi_base); 249 + goto fail_clkreg; 250 + } 251 + 252 + /* Get reset gpio signal and hold asserted (logically high) */ 253 + pcie->reset_gpio = devm_gpiod_get_optional(dev, "reset", 254 + GPIOD_OUT_HIGH); 255 + if (IS_ERR(pcie->reset_gpio)) { 256 + ret = PTR_ERR(pcie->reset_gpio); 257 257 goto fail_clkreg; 258 258 } 259 259
+4
drivers/pci/controller/dwc/pcie-designware-ep.c
··· 503 503 dev_err(dev, "dbi_base/dbi_base2 is not populated\n"); 504 504 return -EINVAL; 505 505 } 506 + if (pci->iatu_unroll_enabled && !pci->atu_base) { 507 + dev_err(dev, "atu_base is not populated\n"); 508 + return -EINVAL; 509 + } 506 510 507 511 ret = of_property_read_u32(np, "num-ib-windows", &ep->num_ib_windows); 508 512 if (ret < 0) {
+27 -13
drivers/pci/controller/dwc/pcie-designware-host.c
··· 99 99 (i * MAX_MSI_IRQS_PER_CTRL) + 100 100 pos); 101 101 generic_handle_irq(irq); 102 - dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_STATUS + 103 - (i * MSI_REG_CTRL_BLOCK_SIZE), 104 - 4, 1 << pos); 105 102 pos++; 106 103 } 107 104 } ··· 165 168 bit = data->hwirq % MAX_MSI_IRQS_PER_CTRL; 166 169 167 170 pp->irq_status[ctrl] &= ~(1 << bit); 168 - dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, 169 - pp->irq_status[ctrl]); 171 + dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_MASK + res, 4, 172 + ~pp->irq_status[ctrl]); 170 173 } 171 174 172 175 raw_spin_unlock_irqrestore(&pp->lock, flags); ··· 188 191 bit = data->hwirq % MAX_MSI_IRQS_PER_CTRL; 189 192 190 193 pp->irq_status[ctrl] |= 1 << bit; 191 - dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, 192 - pp->irq_status[ctrl]); 194 + dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_MASK + res, 4, 195 + ~pp->irq_status[ctrl]); 193 196 } 194 197 195 198 raw_spin_unlock_irqrestore(&pp->lock, flags); ··· 197 200 198 201 static void dw_pci_bottom_ack(struct irq_data *d) 199 202 { 200 - struct msi_desc *msi = irq_data_get_msi_desc(d); 201 - struct pcie_port *pp; 203 + struct pcie_port *pp = irq_data_get_irq_chip_data(d); 204 + unsigned int res, bit, ctrl; 205 + unsigned long flags; 202 206 203 - pp = msi_desc_to_pci_sysdata(msi); 207 + ctrl = d->hwirq / MAX_MSI_IRQS_PER_CTRL; 208 + res = ctrl * MSI_REG_CTRL_BLOCK_SIZE; 209 + bit = d->hwirq % MAX_MSI_IRQS_PER_CTRL; 210 + 211 + raw_spin_lock_irqsave(&pp->lock, flags); 212 + 213 + dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_STATUS + res, 4, 1 << bit); 204 214 205 215 if (pp->ops->msi_irq_ack) 206 216 pp->ops->msi_irq_ack(d->hwirq, pp); 217 + 218 + raw_spin_unlock_irqrestore(&pp->lock, flags); 207 219 } 208 220 209 221 static struct irq_chip dw_pci_msi_bottom_irq_chip = { ··· 664 658 num_ctrls = pp->num_vectors / MAX_MSI_IRQS_PER_CTRL; 665 659 666 660 /* Initialize IRQ Status array */ 667 - for (ctrl = 0; ctrl < num_ctrls; ctrl++) 668 - dw_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_ENABLE + 661 + for (ctrl = 0; ctrl < num_ctrls; ctrl++) { 662 + dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_MASK + 669 663 (ctrl * MSI_REG_CTRL_BLOCK_SIZE), 670 - 4, &pp->irq_status[ctrl]); 664 + 4, ~0); 665 + dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + 666 + (ctrl * MSI_REG_CTRL_BLOCK_SIZE), 667 + 4, ~0); 668 + pp->irq_status[ctrl] = 0; 669 + } 671 670 672 671 /* Setup RC BARs */ 673 672 dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_0, 0x00000004); ··· 709 698 pci->iatu_unroll_enabled = dw_pcie_iatu_unroll_enabled(pci); 710 699 dev_dbg(pci->dev, "iATU unroll: %s\n", 711 700 pci->iatu_unroll_enabled ? "enabled" : "disabled"); 701 + 702 + if (pci->iatu_unroll_enabled && !pci->atu_base) 703 + pci->atu_base = pci->dbi_base + DEFAULT_DBI_ATU_OFFSET; 712 704 713 705 dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX0, 714 706 PCIE_ATU_TYPE_MEM, pp->mem_base,
+4 -4
drivers/pci/controller/dwc/pcie-designware.c
··· 93 93 { 94 94 u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index); 95 95 96 - return dw_pcie_readl_dbi(pci, offset + reg); 96 + return dw_pcie_readl_atu(pci, offset + reg); 97 97 } 98 98 99 99 static void dw_pcie_writel_ob_unroll(struct dw_pcie *pci, u32 index, u32 reg, ··· 101 101 { 102 102 u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index); 103 103 104 - dw_pcie_writel_dbi(pci, offset + reg, val); 104 + dw_pcie_writel_atu(pci, offset + reg, val); 105 105 } 106 106 107 107 static void dw_pcie_prog_outbound_atu_unroll(struct dw_pcie *pci, int index, ··· 187 187 { 188 188 u32 offset = PCIE_GET_ATU_INB_UNR_REG_OFFSET(index); 189 189 190 - return dw_pcie_readl_dbi(pci, offset + reg); 190 + return dw_pcie_readl_atu(pci, offset + reg); 191 191 } 192 192 193 193 static void dw_pcie_writel_ib_unroll(struct dw_pcie *pci, u32 index, u32 reg, ··· 195 195 { 196 196 u32 offset = PCIE_GET_ATU_INB_UNR_REG_OFFSET(index); 197 197 198 - dw_pcie_writel_dbi(pci, offset + reg, val); 198 + dw_pcie_writel_atu(pci, offset + reg, val); 199 199 } 200 200 201 201 static int dw_pcie_prog_inbound_atu_unroll(struct dw_pcie *pci, int index,
+25 -5
drivers/pci/controller/dwc/pcie-designware.h
··· 92 92 #define PCIE_ATU_UNR_LOWER_TARGET 0x14 93 93 #define PCIE_ATU_UNR_UPPER_TARGET 0x18 94 94 95 - /* Register address builder */ 96 - #define PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(region) \ 97 - ((0x3 << 20) | ((region) << 9)) 95 + /* 96 + * The default address offset between dbi_base and atu_base. Root controller 97 + * drivers are not required to initialize atu_base if the offset matches this 98 + * default; the driver core automatically derives atu_base from dbi_base using 99 + * this offset, if atu_base not set. 100 + */ 101 + #define DEFAULT_DBI_ATU_OFFSET (0x3 << 20) 98 102 99 - #define PCIE_GET_ATU_INB_UNR_REG_OFFSET(region) \ 100 - ((0x3 << 20) | ((region) << 9) | (0x1 << 8)) 103 + /* Register address builder */ 104 + #define PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(region) \ 105 + ((region) << 9) 106 + 107 + #define PCIE_GET_ATU_INB_UNR_REG_OFFSET(region) \ 108 + (((region) << 9) | (0x1 << 8)) 101 109 102 110 #define MAX_MSI_IRQS 256 103 111 #define MAX_MSI_IRQS_PER_CTRL 32 ··· 227 219 struct device *dev; 228 220 void __iomem *dbi_base; 229 221 void __iomem *dbi_base2; 222 + /* Used when iatu_unroll_enabled is true */ 223 + void __iomem *atu_base; 230 224 u32 num_viewport; 231 225 u8 iatu_unroll_enabled; 232 226 struct pcie_port pp; ··· 297 287 static inline u32 dw_pcie_readl_dbi2(struct dw_pcie *pci, u32 reg) 298 288 { 299 289 return __dw_pcie_read_dbi(pci, pci->dbi_base2, reg, 0x4); 290 + } 291 + 292 + static inline void dw_pcie_writel_atu(struct dw_pcie *pci, u32 reg, u32 val) 293 + { 294 + __dw_pcie_write_dbi(pci, pci->atu_base, reg, 0x4, val); 295 + } 296 + 297 + static inline u32 dw_pcie_readl_atu(struct dw_pcie *pci, u32 reg) 298 + { 299 + return __dw_pcie_read_dbi(pci, pci->atu_base, reg, 0x4); 300 300 } 301 301 302 302 static inline void dw_pcie_dbi_ro_wr_en(struct dw_pcie *pci)
+1 -1
drivers/pci/controller/dwc/pcie-histb.c
··· 202 202 return 0; 203 203 } 204 204 205 - static struct dw_pcie_host_ops histb_pcie_host_ops = { 205 + static const struct dw_pcie_host_ops histb_pcie_host_ops = { 206 206 .rd_own_conf = histb_pcie_rd_own_conf, 207 207 .wr_own_conf = histb_pcie_wr_own_conf, 208 208 .host_init = histb_pcie_host_init,
+471
drivers/pci/controller/dwc/pcie-uniphier.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * PCIe host controller driver for UniPhier SoCs 4 + * Copyright 2018 Socionext Inc. 5 + * Author: Kunihiko Hayashi <hayashi.kunihiko@socionext.com> 6 + */ 7 + 8 + #include <linux/bitops.h> 9 + #include <linux/bitfield.h> 10 + #include <linux/clk.h> 11 + #include <linux/delay.h> 12 + #include <linux/interrupt.h> 13 + #include <linux/iopoll.h> 14 + #include <linux/irqchip/chained_irq.h> 15 + #include <linux/irqdomain.h> 16 + #include <linux/module.h> 17 + #include <linux/of_irq.h> 18 + #include <linux/pci.h> 19 + #include <linux/phy/phy.h> 20 + #include <linux/platform_device.h> 21 + #include <linux/reset.h> 22 + 23 + #include "pcie-designware.h" 24 + 25 + #define PCL_PINCTRL0 0x002c 26 + #define PCL_PERST_PLDN_REGEN BIT(12) 27 + #define PCL_PERST_NOE_REGEN BIT(11) 28 + #define PCL_PERST_OUT_REGEN BIT(8) 29 + #define PCL_PERST_PLDN_REGVAL BIT(4) 30 + #define PCL_PERST_NOE_REGVAL BIT(3) 31 + #define PCL_PERST_OUT_REGVAL BIT(0) 32 + 33 + #define PCL_PIPEMON 0x0044 34 + #define PCL_PCLK_ALIVE BIT(15) 35 + 36 + #define PCL_APP_READY_CTRL 0x8008 37 + #define PCL_APP_LTSSM_ENABLE BIT(0) 38 + 39 + #define PCL_APP_PM0 0x8078 40 + #define PCL_SYS_AUX_PWR_DET BIT(8) 41 + 42 + #define PCL_RCV_INT 0x8108 43 + #define PCL_RCV_INT_ALL_ENABLE GENMASK(20, 17) 44 + #define PCL_CFG_BW_MGT_STATUS BIT(4) 45 + #define PCL_CFG_LINK_AUTO_BW_STATUS BIT(3) 46 + #define PCL_CFG_AER_RC_ERR_MSI_STATUS BIT(2) 47 + #define PCL_CFG_PME_MSI_STATUS BIT(1) 48 + 49 + #define PCL_RCV_INTX 0x810c 50 + #define PCL_RCV_INTX_ALL_ENABLE GENMASK(19, 16) 51 + #define PCL_RCV_INTX_ALL_MASK GENMASK(11, 8) 52 + #define PCL_RCV_INTX_MASK_SHIFT 8 53 + #define PCL_RCV_INTX_ALL_STATUS GENMASK(3, 0) 54 + #define PCL_RCV_INTX_STATUS_SHIFT 0 55 + 56 + #define PCL_STATUS_LINK 0x8140 57 + #define PCL_RDLH_LINK_UP BIT(1) 58 + #define PCL_XMLH_LINK_UP BIT(0) 59 + 60 + struct uniphier_pcie_priv { 61 + void __iomem *base; 62 + struct dw_pcie pci; 63 + struct clk *clk; 64 + struct reset_control *rst; 65 + struct phy *phy; 66 + struct irq_domain *legacy_irq_domain; 67 + }; 68 + 69 + #define to_uniphier_pcie(x) dev_get_drvdata((x)->dev) 70 + 71 + static void uniphier_pcie_ltssm_enable(struct uniphier_pcie_priv *priv, 72 + bool enable) 73 + { 74 + u32 val; 75 + 76 + val = readl(priv->base + PCL_APP_READY_CTRL); 77 + if (enable) 78 + val |= PCL_APP_LTSSM_ENABLE; 79 + else 80 + val &= ~PCL_APP_LTSSM_ENABLE; 81 + writel(val, priv->base + PCL_APP_READY_CTRL); 82 + } 83 + 84 + static void uniphier_pcie_init_rc(struct uniphier_pcie_priv *priv) 85 + { 86 + u32 val; 87 + 88 + /* use auxiliary power detection */ 89 + val = readl(priv->base + PCL_APP_PM0); 90 + val |= PCL_SYS_AUX_PWR_DET; 91 + writel(val, priv->base + PCL_APP_PM0); 92 + 93 + /* assert PERST# */ 94 + val = readl(priv->base + PCL_PINCTRL0); 95 + val &= ~(PCL_PERST_NOE_REGVAL | PCL_PERST_OUT_REGVAL 96 + | PCL_PERST_PLDN_REGVAL); 97 + val |= PCL_PERST_NOE_REGEN | PCL_PERST_OUT_REGEN 98 + | PCL_PERST_PLDN_REGEN; 99 + writel(val, priv->base + PCL_PINCTRL0); 100 + 101 + uniphier_pcie_ltssm_enable(priv, false); 102 + 103 + usleep_range(100000, 200000); 104 + 105 + /* deassert PERST# */ 106 + val = readl(priv->base + PCL_PINCTRL0); 107 + val |= PCL_PERST_OUT_REGVAL | PCL_PERST_OUT_REGEN; 108 + writel(val, priv->base + PCL_PINCTRL0); 109 + } 110 + 111 + static int uniphier_pcie_wait_rc(struct uniphier_pcie_priv *priv) 112 + { 113 + u32 status; 114 + int ret; 115 + 116 + /* wait PIPE clock */ 117 + ret = readl_poll_timeout(priv->base + PCL_PIPEMON, status, 118 + status & PCL_PCLK_ALIVE, 100000, 1000000); 119 + if (ret) { 120 + dev_err(priv->pci.dev, 121 + "Failed to initialize controller in RC mode\n"); 122 + return ret; 123 + } 124 + 125 + return 0; 126 + } 127 + 128 + static int uniphier_pcie_link_up(struct dw_pcie *pci) 129 + { 130 + struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci); 131 + u32 val, mask; 132 + 133 + val = readl(priv->base + PCL_STATUS_LINK); 134 + mask = PCL_RDLH_LINK_UP | PCL_XMLH_LINK_UP; 135 + 136 + return (val & mask) == mask; 137 + } 138 + 139 + static int uniphier_pcie_establish_link(struct dw_pcie *pci) 140 + { 141 + struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci); 142 + 143 + if (dw_pcie_link_up(pci)) 144 + return 0; 145 + 146 + uniphier_pcie_ltssm_enable(priv, true); 147 + 148 + return dw_pcie_wait_for_link(pci); 149 + } 150 + 151 + static void uniphier_pcie_stop_link(struct dw_pcie *pci) 152 + { 153 + struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci); 154 + 155 + uniphier_pcie_ltssm_enable(priv, false); 156 + } 157 + 158 + static void uniphier_pcie_irq_enable(struct uniphier_pcie_priv *priv) 159 + { 160 + writel(PCL_RCV_INT_ALL_ENABLE, priv->base + PCL_RCV_INT); 161 + writel(PCL_RCV_INTX_ALL_ENABLE, priv->base + PCL_RCV_INTX); 162 + } 163 + 164 + static void uniphier_pcie_irq_disable(struct uniphier_pcie_priv *priv) 165 + { 166 + writel(0, priv->base + PCL_RCV_INT); 167 + writel(0, priv->base + PCL_RCV_INTX); 168 + } 169 + 170 + static void uniphier_pcie_irq_ack(struct irq_data *d) 171 + { 172 + struct pcie_port *pp = irq_data_get_irq_chip_data(d); 173 + struct dw_pcie *pci = to_dw_pcie_from_pp(pp); 174 + struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci); 175 + u32 val; 176 + 177 + val = readl(priv->base + PCL_RCV_INTX); 178 + val &= ~PCL_RCV_INTX_ALL_STATUS; 179 + val |= BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_STATUS_SHIFT); 180 + writel(val, priv->base + PCL_RCV_INTX); 181 + } 182 + 183 + static void uniphier_pcie_irq_mask(struct irq_data *d) 184 + { 185 + struct pcie_port *pp = irq_data_get_irq_chip_data(d); 186 + struct dw_pcie *pci = to_dw_pcie_from_pp(pp); 187 + struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci); 188 + u32 val; 189 + 190 + val = readl(priv->base + PCL_RCV_INTX); 191 + val &= ~PCL_RCV_INTX_ALL_MASK; 192 + val |= BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_MASK_SHIFT); 193 + writel(val, priv->base + PCL_RCV_INTX); 194 + } 195 + 196 + static void uniphier_pcie_irq_unmask(struct irq_data *d) 197 + { 198 + struct pcie_port *pp = irq_data_get_irq_chip_data(d); 199 + struct dw_pcie *pci = to_dw_pcie_from_pp(pp); 200 + struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci); 201 + u32 val; 202 + 203 + val = readl(priv->base + PCL_RCV_INTX); 204 + val &= ~PCL_RCV_INTX_ALL_MASK; 205 + val &= ~BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_MASK_SHIFT); 206 + writel(val, priv->base + PCL_RCV_INTX); 207 + } 208 + 209 + static struct irq_chip uniphier_pcie_irq_chip = { 210 + .name = "PCI", 211 + .irq_ack = uniphier_pcie_irq_ack, 212 + .irq_mask = uniphier_pcie_irq_mask, 213 + .irq_unmask = uniphier_pcie_irq_unmask, 214 + }; 215 + 216 + static int uniphier_pcie_intx_map(struct irq_domain *domain, unsigned int irq, 217 + irq_hw_number_t hwirq) 218 + { 219 + irq_set_chip_and_handler(irq, &uniphier_pcie_irq_chip, 220 + handle_level_irq); 221 + irq_set_chip_data(irq, domain->host_data); 222 + 223 + return 0; 224 + } 225 + 226 + static const struct irq_domain_ops uniphier_intx_domain_ops = { 227 + .map = uniphier_pcie_intx_map, 228 + }; 229 + 230 + static void uniphier_pcie_irq_handler(struct irq_desc *desc) 231 + { 232 + struct pcie_port *pp = irq_desc_get_handler_data(desc); 233 + struct dw_pcie *pci = to_dw_pcie_from_pp(pp); 234 + struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci); 235 + struct irq_chip *chip = irq_desc_get_chip(desc); 236 + unsigned long reg; 237 + u32 val, bit, virq; 238 + 239 + /* INT for debug */ 240 + val = readl(priv->base + PCL_RCV_INT); 241 + 242 + if (val & PCL_CFG_BW_MGT_STATUS) 243 + dev_dbg(pci->dev, "Link Bandwidth Management Event\n"); 244 + if (val & PCL_CFG_LINK_AUTO_BW_STATUS) 245 + dev_dbg(pci->dev, "Link Autonomous Bandwidth Event\n"); 246 + if (val & PCL_CFG_AER_RC_ERR_MSI_STATUS) 247 + dev_dbg(pci->dev, "Root Error\n"); 248 + if (val & PCL_CFG_PME_MSI_STATUS) 249 + dev_dbg(pci->dev, "PME Interrupt\n"); 250 + 251 + writel(val, priv->base + PCL_RCV_INT); 252 + 253 + /* INTx */ 254 + chained_irq_enter(chip, desc); 255 + 256 + val = readl(priv->base + PCL_RCV_INTX); 257 + reg = FIELD_GET(PCL_RCV_INTX_ALL_STATUS, val); 258 + 259 + for_each_set_bit(bit, &reg, PCI_NUM_INTX) { 260 + virq = irq_linear_revmap(priv->legacy_irq_domain, bit); 261 + generic_handle_irq(virq); 262 + } 263 + 264 + chained_irq_exit(chip, desc); 265 + } 266 + 267 + static int uniphier_pcie_config_legacy_irq(struct pcie_port *pp) 268 + { 269 + struct dw_pcie *pci = to_dw_pcie_from_pp(pp); 270 + struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci); 271 + struct device_node *np = pci->dev->of_node; 272 + struct device_node *np_intc; 273 + 274 + np_intc = of_get_child_by_name(np, "legacy-interrupt-controller"); 275 + if (!np_intc) { 276 + dev_err(pci->dev, "Failed to get legacy-interrupt-controller node\n"); 277 + return -EINVAL; 278 + } 279 + 280 + pp->irq = irq_of_parse_and_map(np_intc, 0); 281 + if (!pp->irq) { 282 + dev_err(pci->dev, "Failed to get an IRQ entry in legacy-interrupt-controller\n"); 283 + return -EINVAL; 284 + } 285 + 286 + priv->legacy_irq_domain = irq_domain_add_linear(np_intc, PCI_NUM_INTX, 287 + &uniphier_intx_domain_ops, pp); 288 + if (!priv->legacy_irq_domain) { 289 + dev_err(pci->dev, "Failed to get INTx domain\n"); 290 + return -ENODEV; 291 + } 292 + 293 + irq_set_chained_handler_and_data(pp->irq, uniphier_pcie_irq_handler, 294 + pp); 295 + 296 + return 0; 297 + } 298 + 299 + static int uniphier_pcie_host_init(struct pcie_port *pp) 300 + { 301 + struct dw_pcie *pci = to_dw_pcie_from_pp(pp); 302 + struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci); 303 + int ret; 304 + 305 + ret = uniphier_pcie_config_legacy_irq(pp); 306 + if (ret) 307 + return ret; 308 + 309 + uniphier_pcie_irq_enable(priv); 310 + 311 + dw_pcie_setup_rc(pp); 312 + ret = uniphier_pcie_establish_link(pci); 313 + if (ret) 314 + return ret; 315 + 316 + if (IS_ENABLED(CONFIG_PCI_MSI)) 317 + dw_pcie_msi_init(pp); 318 + 319 + return 0; 320 + } 321 + 322 + static const struct dw_pcie_host_ops uniphier_pcie_host_ops = { 323 + .host_init = uniphier_pcie_host_init, 324 + }; 325 + 326 + static int uniphier_add_pcie_port(struct uniphier_pcie_priv *priv, 327 + struct platform_device *pdev) 328 + { 329 + struct dw_pcie *pci = &priv->pci; 330 + struct pcie_port *pp = &pci->pp; 331 + struct device *dev = &pdev->dev; 332 + int ret; 333 + 334 + pp->ops = &uniphier_pcie_host_ops; 335 + 336 + if (IS_ENABLED(CONFIG_PCI_MSI)) { 337 + pp->msi_irq = platform_get_irq_byname(pdev, "msi"); 338 + if (pp->msi_irq < 0) 339 + return pp->msi_irq; 340 + } 341 + 342 + ret = dw_pcie_host_init(pp); 343 + if (ret) { 344 + dev_err(dev, "Failed to initialize host (%d)\n", ret); 345 + return ret; 346 + } 347 + 348 + return 0; 349 + } 350 + 351 + static int uniphier_pcie_host_enable(struct uniphier_pcie_priv *priv) 352 + { 353 + int ret; 354 + 355 + ret = clk_prepare_enable(priv->clk); 356 + if (ret) 357 + return ret; 358 + 359 + ret = reset_control_deassert(priv->rst); 360 + if (ret) 361 + goto out_clk_disable; 362 + 363 + uniphier_pcie_init_rc(priv); 364 + 365 + ret = phy_init(priv->phy); 366 + if (ret) 367 + goto out_rst_assert; 368 + 369 + ret = uniphier_pcie_wait_rc(priv); 370 + if (ret) 371 + goto out_phy_exit; 372 + 373 + return 0; 374 + 375 + out_phy_exit: 376 + phy_exit(priv->phy); 377 + out_rst_assert: 378 + reset_control_assert(priv->rst); 379 + out_clk_disable: 380 + clk_disable_unprepare(priv->clk); 381 + 382 + return ret; 383 + } 384 + 385 + static void uniphier_pcie_host_disable(struct uniphier_pcie_priv *priv) 386 + { 387 + uniphier_pcie_irq_disable(priv); 388 + phy_exit(priv->phy); 389 + reset_control_assert(priv->rst); 390 + clk_disable_unprepare(priv->clk); 391 + } 392 + 393 + static const struct dw_pcie_ops dw_pcie_ops = { 394 + .start_link = uniphier_pcie_establish_link, 395 + .stop_link = uniphier_pcie_stop_link, 396 + .link_up = uniphier_pcie_link_up, 397 + }; 398 + 399 + static int uniphier_pcie_probe(struct platform_device *pdev) 400 + { 401 + struct device *dev = &pdev->dev; 402 + struct uniphier_pcie_priv *priv; 403 + struct resource *res; 404 + int ret; 405 + 406 + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 407 + if (!priv) 408 + return -ENOMEM; 409 + 410 + priv->pci.dev = dev; 411 + priv->pci.ops = &dw_pcie_ops; 412 + 413 + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi"); 414 + priv->pci.dbi_base = devm_pci_remap_cfg_resource(dev, res); 415 + if (IS_ERR(priv->pci.dbi_base)) 416 + return PTR_ERR(priv->pci.dbi_base); 417 + 418 + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "link"); 419 + priv->base = devm_ioremap_resource(dev, res); 420 + if (IS_ERR(priv->base)) 421 + return PTR_ERR(priv->base); 422 + 423 + priv->clk = devm_clk_get(dev, NULL); 424 + if (IS_ERR(priv->clk)) 425 + return PTR_ERR(priv->clk); 426 + 427 + priv->rst = devm_reset_control_get_shared(dev, NULL); 428 + if (IS_ERR(priv->rst)) 429 + return PTR_ERR(priv->rst); 430 + 431 + priv->phy = devm_phy_optional_get(dev, "pcie-phy"); 432 + if (IS_ERR(priv->phy)) 433 + return PTR_ERR(priv->phy); 434 + 435 + platform_set_drvdata(pdev, priv); 436 + 437 + ret = uniphier_pcie_host_enable(priv); 438 + if (ret) 439 + return ret; 440 + 441 + return uniphier_add_pcie_port(priv, pdev); 442 + } 443 + 444 + static int uniphier_pcie_remove(struct platform_device *pdev) 445 + { 446 + struct uniphier_pcie_priv *priv = platform_get_drvdata(pdev); 447 + 448 + uniphier_pcie_host_disable(priv); 449 + 450 + return 0; 451 + } 452 + 453 + static const struct of_device_id uniphier_pcie_match[] = { 454 + { .compatible = "socionext,uniphier-pcie", }, 455 + { /* sentinel */ }, 456 + }; 457 + MODULE_DEVICE_TABLE(of, uniphier_pcie_match); 458 + 459 + static struct platform_driver uniphier_pcie_driver = { 460 + .probe = uniphier_pcie_probe, 461 + .remove = uniphier_pcie_remove, 462 + .driver = { 463 + .name = "uniphier-pcie", 464 + .of_match_table = uniphier_pcie_match, 465 + }, 466 + }; 467 + builtin_platform_driver(uniphier_pcie_driver); 468 + 469 + MODULE_AUTHOR("Kunihiko Hayashi <hayashi.kunihiko@socionext.com>"); 470 + MODULE_DESCRIPTION("UniPhier PCIe host controller driver"); 471 + MODULE_LICENSE("GPL v2");
+27 -82
drivers/pci/controller/pcie-mediatek.c
··· 161 161 * @obff_ck: pointer to OBFF functional block operating clock 162 162 * @pipe_ck: pointer to LTSSM and PHY/MAC layer operating clock 163 163 * @phy: pointer to PHY control block 164 - * @lane: lane count 165 164 * @slot: port slot 166 165 * @irq: GIC irq 167 166 * @irq_domain: legacy INTx IRQ domain ··· 181 182 struct clk *obff_ck; 182 183 struct clk *pipe_ck; 183 184 struct phy *phy; 184 - u32 lane; 185 185 u32 slot; 186 186 int irq; 187 187 struct irq_domain *irq_domain; ··· 195 197 * @dev: pointer to PCIe device 196 198 * @base: IO mapped register base 197 199 * @free_ck: free-run reference clock 198 - * @io: IO resource 199 - * @pio: PIO resource 200 200 * @mem: non-prefetchable memory resource 201 - * @busn: bus range 202 - * @offset: IO / Memory offset 203 201 * @ports: pointer to PCIe port information 204 202 * @soc: pointer to SoC-dependent operations 203 + * @busnr: root bus number 205 204 */ 206 205 struct mtk_pcie { 207 206 struct device *dev; 208 207 void __iomem *base; 209 208 struct clk *free_ck; 210 209 211 - struct resource io; 212 - struct resource pio; 213 210 struct resource mem; 214 - struct resource busn; 215 - struct { 216 - resource_size_t mem; 217 - resource_size_t io; 218 - } offset; 219 211 struct list_head ports; 220 212 const struct mtk_pcie_soc *soc; 213 + unsigned int busnr; 221 214 }; 222 215 223 216 static void mtk_pcie_subsys_powerdown(struct mtk_pcie *pcie) ··· 893 904 if (!port) 894 905 return -ENOMEM; 895 906 896 - err = of_property_read_u32(node, "num-lanes", &port->lane); 897 - if (err) { 898 - dev_err(dev, "missing num-lanes property\n"); 899 - return err; 900 - } 901 - 902 907 snprintf(name, sizeof(name), "port%d", slot); 903 908 regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); 904 909 port->base = devm_ioremap_resource(dev, regs); ··· 1028 1045 { 1029 1046 struct device *dev = pcie->dev; 1030 1047 struct device_node *node = dev->of_node, *child; 1031 - struct of_pci_range_parser parser; 1032 - struct of_pci_range range; 1033 - struct resource res; 1034 1048 struct mtk_pcie_port *port, *tmp; 1049 + struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie); 1050 + struct list_head *windows = &host->windows; 1051 + struct resource_entry *win, *tmp_win; 1052 + resource_size_t io_base; 1035 1053 int err; 1036 1054 1037 - if (of_pci_range_parser_init(&parser, node)) { 1038 - dev_err(dev, "missing \"ranges\" property\n"); 1039 - return -EINVAL; 1040 - } 1055 + err = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff, 1056 + windows, &io_base); 1057 + if (err) 1058 + return err; 1041 1059 1042 - for_each_of_pci_range(&parser, &range) { 1043 - err = of_pci_range_to_resource(&range, node, &res); 1044 - if (err < 0) 1045 - return err; 1060 + err = devm_request_pci_bus_resources(dev, windows); 1061 + if (err < 0) 1062 + return err; 1046 1063 1047 - switch (res.flags & IORESOURCE_TYPE_BITS) { 1064 + /* Get the I/O and memory ranges from DT */ 1065 + resource_list_for_each_entry_safe(win, tmp_win, windows) { 1066 + switch (resource_type(win->res)) { 1048 1067 case IORESOURCE_IO: 1049 - pcie->offset.io = res.start - range.pci_addr; 1050 - 1051 - memcpy(&pcie->pio, &res, sizeof(res)); 1052 - pcie->pio.name = node->full_name; 1053 - 1054 - pcie->io.start = range.cpu_addr; 1055 - pcie->io.end = range.cpu_addr + range.size - 1; 1056 - pcie->io.flags = IORESOURCE_MEM; 1057 - pcie->io.name = "I/O"; 1058 - 1059 - memcpy(&res, &pcie->io, sizeof(res)); 1068 + err = devm_pci_remap_iospace(dev, win->res, io_base); 1069 + if (err) { 1070 + dev_warn(dev, "error %d: failed to map resource %pR\n", 1071 + err, win->res); 1072 + resource_list_destroy_entry(win); 1073 + } 1060 1074 break; 1061 - 1062 1075 case IORESOURCE_MEM: 1063 - pcie->offset.mem = res.start - range.pci_addr; 1064 - 1065 - memcpy(&pcie->mem, &res, sizeof(res)); 1076 + memcpy(&pcie->mem, win->res, sizeof(*win->res)); 1066 1077 pcie->mem.name = "non-prefetchable"; 1067 1078 break; 1079 + case IORESOURCE_BUS: 1080 + pcie->busnr = win->res->start; 1081 + break; 1068 1082 } 1069 - } 1070 - 1071 - err = of_pci_parse_bus_range(node, &pcie->busn); 1072 - if (err < 0) { 1073 - dev_err(dev, "failed to parse bus ranges property: %d\n", err); 1074 - pcie->busn.name = node->name; 1075 - pcie->busn.start = 0; 1076 - pcie->busn.end = 0xff; 1077 - pcie->busn.flags = IORESOURCE_BUS; 1078 1083 } 1079 1084 1080 1085 for_each_available_child_of_node(node, child) { ··· 1096 1125 return 0; 1097 1126 } 1098 1127 1099 - static int mtk_pcie_request_resources(struct mtk_pcie *pcie) 1100 - { 1101 - struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie); 1102 - struct list_head *windows = &host->windows; 1103 - struct device *dev = pcie->dev; 1104 - int err; 1105 - 1106 - pci_add_resource_offset(windows, &pcie->pio, pcie->offset.io); 1107 - pci_add_resource_offset(windows, &pcie->mem, pcie->offset.mem); 1108 - pci_add_resource(windows, &pcie->busn); 1109 - 1110 - err = devm_request_pci_bus_resources(dev, windows); 1111 - if (err < 0) 1112 - return err; 1113 - 1114 - err = devm_pci_remap_iospace(dev, &pcie->pio, pcie->io.start); 1115 - if (err) 1116 - return err; 1117 - 1118 - return 0; 1119 - } 1120 - 1121 1128 static int mtk_pcie_probe(struct platform_device *pdev) 1122 1129 { 1123 1130 struct device *dev = &pdev->dev; ··· 1118 1169 if (err) 1119 1170 return err; 1120 1171 1121 - err = mtk_pcie_request_resources(pcie); 1122 - if (err) 1123 - goto put_resources; 1124 - 1125 - host->busnr = pcie->busn.start; 1172 + host->busnr = pcie->busnr; 1126 1173 host->dev.parent = pcie->dev; 1127 1174 host->ops = pcie->soc->ops; 1128 1175 host->map_irq = of_irq_parse_and_map_pci;
+37 -13
drivers/pci/iov.c
··· 252 252 return 0; 253 253 } 254 254 255 + static int sriov_add_vfs(struct pci_dev *dev, u16 num_vfs) 256 + { 257 + unsigned int i; 258 + int rc; 259 + 260 + if (dev->no_vf_scan) 261 + return 0; 262 + 263 + for (i = 0; i < num_vfs; i++) { 264 + rc = pci_iov_add_virtfn(dev, i); 265 + if (rc) 266 + goto failed; 267 + } 268 + return 0; 269 + failed: 270 + while (i--) 271 + pci_iov_remove_virtfn(dev, i); 272 + 273 + return rc; 274 + } 275 + 255 276 static int sriov_enable(struct pci_dev *dev, int nr_virtfn) 256 277 { 257 278 int rc; ··· 358 337 msleep(100); 359 338 pci_cfg_access_unlock(dev); 360 339 361 - for (i = 0; i < initial; i++) { 362 - rc = pci_iov_add_virtfn(dev, i); 363 - if (rc) 364 - goto failed; 365 - } 340 + rc = sriov_add_vfs(dev, initial); 341 + if (rc) 342 + goto err_pcibios; 366 343 367 344 kobject_uevent(&dev->dev.kobj, KOBJ_CHANGE); 368 345 iov->num_VFs = nr_virtfn; 369 346 370 347 return 0; 371 - 372 - failed: 373 - while (i--) 374 - pci_iov_remove_virtfn(dev, i); 375 348 376 349 err_pcibios: 377 350 iov->ctrl &= ~(PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE); ··· 383 368 return rc; 384 369 } 385 370 371 + static void sriov_del_vfs(struct pci_dev *dev) 372 + { 373 + struct pci_sriov *iov = dev->sriov; 374 + int i; 375 + 376 + if (dev->no_vf_scan) 377 + return; 378 + 379 + for (i = 0; i < iov->num_VFs; i++) 380 + pci_iov_remove_virtfn(dev, i); 381 + } 382 + 386 383 static void sriov_disable(struct pci_dev *dev) 387 384 { 388 - int i; 389 385 struct pci_sriov *iov = dev->sriov; 390 386 391 387 if (!iov->num_VFs) 392 388 return; 393 389 394 - for (i = 0; i < iov->num_VFs; i++) 395 - pci_iov_remove_virtfn(dev, i); 396 - 390 + sriov_del_vfs(dev); 397 391 iov->ctrl &= ~(PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE); 398 392 pci_cfg_access_lock(dev); 399 393 pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
+7 -7
drivers/pci/p2pdma.c
··· 416 416 * 417 417 * Returns -1 if any of the clients are not compatible (behind the same 418 418 * root port as the provider), otherwise returns a positive number where 419 - * a lower number is the preferrable choice. (If there's one client 419 + * a lower number is the preferable choice. (If there's one client 420 420 * that's the same as the provider it will return 0, which is best choice). 421 421 * 422 422 * For now, "compatible" means the provider and the clients are all behind ··· 487 487 * @num_clients: number of client devices in the list 488 488 * 489 489 * If multiple devices are behind the same switch, the one "closest" to the 490 - * client devices in use will be chosen first. (So if one of the providers are 490 + * client devices in use will be chosen first. (So if one of the providers is 491 491 * the same as one of the clients, that provider will be used ahead of any 492 492 * other providers that are unrelated). If multiple providers are an equal 493 493 * distance away, one will be chosen at random. ··· 574 574 * pci_free_p2pmem - free peer-to-peer DMA memory 575 575 * @pdev: the device the memory was allocated from 576 576 * @addr: address of the memory that was allocated 577 - * @size: number of bytes that was allocated 577 + * @size: number of bytes that were allocated 578 578 */ 579 579 void pci_free_p2pmem(struct pci_dev *pdev, void *addr, size_t size) 580 580 { ··· 611 611 * @nents: the number of SG entries in the list 612 612 * @length: number of bytes to allocate 613 613 * 614 - * Returns 0 on success 614 + * Return: %NULL on error or &struct scatterlist pointer and @nents on success 615 615 */ 616 616 struct scatterlist *pci_p2pmem_alloc_sgl(struct pci_dev *pdev, 617 617 unsigned int *nents, u32 length) ··· 667 667 * 668 668 * Published memory can be used by other PCI device drivers for 669 669 * peer-2-peer DMA operations. Non-published memory is reserved for 670 - * exlusive use of the device driver that registers the peer-to-peer 670 + * exclusive use of the device driver that registers the peer-to-peer 671 671 * memory. 672 672 */ 673 673 void pci_p2pmem_publish(struct pci_dev *pdev, bool publish) ··· 727 727 * @use_p2pdma: returns whether to enable p2pdma or not 728 728 * 729 729 * Parses an attribute value to decide whether to enable p2pdma. 730 - * The value can select a PCI device (using it's full BDF device 730 + * The value can select a PCI device (using its full BDF device 731 731 * name) or a boolean (in any format strtobool() accepts). A false 732 732 * value disables p2pdma, a true value expects the caller 733 733 * to automatically find a compatible device and specifying a PCI device ··· 778 778 * whether p2pdma is enabled 779 779 * @page: contents of the stored value 780 780 * @p2p_dev: the selected p2p device (NULL if no device is selected) 781 - * @use_p2pdma: whether p2pdme has been enabled 781 + * @use_p2pdma: whether p2pdma has been enabled 782 782 * 783 783 * Attributes that use pci_p2pdma_enable_store() should use this function 784 784 * to show the value of the attribute.
+12 -15
drivers/pci/pci-driver.c
··· 1251 1251 return 0; 1252 1252 } 1253 1253 1254 - if (!pm || !pm->runtime_suspend) 1255 - return -ENOSYS; 1256 - 1257 1254 pci_dev->state_saved = false; 1258 - error = pm->runtime_suspend(dev); 1259 - if (error) { 1255 + if (pm && pm->runtime_suspend) { 1256 + error = pm->runtime_suspend(dev); 1260 1257 /* 1261 1258 * -EBUSY and -EAGAIN is used to request the runtime PM core 1262 1259 * to schedule a new suspend, so log the event only with debug 1263 1260 * log level. 1264 1261 */ 1265 - if (error == -EBUSY || error == -EAGAIN) 1262 + if (error == -EBUSY || error == -EAGAIN) { 1266 1263 dev_dbg(dev, "can't suspend now (%pf returned %d)\n", 1267 1264 pm->runtime_suspend, error); 1268 - else 1265 + return error; 1266 + } else if (error) { 1269 1267 dev_err(dev, "can't suspend (%pf returned %d)\n", 1270 1268 pm->runtime_suspend, error); 1271 - 1272 - return error; 1269 + return error; 1270 + } 1273 1271 } 1274 1272 1275 1273 pci_fixup_device(pci_fixup_suspend, pci_dev); 1276 1274 1277 - if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0 1275 + if (pm && pm->runtime_suspend 1276 + && !pci_dev->state_saved && pci_dev->current_state != PCI_D0 1278 1277 && pci_dev->current_state != PCI_UNKNOWN) { 1279 1278 WARN_ONCE(pci_dev->current_state != prev, 1280 1279 "PCI PM: State of device not saved by %pF\n", ··· 1291 1292 1292 1293 static int pci_pm_runtime_resume(struct device *dev) 1293 1294 { 1294 - int rc; 1295 + int rc = 0; 1295 1296 struct pci_dev *pci_dev = to_pci_dev(dev); 1296 1297 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 1297 1298 ··· 1305 1306 if (!pci_dev->driver) 1306 1307 return 0; 1307 1308 1308 - if (!pm || !pm->runtime_resume) 1309 - return -ENOSYS; 1310 - 1311 1309 pci_fixup_device(pci_fixup_resume_early, pci_dev); 1312 1310 pci_enable_wake(pci_dev, PCI_D0, false); 1313 1311 pci_fixup_device(pci_fixup_resume, pci_dev); 1314 1312 1315 - rc = pm->runtime_resume(dev); 1313 + if (pm && pm->runtime_resume) 1314 + rc = pm->runtime_resume(dev); 1316 1315 1317 1316 pci_dev->runtime_d3cold = false; 1318 1317
+2
drivers/pci/pci.h
··· 2 2 #ifndef DRIVERS_PCI_H 3 3 #define DRIVERS_PCI_H 4 4 5 + #include <linux/pci.h> 6 + 5 7 #define PCI_FIND_CAP_TTL 48 6 8 7 9 #define PCI_VSEC_ID_INTEL_TBT 0x1234 /* Thunderbolt */
-6
drivers/pci/pcie/aspm.c
··· 53 53 struct pcie_link_state *root; /* pointer to the root port link */ 54 54 struct pcie_link_state *parent; /* pointer to the parent Link state */ 55 55 struct list_head sibling; /* node in link_list */ 56 - struct list_head children; /* list of child link states */ 57 - struct list_head link; /* node in parent's children list */ 58 56 59 57 /* ASPM state */ 60 58 u32 aspm_support:7; /* Supported ASPM state */ ··· 848 850 return NULL; 849 851 850 852 INIT_LIST_HEAD(&link->sibling); 851 - INIT_LIST_HEAD(&link->children); 852 - INIT_LIST_HEAD(&link->link); 853 853 link->pdev = pdev; 854 854 link->downstream = pci_function_0(pdev->subordinate); 855 855 ··· 873 877 874 878 link->parent = parent; 875 879 link->root = link->parent->root; 876 - list_add(&link->link, &parent->children); 877 880 } 878 881 879 882 list_add(&link->sibling, &link_list); ··· 996 1001 /* All functions are removed, so just disable ASPM for the link */ 997 1002 pcie_config_aspm_link(link, 0); 998 1003 list_del(&link->sibling); 999 - list_del(&link->link); 1000 1004 /* Clock PM is for endpoint device */ 1001 1005 free_link_state(link); 1002 1006
+8 -8
drivers/pci/pcie/portdrv.h
··· 71 71 72 72 struct pcie_port_service_driver { 73 73 const char *name; 74 - int (*probe) (struct pcie_device *dev); 75 - void (*remove) (struct pcie_device *dev); 76 - int (*suspend) (struct pcie_device *dev); 77 - int (*resume_noirq) (struct pcie_device *dev); 78 - int (*resume) (struct pcie_device *dev); 79 - int (*runtime_suspend) (struct pcie_device *dev); 80 - int (*runtime_resume) (struct pcie_device *dev); 74 + int (*probe)(struct pcie_device *dev); 75 + void (*remove)(struct pcie_device *dev); 76 + int (*suspend)(struct pcie_device *dev); 77 + int (*resume_noirq)(struct pcie_device *dev); 78 + int (*resume)(struct pcie_device *dev); 79 + int (*runtime_suspend)(struct pcie_device *dev); 80 + int (*runtime_resume)(struct pcie_device *dev); 81 81 82 82 /* Device driver may resume normal operations */ 83 83 void (*error_resume)(struct pci_dev *dev); 84 84 85 85 /* Link Reset Capability - AER service driver specific */ 86 - pci_ers_result_t (*reset_link) (struct pci_dev *dev); 86 + pci_ers_result_t (*reset_link)(struct pci_dev *dev); 87 87 88 88 int port_type; /* Type of the port this driver can handle */ 89 89 u32 service; /* Port service this device represents */
+24
drivers/pci/quirks.c
··· 619 619 quirk_amd_nl_class); 620 620 621 621 /* 622 + * Synopsys USB 3.x host HAPS platform has a class code of 623 + * PCI_CLASS_SERIAL_USB_XHCI, and xhci driver can claim it. However, these 624 + * devices should use dwc3-haps driver. Change these devices' class code to 625 + * PCI_CLASS_SERIAL_USB_DEVICE to prevent the xhci-pci driver from claiming 626 + * them. 627 + */ 628 + static void quirk_synopsys_haps(struct pci_dev *pdev) 629 + { 630 + u32 class = pdev->class; 631 + 632 + switch (pdev->device) { 633 + case PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3: 634 + case PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3_AXI: 635 + case PCI_DEVICE_ID_SYNOPSYS_HAPSUSB31: 636 + pdev->class = PCI_CLASS_SERIAL_USB_DEVICE; 637 + pci_info(pdev, "PCI class overridden (%#08x -> %#08x) so dwc3 driver can claim this instead of xhci\n", 638 + class, pdev->class); 639 + break; 640 + } 641 + } 642 + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SYNOPSYS, PCI_ANY_ID, 643 + quirk_synopsys_haps); 644 + 645 + /* 622 646 * Let's make the southbridge information explicit instead of having to 623 647 * worry about people probing the ACPI areas, for example.. (Yes, it 624 648 * happens, and if you read the wrong ACPI register it will put the machine
+137 -17
drivers/pci/switch/switchtec.c
··· 13 13 #include <linux/uaccess.h> 14 14 #include <linux/poll.h> 15 15 #include <linux/wait.h> 16 - 16 + #include <linux/io-64-nonatomic-lo-hi.h> 17 17 #include <linux/nospec.h> 18 18 19 19 MODULE_DESCRIPTION("Microsemi Switchtec(tm) PCIe Management Driver"); ··· 24 24 static int max_devices = 16; 25 25 module_param(max_devices, int, 0644); 26 26 MODULE_PARM_DESC(max_devices, "max number of switchtec device instances"); 27 + 28 + static bool use_dma_mrpc = 1; 29 + module_param(use_dma_mrpc, bool, 0644); 30 + MODULE_PARM_DESC(use_dma_mrpc, 31 + "Enable the use of the DMA MRPC feature"); 27 32 28 33 static dev_t switchtec_devt; 29 34 static DEFINE_IDA(switchtec_minor_ida); ··· 118 113 119 114 static void mrpc_complete_cmd(struct switchtec_dev *stdev); 120 115 116 + static void flush_wc_buf(struct switchtec_dev *stdev) 117 + { 118 + struct ntb_dbmsg_regs __iomem *mmio_dbmsg; 119 + 120 + /* 121 + * odb (outbound doorbell) register is processed by low latency 122 + * hardware and w/o side effect 123 + */ 124 + mmio_dbmsg = (void __iomem *)stdev->mmio_ntb + 125 + SWITCHTEC_NTB_REG_DBMSG_OFFSET; 126 + ioread32(&mmio_dbmsg->odb); 127 + } 128 + 121 129 static void mrpc_cmd_submit(struct switchtec_dev *stdev) 122 130 { 123 131 /* requires the mrpc_mutex to already be held when called */ ··· 146 128 stuser = list_entry(stdev->mrpc_queue.next, struct switchtec_user, 147 129 list); 148 130 131 + if (stdev->dma_mrpc) { 132 + stdev->dma_mrpc->status = SWITCHTEC_MRPC_STATUS_INPROGRESS; 133 + memset(stdev->dma_mrpc->data, 0xFF, SWITCHTEC_MRPC_PAYLOAD_SIZE); 134 + } 135 + 149 136 stuser_set_state(stuser, MRPC_RUNNING); 150 137 stdev->mrpc_busy = 1; 151 138 memcpy_toio(&stdev->mmio_mrpc->input_data, 152 139 stuser->data, stuser->data_len); 140 + flush_wc_buf(stdev); 153 141 iowrite32(stuser->cmd, &stdev->mmio_mrpc->cmd); 154 - 155 - stuser->status = ioread32(&stdev->mmio_mrpc->status); 156 - if (stuser->status != SWITCHTEC_MRPC_STATUS_INPROGRESS) 157 - mrpc_complete_cmd(stdev); 158 142 159 143 schedule_delayed_work(&stdev->mrpc_timeout, 160 144 msecs_to_jiffies(500)); ··· 190 170 stuser = list_entry(stdev->mrpc_queue.next, struct switchtec_user, 191 171 list); 192 172 193 - stuser->status = ioread32(&stdev->mmio_mrpc->status); 173 + if (stdev->dma_mrpc) 174 + stuser->status = stdev->dma_mrpc->status; 175 + else 176 + stuser->status = ioread32(&stdev->mmio_mrpc->status); 177 + 194 178 if (stuser->status == SWITCHTEC_MRPC_STATUS_INPROGRESS) 195 179 return; 196 180 ··· 204 180 if (stuser->status != SWITCHTEC_MRPC_STATUS_DONE) 205 181 goto out; 206 182 207 - stuser->return_code = ioread32(&stdev->mmio_mrpc->ret_value); 183 + if (stdev->dma_mrpc) 184 + stuser->return_code = stdev->dma_mrpc->rtn_code; 185 + else 186 + stuser->return_code = ioread32(&stdev->mmio_mrpc->ret_value); 208 187 if (stuser->return_code != 0) 209 188 goto out; 210 189 211 - memcpy_fromio(stuser->data, &stdev->mmio_mrpc->output_data, 212 - stuser->read_len); 213 - 190 + if (stdev->dma_mrpc) 191 + memcpy(stuser->data, &stdev->dma_mrpc->data, 192 + stuser->read_len); 193 + else 194 + memcpy_fromio(stuser->data, &stdev->mmio_mrpc->output_data, 195 + stuser->read_len); 214 196 out: 215 197 complete_all(&stuser->comp); 216 198 list_del_init(&stuser->list); ··· 251 221 252 222 mutex_lock(&stdev->mrpc_mutex); 253 223 254 - status = ioread32(&stdev->mmio_mrpc->status); 224 + if (stdev->dma_mrpc) 225 + status = stdev->dma_mrpc->status; 226 + else 227 + status = ioread32(&stdev->mmio_mrpc->status); 255 228 if (status == SWITCHTEC_MRPC_STATUS_INPROGRESS) { 256 229 schedule_delayed_work(&stdev->mrpc_timeout, 257 230 msecs_to_jiffies(500)); ··· 262 229 } 263 230 264 231 mrpc_complete_cmd(stdev); 265 - 266 232 out: 267 233 mutex_unlock(&stdev->mrpc_mutex); 268 234 } ··· 832 800 { 833 801 int ret; 834 802 int nr_idxs; 803 + unsigned int event_flags; 835 804 struct switchtec_ioctl_event_ctl ctl; 836 805 837 806 if (copy_from_user(&ctl, uctl, sizeof(ctl))) ··· 854 821 else 855 822 return -EINVAL; 856 823 824 + event_flags = ctl.flags; 857 825 for (ctl.index = 0; ctl.index < nr_idxs; ctl.index++) { 826 + ctl.flags = event_flags; 858 827 ret = event_ctl(stdev, &ctl); 859 828 if (ret < 0) 860 829 return ret; ··· 1052 1017 } 1053 1018 } 1054 1019 1020 + static void enable_dma_mrpc(struct switchtec_dev *stdev) 1021 + { 1022 + writeq(stdev->dma_mrpc_dma_addr, &stdev->mmio_mrpc->dma_addr); 1023 + flush_wc_buf(stdev); 1024 + iowrite32(SWITCHTEC_DMA_MRPC_EN, &stdev->mmio_mrpc->dma_en); 1025 + } 1026 + 1055 1027 static void stdev_release(struct device *dev) 1056 1028 { 1057 1029 struct switchtec_dev *stdev = to_stdev(dev); 1058 1030 1031 + if (stdev->dma_mrpc) { 1032 + iowrite32(0, &stdev->mmio_mrpc->dma_en); 1033 + flush_wc_buf(stdev); 1034 + writeq(0, &stdev->mmio_mrpc->dma_addr); 1035 + dma_free_coherent(&stdev->pdev->dev, sizeof(*stdev->dma_mrpc), 1036 + stdev->dma_mrpc, stdev->dma_mrpc_dma_addr); 1037 + } 1059 1038 kfree(stdev); 1060 1039 } 1061 1040 ··· 1225 1176 return ret; 1226 1177 } 1227 1178 1179 + 1180 + static irqreturn_t switchtec_dma_mrpc_isr(int irq, void *dev) 1181 + { 1182 + struct switchtec_dev *stdev = dev; 1183 + irqreturn_t ret = IRQ_NONE; 1184 + 1185 + iowrite32(SWITCHTEC_EVENT_CLEAR | 1186 + SWITCHTEC_EVENT_EN_IRQ, 1187 + &stdev->mmio_part_cfg->mrpc_comp_hdr); 1188 + schedule_work(&stdev->mrpc_work); 1189 + 1190 + ret = IRQ_HANDLED; 1191 + return ret; 1192 + } 1193 + 1228 1194 static int switchtec_init_isr(struct switchtec_dev *stdev) 1229 1195 { 1230 1196 int nvecs; 1231 1197 int event_irq; 1198 + int dma_mrpc_irq; 1199 + int rc; 1232 1200 1233 1201 nvecs = pci_alloc_irq_vectors(stdev->pdev, 1, 4, 1234 1202 PCI_IRQ_MSIX | PCI_IRQ_MSI); ··· 1260 1194 if (event_irq < 0) 1261 1195 return event_irq; 1262 1196 1263 - return devm_request_irq(&stdev->pdev->dev, event_irq, 1197 + rc = devm_request_irq(&stdev->pdev->dev, event_irq, 1264 1198 switchtec_event_isr, 0, 1265 1199 KBUILD_MODNAME, stdev); 1200 + 1201 + if (rc) 1202 + return rc; 1203 + 1204 + if (!stdev->dma_mrpc) 1205 + return rc; 1206 + 1207 + dma_mrpc_irq = ioread32(&stdev->mmio_mrpc->dma_vector); 1208 + if (dma_mrpc_irq < 0 || dma_mrpc_irq >= nvecs) 1209 + return -EFAULT; 1210 + 1211 + dma_mrpc_irq = pci_irq_vector(stdev->pdev, dma_mrpc_irq); 1212 + if (dma_mrpc_irq < 0) 1213 + return dma_mrpc_irq; 1214 + 1215 + rc = devm_request_irq(&stdev->pdev->dev, dma_mrpc_irq, 1216 + switchtec_dma_mrpc_isr, 0, 1217 + KBUILD_MODNAME, stdev); 1218 + 1219 + return rc; 1266 1220 } 1267 1221 1268 1222 static void init_pff(struct switchtec_dev *stdev) ··· 1318 1232 struct pci_dev *pdev) 1319 1233 { 1320 1234 int rc; 1235 + void __iomem *map; 1236 + unsigned long res_start, res_len; 1321 1237 1322 1238 rc = pcim_enable_device(pdev); 1323 1239 if (rc) 1324 1240 return rc; 1325 1241 1326 - rc = pcim_iomap_regions(pdev, 0x1, KBUILD_MODNAME); 1242 + rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64)); 1327 1243 if (rc) 1328 1244 return rc; 1329 1245 1330 1246 pci_set_master(pdev); 1331 1247 1332 - stdev->mmio = pcim_iomap_table(pdev)[0]; 1333 - stdev->mmio_mrpc = stdev->mmio + SWITCHTEC_GAS_MRPC_OFFSET; 1248 + res_start = pci_resource_start(pdev, 0); 1249 + res_len = pci_resource_len(pdev, 0); 1250 + 1251 + if (!devm_request_mem_region(&pdev->dev, res_start, 1252 + res_len, KBUILD_MODNAME)) 1253 + return -EBUSY; 1254 + 1255 + stdev->mmio_mrpc = devm_ioremap_wc(&pdev->dev, res_start, 1256 + SWITCHTEC_GAS_TOP_CFG_OFFSET); 1257 + if (!stdev->mmio_mrpc) 1258 + return -ENOMEM; 1259 + 1260 + map = devm_ioremap(&pdev->dev, 1261 + res_start + SWITCHTEC_GAS_TOP_CFG_OFFSET, 1262 + res_len - SWITCHTEC_GAS_TOP_CFG_OFFSET); 1263 + if (!map) 1264 + return -ENOMEM; 1265 + 1266 + stdev->mmio = map - SWITCHTEC_GAS_TOP_CFG_OFFSET; 1334 1267 stdev->mmio_sw_event = stdev->mmio + SWITCHTEC_GAS_SW_EVENT_OFFSET; 1335 1268 stdev->mmio_sys_info = stdev->mmio + SWITCHTEC_GAS_SYS_INFO_OFFSET; 1336 1269 stdev->mmio_flash_info = stdev->mmio + SWITCHTEC_GAS_FLASH_INFO_OFFSET; ··· 1366 1261 init_pff(stdev); 1367 1262 1368 1263 pci_set_drvdata(pdev, stdev); 1264 + 1265 + if (!use_dma_mrpc) 1266 + return 0; 1267 + 1268 + if (ioread32(&stdev->mmio_mrpc->dma_ver) == 0) 1269 + return 0; 1270 + 1271 + stdev->dma_mrpc = dma_zalloc_coherent(&stdev->pdev->dev, 1272 + sizeof(*stdev->dma_mrpc), 1273 + &stdev->dma_mrpc_dma_addr, 1274 + GFP_KERNEL); 1275 + if (stdev->dma_mrpc == NULL) 1276 + return -ENOMEM; 1369 1277 1370 1278 return 0; 1371 1279 } ··· 1411 1293 &stdev->mmio_part_cfg->mrpc_comp_hdr); 1412 1294 enable_link_state_events(stdev); 1413 1295 1296 + if (stdev->dma_mrpc) 1297 + enable_dma_mrpc(stdev); 1298 + 1414 1299 rc = cdev_device_add(&stdev->cdev, &stdev->dev); 1415 1300 if (rc) 1416 1301 goto err_devadd; ··· 1439 1318 cdev_device_del(&stdev->cdev, &stdev->dev); 1440 1319 ida_simple_remove(&switchtec_minor_ida, MINOR(stdev->dev.devt)); 1441 1320 dev_info(&stdev->dev, "unregistered.\n"); 1442 - 1443 1321 stdev_kill(stdev); 1444 1322 put_device(&stdev->dev); 1445 1323 }
-4
drivers/usb/dwc3/dwc3-haps.c
··· 15 15 #include <linux/platform_device.h> 16 16 #include <linux/property.h> 17 17 18 - #define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3 0xabcd 19 - #define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3_AXI 0xabce 20 - #define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB31 0xabcf 21 - 22 18 /** 23 19 * struct dwc3_haps - Driver private structure 24 20 * @dwc3: child dwc3 platform_device
+1
include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
··· 440 440 #define IMX6SX_GPR5_DISP_MUX_DCIC1_MASK (0x1 << 1) 441 441 442 442 #define IMX6SX_GPR12_PCIE_TEST_POWERDOWN BIT(30) 443 + #define IMX6SX_GPR12_PCIE_PM_TURN_OFF BIT(16) 443 444 #define IMX6SX_GPR12_PCIE_RX_EQ_MASK (0x7 << 0) 444 445 #define IMX6SX_GPR12_PCIE_RX_EQ_2 (0x2 << 0) 445 446
+4 -3
include/linux/pci.h
··· 413 413 unsigned int non_compliant_bars:1; /* Broken BARs; ignore them */ 414 414 unsigned int is_probed:1; /* Device probing in progress */ 415 415 unsigned int link_active_reporting:1;/* Device capable of reporting link active */ 416 + unsigned int no_vf_scan:1; /* Don't scan for VFs after IOV enablement */ 416 417 pci_dev_flags_t dev_flags; 417 418 atomic_t enable_cnt; /* pci_enable_device has been called */ 418 419 ··· 773 772 int (*suspend)(struct pci_dev *dev, pm_message_t state); /* Device suspended */ 774 773 int (*suspend_late)(struct pci_dev *dev, pm_message_t state); 775 774 int (*resume_early)(struct pci_dev *dev); 776 - int (*resume) (struct pci_dev *dev); /* Device woken up */ 777 - void (*shutdown) (struct pci_dev *dev); 778 - int (*sriov_configure) (struct pci_dev *dev, int num_vfs); /* On PF */ 775 + int (*resume)(struct pci_dev *dev); /* Device woken up */ 776 + void (*shutdown)(struct pci_dev *dev); 777 + int (*sriov_configure)(struct pci_dev *dev, int num_vfs); /* On PF */ 779 778 const struct pci_error_handlers *err_handler; 780 779 const struct attribute_group **groups; 781 780 struct device_driver driver;
+3
include/linux/pci_ids.h
··· 2361 2361 #define PCI_DEVICE_ID_CENATEK_IDE 0x0001 2362 2362 2363 2363 #define PCI_VENDOR_ID_SYNOPSYS 0x16c3 2364 + #define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3 0xabcd 2365 + #define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3_AXI 0xabce 2366 + #define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB31 0xabcf 2364 2367 2365 2368 #define PCI_VENDOR_ID_USR 0x16ec 2366 2369
+16
include/linux/switchtec.h
··· 29 29 #define SWITCHTEC_EVENT_EN_IRQ BIT(3) 30 30 #define SWITCHTEC_EVENT_FATAL BIT(4) 31 31 32 + #define SWITCHTEC_DMA_MRPC_EN BIT(0) 32 33 enum { 33 34 SWITCHTEC_GAS_MRPC_OFFSET = 0x0000, 34 35 SWITCHTEC_GAS_TOP_CFG_OFFSET = 0x1000, ··· 47 46 u32 cmd; 48 47 u32 status; 49 48 u32 ret_value; 49 + u32 dma_en; 50 + u64 dma_addr; 51 + u32 dma_vector; 52 + u32 dma_ver; 50 53 } __packed; 51 54 52 55 enum mrpc_status { ··· 347 342 348 343 struct switchtec_ntb; 349 344 345 + struct dma_mrpc_output { 346 + u32 status; 347 + u32 cmd_id; 348 + u32 rtn_code; 349 + u32 output_size; 350 + u8 data[SWITCHTEC_MRPC_PAYLOAD_SIZE]; 351 + }; 352 + 350 353 struct switchtec_dev { 351 354 struct pci_dev *pdev; 352 355 struct device dev; ··· 394 381 u8 link_event_count[SWITCHTEC_MAX_PFF_CSR]; 395 382 396 383 struct switchtec_ntb *sndev; 384 + 385 + struct dma_mrpc_output *dma_mrpc; 386 + dma_addr_t dma_mrpc_dma_addr; 397 387 }; 398 388 399 389 static inline struct switchtec_dev *to_stdev(struct device *dev)