summaryrefslogtreecommitdiff
path: root/drivers/pci/controller/dwc/pcie-designware.c
AgeCommit message (Collapse)Author
2025-03-27Merge branch 'pci/controller/dwc-cpu-addr-fixup'Bjorn Helgaas
- Ioremap() msg_res region using res->start (the CPU address), not the ATU 'cpu_addr', which will be replaced with the ATU input address (which may not be the CPU address) (Frank Li) - Rename struct dw_pcie_ob_atu_cfg.cpu_addr to 'parent_bus_addr' (Frank Li) - Call devm_pci_alloc_host_bridge() early in dw_pcie_host_init() to keep devicetree-related code together (Frank Li) - Consolidate devicetree handling in dw_pcie_host_get_resources() (Bjorn Helgaas) - Add dw_pcie_parent_bus_offset() to look up the parent bus address of a specified 'reg' property and return the offset from the CPU physical address (Frank Li) - Add cross-checking with .cpu_addr_fixup() and debug logging to dw_pcie_parent_bus_offset() (Frank Li) - Use devicetree 'reg[config]' via dw_pcie_parent_bus_offset() to derive CPU -> ATU addr offset for host controller (Frank Li) - Call epc_create() early in dw_pcie_ep_init() to keep devicetree-related code together (Bjorn Helgaas) - Consolidate devicetree handling in dw_pcie_ep_get_resources() (Bjorn Helgaas) - Use devicetree 'reg[addr_space]' via dw_pcie_parent_bus_offset() to derive CPU -> ATU addr offset for endpoint controller (Frank Li) - Update dw_pcie_find_index() to remove assumption that ATU input address is non-zero (Frank Li) - Apply struct dw_pcie.parent_bus_offset in ATU users to remove use of .cpu_addr_fixup() when programming ATU (Frank Li) - Remove imx_pcie_cpu_addr_fixup() since dwc core can now derive the ATU input address (using parent_bus_offset) from devicetree (Frank Li) - Remove intel_pcie_cpu_addr() since dwc core can now derive the ATU input address (using parent_bus_offset) from devicetree (Frank Li) * pci/controller/dwc-cpu-addr-fixup: PCI: intel-gw: Remove intel_pcie_cpu_addr() PCI: imx6: Remove imx_pcie_cpu_addr_fixup() PCI: dwc: Use parent_bus_offset to remove need for .cpu_addr_fixup() PCI: dwc: ep: Ensure proper iteration over outbound map windows PCI: dwc: ep: Use devicetree 'reg[addr_space]' to derive CPU -> ATU addr offset PCI: dwc: ep: Consolidate devicetree handling in dw_pcie_ep_get_resources() PCI: dwc: ep: Call epc_create() early in dw_pcie_ep_init() PCI: dwc: Use devicetree 'reg[config]' to derive CPU -> ATU addr offset PCI: dwc: Add dw_pcie_parent_bus_offset() checking and debug PCI: dwc: Add dw_pcie_parent_bus_offset() PCI: dwc: Consolidate devicetree handling in dw_pcie_host_get_resources() PCI: dwc: Call devm_pci_alloc_host_bridge() early in dw_pcie_host_init() PCI: dwc: Rename cpu_addr to parent_bus_addr for ATU configuration PCI: dwc: Use resource start as ioremap() input in dw_pcie_pme_turn_off() # Conflicts: # drivers/pci/controller/dwc/pcie-designware.c # drivers/pci/controller/dwc/pcie-designware.h
2025-03-24PCI: dwc: Use parent_bus_offset to remove need for .cpu_addr_fixup()Frank Li
We know the parent_bus_offset, either computed from a DT reg property (the offset is the CPU physical addr - the 'config'/'addr_space' address on the parent bus) or from a .cpu_addr_fixup() (which may have used a host bridge window offset). Apply that parent_bus_offset instead of calling .cpu_addr_fixup() when programming the ATU. This assumes all intermediate addresses are at the same offset from the CPU physical addresses. [bhelgaas: commit log] Link: https://lore.kernel.org/r/20250315201548.858189-13-helgaas@kernel.org Signed-off-by: Frank Li <Frank.Li@nxp.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
2025-03-24PCI: dwc: Add dw_pcie_parent_bus_offset() checking and debugFrank Li
dw_pcie_parent_bus_offset() looks up the parent bus address of a PCI controller 'reg' property in devicetree. If implemented, .cpu_addr_fixup() is a hard-coded way to get the parent bus address corresponding to a CPU physical address. Add debug code to compare the address from .cpu_addr_fixup() with the address from devicetree. If they match, warn that .cpu_addr_fixup() is redundant and should be removed; if they differ, warn that something is wrong with the devicetree. If .cpu_addr_fixup() is not implemented, the parent bus address should be identical to the CPU physical address because we previously ignored the parent bus address from devicetree. If the devicetree has a different parent bus address, warn about it being broken. [bhelgaas: split debug to separate patch for easier future revert, commit log] Link: https://lore.kernel.org/r/20250315201548.858189-7-helgaas@kernel.org Signed-off-by: Frank Li <Frank.Li@nxp.com> [bhelgaas: squash Ioana Ciornei <ioana.ciornei@nxp.com> fix for NULL pointer deref when driver doesn't supply dw_pcie_ops, e.g., layerscape-pcie https://lore.kernel.org/r/20250319134339.3114817-1-ioana.ciornei@nxp.com] Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
2025-03-24PCI: dwc: Add dw_pcie_parent_bus_offset()Frank Li
Return the offset from CPU physical address to the parent bus address of the specified element of the devicetree 'reg' property. [bhelgaas: cpu_phy_addr -> cpu_phys_addr, return offset, split .cpu_addr_fixup() checking and debug to separate patch] Link: https://lore.kernel.org/r/20250315201548.858189-6-helgaas@kernel.org Signed-off-by: Frank Li <Frank.Li@nxp.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
2025-03-17PCI: dwc: Rename cpu_addr to parent_bus_addr for ATU configurationFrank Li
Rename 'cpu_addr' to 'parent_bus_addr' in the DesignWare ATU configuration. The ATU translates parent bus addresses to PCI addresses, which are often the same as CPU addresses but can differ in systems where the bus fabric translates addresses before passing them to the PCIe controller. This renaming clarifies the purpose and avoids confusion. Link: https://lore.kernel.org/r/20250315201548.858189-3-helgaas@kernel.org Signed-off-by: Frank Li <Frank.Li@nxp.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
2025-03-06PCI: dwc: Add debugfs based Silicon Debug support for DWCShradha Todi
Add support to provide Silicon Debug interface to userspace. This set of debug registers are part of the RAS DES feature present in DesignWare PCIe controllers. Co-developed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> Signed-off-by: Shradha Todi <shradha.t@samsung.com> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> Reviewed-by: Fan Ni <fan.ni@samsung.com> Tested-by: Hrishikesh Deleep <hrishikesh.d@samsung.com> Link: https://lore.kernel.org/r/20250221131548.59616-4-shradha.t@samsung.com [kwilczynski: commit log, tidy up Kconfig and drop "default y", tidy up code comments, squashed patch that fixes a NULL pointer dereference when debugfs is already unavailable during clean-up from https://lore.kernel.org/linux-pci/20250225171239.19574-2-manivannan.sadhasivam@linaro.org, refactor dwc_pcie_debugfs_init() to not return errors, squashed patch that changes how lack of the RAS DES capability is handled from https://lore.kernel.org/linux-pci/20250304151814.6xu7cbpwpqrvcad5@thinkpad] Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
2025-03-03PCI: dwc: Add helper to find the Vendor Specific Extended Capability (VSEC)Shradha Todi
The new dw_pcie_find_vsec_capability() helper will be used within different DWC APIs to find the VSEC capabilities like PTM, RAS, etc. Co-developed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> Signed-off-by: Shradha Todi <shradha.t@samsung.com> Reviewed-by: Fan Ni <fan.ni@samsung.com> Tested-by: Hrishikesh Deleep <hrishikesh.d@samsung.com> Link: https://lore.kernel.org/r/20250221131548.59616-3-shradha.t@samsung.com [kwilczynski: commit log] Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
2025-01-23Merge branch 'pci/controller/dwc'Bjorn Helgaas
- Fix potential string truncation in dw_pcie_edma_irq_verify() (Niklas Cassel) - Don't wait for link up in DWC core if driver can detect Link Up event (Krishna chaitanya chundru) - If qcom 'global' IRQ is supported for detection of Link Up events, tell DWC core not to wait for link up (Krishna chaitanya chundru) - Update ICC and OPP votes after Link Up events (Krishna chaitanya chundru) - Use dw-rockchip dll_link_up IRQ to detect Link Up and enumerate devices so users don't have to manually rescan (Niklas Cassel) - In dw-rockchip, the 'sys' interrupt is required and detects Link Up events, so tell DWC core not to wait for link up (Niklas Cassel) - Always stop link in dw_pcie_suspend_noirq(), which is required at least for i.MX8QM to re-establish link on resume (Richard Zhu) - Drop racy and unnecessary LTSSM state check before sending PME_TURN_OFF message in dw_pcie_suspend_noirq() (Richard Zhu) - Add stubs for dw_pcie_suspend_noirq() dw_pcie_resume_noirq() when CONFIG_PCIE_DW_HOST is not defined so drivers don't need #ifdefs (Bjorn Helgaas) - Use DWC core suspend/resume functions for imx6 (Frank Li) - Add imx6 suspend/resume support for i.MX8MQ, i.MX8Q, and i.MX95 (Richard Zhu) - Add struct of_pci_range.parent_bus_addr for devices that need their immediate parent bus address, not the CPU address, e.g., to program an internal Address Translation Unit (iATU) (Frank Li) * pci/controller/dwc: PCI: dwc: Simplify config resource lookup of: address: Add parent_bus_addr to struct of_pci_range PCI: imx6: Add i.MX8MQ, i.MX8Q and i.MX95 PM support PCI: imx6: Use DWC common suspend resume method PCI: dwc: Add dw_pcie_suspend_noirq(), dw_pcie_resume_noirq() stubs for !CONFIG_PCIE_DW_HOST PCI: dwc: Remove LTSSM state test in dw_pcie_suspend_noirq() PCI: dwc: Always stop link in the dw_pcie_suspend_noirq PCI: dw-rockchip: Don't wait for link since we can detect Link Up PCI: dw-rockchip: Enumerate endpoints based on dll_link_up IRQ PCI: qcom: Update ICC and OPP values after Link Up event PCI: qcom: Don't wait for link if we can detect Link Up PCI: dwc: Don't wait for link up if driver can detect Link Up event PCI: dwc: Fix potential truncation in dw_pcie_edma_irq_verify() # Conflicts: # drivers/pci/controller/dwc/pci-imx6.c
2025-01-18PCI: dwc: Fix potential truncation in dw_pcie_edma_irq_verify()Niklas Cassel
Increase the size of the string buffer to avoid potential truncation in dw_pcie_edma_irq_verify(). This fixes the following build warning when compiling with W=1: drivers/pci/controller/dwc/pcie-designware.c: In function ‘dw_pcie_edma_detect’: drivers/pci/controller/dwc/pcie-designware.c:989:50: warning: ‘%d’ directive output may be truncated writing between 1 and 11 bytes into a region of size 3 [-Wformat-truncation=] 989 | snprintf(name, sizeof(name), "dma%d", pci->edma.nr_irqs); | ^~ Link: https://lore.kernel.org/r/20250104002119.2681246-2-cassel@kernel.org Signed-off-by: Niklas Cassel <cassel@kernel.org> Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
2024-12-18PCI: dwc: ep: Add 'address' alignment to 'size' check in ↵Niklas Cassel
dw_pcie_prog_ep_inbound_atu() dw_pcie_prog_ep_inbound_atu() is used to program an inbound iATU in "BAR Match Mode". A memory address returned by e.g. kmalloc() is guaranteed to have natural alignment (aligned to the size of the allocation). It is however not guaranteed that pci_epc_set_bar() (and thus dw_pcie_prog_ep_inbound_atu()) is supplied an address that has natural alignment. (An EPF driver can send in an arbitrary physical address to pci_epc_set_bar().) The DWC Databook description for the LWR_TARGET_RW and LWR_TARGET_HW fields in the IATU_LWR_TARGET_ADDR_OFF_INBOUND_i registers state that: "Field size depends on log2(BAR_MASK+1) in BAR match mode." I.e. only the upper bits are writable, and the number of writable bits is dependent on the configured BAR_MASK. Add a check to ensure that the physical address programmed in the iATU is aligned to the size of the BAR (BAR_MASK+1), as without this, we can get hard to debug errors, as we could write to bits that are read-only (without getting a write error), which could cause the iATU to end up redirecting to a physical address that is different from the address that we intended. Link: https://lore.kernel.org/r/20241213143301.4158431-11-cassel@kernel.org Signed-off-by: Niklas Cassel <cassel@kernel.org> Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
2024-09-13PCI: dwc: Always cache the maximum link speed value in dw_pcie::max_link_speedManivannan Sadhasivam
Currently, the dw_pcie::max_link_speed has a valid value only if the controller driver restricts the maximum link speed in the driver or if the platform does so in the devicetree using the 'max-link-speed' property. But having the maximum supported link speed of the platform would be helpful for the vendor drivers to configure any link specific settings. So in the case of non-valid value in dw_pcie::max_link_speed, just cache the hardware default value from Link Capability register. While at it, remove the 'max_link_speed' argument to the dw_pcie_link_set_max_speed() function since the value can be retrieved within the function. Link: https://lore.kernel.org/linux-pci/20240911-pci-qcom-gen4-stability-v7-2-743f5c1fd027@linaro.org Tested-by: Johan Hovold <johan+linaro@kernel.org> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> [kwilczynski: commit log] Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org> Reviewed-by: Frank Li <Frank.Li@nxp.com> Reviewed-by: Johan Hovold <johan+linaro@kernel.org>
2024-09-13PCI: dwc: Rename 'dw_pcie::link_gen' to 'dw_pcie::max_link_speed'Manivannan Sadhasivam
The 'link_gen' field is now holding the maximum supported link speed set either by the controller driver or by DT through 'max-link-speed' property. However, the name 'link_gen' sounds like the negotiated link speed of the PCIe link. So rename it to 'max_link_speed' to make it clear that it holds the maximum supported link speed of the controller. Link: https://lore.kernel.org/linux-pci/20240911-pci-qcom-gen4-stability-v7-1-743f5c1fd027@linaro.org Tested-by: Johan Hovold <johan+linaro@kernel.org> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> [kwilczynski: commit log] Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org> Reviewed-by: Frank Li <Frank.Li@nxp.com> Reviewed-by: Johan Hovold <johan+linaro@kernel.org>
2024-09-01PCI: qcom: Disable mirroring of DBI and iATU register space in BAR regionPrudhvi Yarlagadda
PARF hardware block which is a wrapper on top of DWC PCIe controller mirrors the DBI and ATU register space. It uses PARF_SLV_ADDR_SPACE_SIZE register to get the size of the memory block to be mirrored and uses PARF_DBI_BASE_ADDR, PARF_ATU_BASE_ADDR registers to determine the base address of DBI and ATU space inside the memory block that is being mirrored. When a memory region which is located above the SLV_ADDR_SPACE_SIZE boundary is used for BAR region then there could be an overlap of DBI and ATU address space that is getting mirrored and the BAR region. This results in DBI and ATU address space contents getting updated when a PCIe function driver tries updating the BAR/MMIO memory region. Reference memory map of the PCIe memory region with DBI and ATU address space overlapping BAR region is as below. |---------------| | | | | ------- --------|---------------| | | |---------------| | | | DBI | | | |---------------|---->DBI_BASE_ADDR | | | | | | | | | PCIe | |---->2*SLV_ADDR_SPACE_SIZE | BAR/MMIO|---------------| | Region | ATU | | | |---------------|---->ATU_BASE_ADDR | | | | PCIe | |---------------| Memory | | DBI | Region | |---------------|---->DBI_BASE_ADDR | | | | | --------| | | | |---->SLV_ADDR_SPACE_SIZE | |---------------| | | ATU | | |---------------|---->ATU_BASE_ADDR | | | | |---------------| | | DBI | | |---------------|---->DBI_BASE_ADDR | | | | | | ----------------|---------------| | | | | | | |---------------| Currently memory region beyond the SLV_ADDR_SPACE_SIZE boundary is not used for BAR region which is why the above mentioned issue is not encountered. This issue is discovered as part of internal testing when we tried moving the BAR region beyond the SLV_ADDR_SPACE_SIZE boundary. Hence we are trying to fix this. As PARF hardware block mirrors DBI and ATU register space after every PARF_SLV_ADDR_SPACE_SIZE (default 0x1000000) boundary multiple, program maximum possible size to this register by writing 0x80000000 to it(it considers only powers of 2 as values) to avoid mirroring DBI and ATU to BAR/MMIO region. Write the physical base address of DBI and ATU register blocks to PARF_DBI_BASE_ADDR (default 0x0) and PARF_ATU_BASE_ADDR (default 0x1000) respectively to make sure DBI and ATU blocks are at expected memory locations. The register offsets PARF_DBI_BASE_ADDR_V2, PARF_SLV_ADDR_SPACE_SIZE_V2 and PARF_ATU_BASE_ADDR are applicable for platforms that use Qcom IP rev 1.9.0, 2.7.0 and 2.9.0. PARF_DBI_BASE_ADDR_V2 and PARF_SLV_ADDR_SPACE_SIZE_V2 are applicable for Qcom IP rev 2.3.3. PARF_DBI_BASE_ADDR and PARF_SLV_ADDR_SPACE_SIZE are applicable for Qcom IP rev 1.0.0, 2.3.2 and 2.4.0. Update init()/post_init() functions of the respective Qcom IP versions to program applicable PARF_DBI_BASE_ADDR, PARF_SLV_ADDR_SPACE_SIZE and PARF_ATU_BASE_ADDR register offsets. Update the SLV_ADDR_SPACE_SZ macro to 0x80000000 to set highest bit in PARF_SLV_ADDR_SPACE_SIZE register. Cache DBI and iATU physical addresses in 'struct dw_pcie' so that pcie_qcom.c driver can program these addresses in the PARF_DBI_BASE_ADDR and PARF_ATU_BASE_ADDR registers. Suggested-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> Link: https://lore.kernel.org/linux-pci/20240814220338.1969668-1-quic_pyarlaga@quicinc.com Signed-off-by: Prudhvi Yarlagadda <quic_pyarlaga@quicinc.com> Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> Reviewed-by: Mayank Rana <quic_mrana@quicinc.com>
2024-07-19Merge branch 'pci/controller/qcom'Bjorn Helgaas
- Use devm_clk_bulk_get_all() to get all the clocks from DT to avoid writing out all the clock names (Manivannan Sadhasivam) - Add DT binding and driver support for the SA8775P SoC (Mrinmay Sarkar) - Refactor dw_pcie_edma_find_chip() to enable adding support for Hyper DMA (HDMA) (Manivannan Sadhasivam) - Enable drivers to supply the eDMA channel count since some can't auto detect this (Manivannan Sadhasivam) - Add HDMA support for the SA8775P SoC (Mrinmay Sarkar) - Override the SA8775P NO_SNOOP default to avoid possible memory corruption (Mrinmay Sarkar) - Make sure resources are disabled during PERST# assertion, even if the link is already disabled (Manivannan Sadhasivam) - Vote for the CPU-PCIe ICC (interconnect) path to ensure it stays active even if other drivers don't vote for it (Krishna chaitanya chundru) - Add Operating Performance Points (OPP) to scale performance state based on aggregate link bandwidth to improve SoC power efficiency (Krishna chaitanya chundru) - Return failure instead of success if dev_pm_opp_find_freq_floor() fails (Dan Carpenter) - Avoid an error pointer dereference if dev_pm_opp_find_freq_exact() fails (Dan Carpenter) - Prevent use of uninitialized data in qcom_pcie_suspend_noirq() (Dan Carpenter) * pci/controller/qcom: PCI: qcom: Prevent use of uninitialized data in qcom_pcie_suspend_noirq() PCI: qcom: Prevent potential error pointer dereference PCI: qcom: Fix missing error code in qcom_pcie_probe() PCI: qcom: Add OPP support to scale performance PCI: Bring the PCIe speed to MBps logic to new pcie_dev_speed_mbps() PCI: qcom: Add ICC bandwidth vote for CPU to PCIe path PCI: qcom-ep: Disable resources unconditionally during PERST# assert PCI: qcom-ep: Override NO_SNOOP attribute for SA8775P EP PCI: qcom: Override NO_SNOOP attribute for SA8775P RC PCI: epf-mhi: Enable HDMA for SA8775P SoC PCI: qcom-ep: Add HDMA support for SA8775P SoC PCI: dwc: Pass the eDMA mapping format flag directly from glue drivers PCI: dwc: Skip finding eDMA channels count for HDMA platforms PCI: dwc: Refactor dw_pcie_edma_find_chip() API PCI: qcom-ep: Add support for SA8775P SOC dt-bindings: PCI: qcom-ep: Add support for SA8775P SoC PCI: qcom: Use devm_clk_bulk_get_all() API
2024-07-09PCI: dwc: Add outbound MSG TLPs supportYoshihiro Shimoda
Add "code" and "routing" into struct dw_pcie_ob_atu_cfg for triggering INTx IRQs by iATU in the PCIe endpoint mode in near the future. PCIE_ATU_INHIBIT_PAYLOAD is set to issue TLP type of Msg instead of MsgD. This implementation supports the data-less messages only for now. Link: https://lore.kernel.org/linux-pci/20240418-pme_msg-v8-3-a54265c39742@nxp.com Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> Signed-off-by: Frank Li <Frank.Li@nxp.com> Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> Reviewed-by: Serge Semin <fancer.lancer@gmail.com>
2024-07-09PCI: dwc: Consolidate args of dw_pcie_prog_outbound_atu() into a structureYoshihiro Shimoda
This is a preparation before adding the Msg-type outbound iATU mapping. The respective update will require two more arguments added to __dw_pcie_prog_outbound_atu(). That will make the already complicated function prototype even more hard to comprehend accepting _eight_ arguments. To prevent that and keep the code more-or-less readable, move all the outbound iATU-related arguments to a new config structure: struct dw_pcie_ob_atu_cfg, and pass a pointer to dw_pcie_prog_outbound_atu(). The structure should be locally defined and populated with the outbound iATU settings implied by the caller context. As a result of this change there is no longer need in having the two distinctive methods for the Host and Endpoint outbound iATU setups since the code can directly call the dw_pcie_prog_outbound_atu() method with the config structure populated, so drop dw_pcie_prog_ep_outbound_atu(). [kwilczynski: commit log] Link: https://lore.kernel.org/linux-pci/20240418-pme_msg-v8-2-a54265c39742@nxp.com Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> Signed-off-by: Frank Li <Frank.Li@nxp.com> Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> Reviewed-by: Serge Semin <fancer.lancer@gmail.com>
2024-07-09PCI: dwc: Use msleep() in dw_pcie_wait_for_link()Konrad Dybcio
According to [1], msleep should be used for large sleeps, such as the 100-ish ms one in this function. Comply with the guide and use it. [1] https://docs.kernel.org/timers/timers-howto.html [kwilczynski: commit log] Link: https://lore.kernel.org/linux-pci/20240215-topic-pci_sleep-v2-1-79334884546b@linaro.org Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org> Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Johan Hovold <johan+linaro@kernel.org> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
2024-05-28PCI: dwc: Pass the eDMA mapping format flag directly from glue driversManivannan Sadhasivam
Instead of maintaining a separate capability for glue drivers that cannot support auto detection of the eDMA mapping format, pass the mapping format directly from them. This will simplify the code and also allow adding HDMA support that also doesn't support auto detection of mapping format. Suggested-by: Serge Semin <fancer.lancer@gmail.com> Link: https://lore.kernel.org/linux-pci/20240318-dw-hdma-v5-3-f04c5cdde760@linaro.org Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Serge Semin <fancer.lancer@gmail.com> Reviewed-by: Siddharth Vadapalli <s-vadapalli@ti.com> Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> Tested-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
2024-05-28PCI: dwc: Skip finding eDMA channels count for HDMA platformsManivannan Sadhasivam
In the case of Hyper DMA (HDMA) present in DWC controllers, there is no way the drivers can auto detect the number of read/write channels as like its predecessor embedded DMA (eDMA). So the glue drivers making use of HDMA have to pass the channels count during probe. To accommodate that, skip the existing auto detection of channels count procedure for HDMA based platforms. If the channels count passed by the glue drivers were wrong in any form, then the existing sanity check will catch it. Suggested-by: Serge Semin <fancer.lancer@gmail.com> Link: https://lore.kernel.org/linux-pci/20240318-dw-hdma-v5-2-f04c5cdde760@linaro.org Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Frank Li <frank.li@nxp.com> Reviewed-by: Serge Semin <fancer.lancer@gmail.com> Reviewed-by: Siddharth Vadapalli <s-vadapalli@ti.com> Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
2024-05-28PCI: dwc: Refactor dw_pcie_edma_find_chip() APIManivannan Sadhasivam
In order to add support for Hyper DMA (HDMA), refactor the existing dw_pcie_edma_find_chip() API by moving the common code to separate functions. No functional change. Suggested-by: Serge Semin <fancer.lancer@gmail.com> Link: https://lore.kernel.org/linux-pci/20240318-dw-hdma-v5-1-f04c5cdde760@linaro.org Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Frank Li <frank.li@nxp.com> Reviewed-by: Serge Semin <fancer.lancer@gmail.com> Reviewed-by: Siddharth Vadapalli <s-vadapalli@ti.com> Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
2023-10-23PCI: dwc: Expose dw_pcie_write_dbi2() to moduleYoshihiro Shimoda
Since no PCIe controller drivers call this, this change is not required for now. But, Renesas R-Car Gen4 PCIe controller driver will call this and if the controller driver is built as a kernel module, the following build error happens: ERROR: modpost: "dw_pcie_write_dbi2" [drivers/pci/controller/dwc/pcie-rcar-gen4-host-drv.ko] undefined! So, expose dw_pcie_write_dbi2() for it. Link: https://lore.kernel.org/linux-pci/20230926122431.3974714-8-yoshihiro.shimoda.uh@renesas.com Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org> Reviewed-by: Serge Semin <fancer.lancer@gmail.com>
2023-10-20PCI: dwc: Add EDMA_UNROLL capability flagYoshihiro Shimoda
Renesas R-Car Gen4 PCIe controllers have an unexpected register value in the eDMA CTRL register. So, add a new capability flag "EDMA_UNROLL" which would force the unrolled eDMA mapping for the problematic device. Suggested-by: Serge Semin <fancer.lancer@gmail.com> Link: https://lore.kernel.org/linux-pci/20231018085631.1121289-7-yoshihiro.shimoda.uh@renesas.com Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> Reviewed-by: Serge Semin <fancer.lancer@gmail.com>
2023-10-20PCI: dwc: Add missing PCI_EXP_LNKCAP_MLW handlingYoshihiro Shimoda
Update dw_pcie_link_set_max_link_width() to set PCI_EXP_LNKCAP_MLW. In accordance with the DW PCIe RC/EP HW manuals [1,2,3,...] aside with the PORT_LINK_CTRL_OFF.LINK_CAPABLE and GEN2_CTRL_OFF.NUM_OF_LANES[8:0] field there is another one which needs to be updated. It's LINK_CAPABILITIES_REG.PCIE_CAP_MAX_LINK_WIDTH. If it isn't done at the very least the maximum link-width capability CSR won't expose the actual maximum capability. [1] DesignWare Cores PCI Express Controller Databook - DWC PCIe Root Port, Version 4.60a, March 2015, p.1032 [2] DesignWare Cores PCI Express Controller Databook - DWC PCIe Root Port, Version 4.70a, March 2016, p.1065 [3] DesignWare Cores PCI Express Controller Databook - DWC PCIe Root Port, Version 4.90a, March 2016, p.1057 ... [X] DesignWare Cores PCI Express Controller Databook - DWC PCIe Endpoint, Version 5.40a, March 2019, p.1396 [X+1] DesignWare Cores PCI Express Controller Databook - DWC PCIe Root Port, Version 5.40a, March 2019, p.1266 Suggested-by: Serge Semin <fancer.lancer@gmail.com> Link: https://lore.kernel.org/linux-pci/20231018085631.1121289-4-yoshihiro.shimoda.uh@renesas.com Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> Reviewed-by: Serge Semin <fancer.lancer@gmail.com>
2023-10-20PCI: dwc: Add dw_pcie_link_set_max_link_width()Yoshihiro Shimoda
This is a preparation before adding the Max-Link-width capability setup which would in its turn complete the max-link-width setup procedure defined by Synopsys in the HW-manual. Seeing there is a max-link-speed setup method defined in the DW PCIe core driver it would be good to have a similar function for the link width setup. That's why we need to define a dedicated function first from already implemented but incomplete link-width setting up code. Link: https://lore.kernel.org/linux-pci/20231018085631.1121289-3-yoshihiro.shimoda.uh@renesas.com Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org> Reviewed-by: Manivannan Sadhasivam <mani@kernel.org> Reviewed-by: Serge Semin <fancer.lancer@gmail.com>
2023-08-30Merge tag 'pci-v6.6-changes' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci Pull PCI updates from Bjorn Helgaas: "Enumeration: - Add locking to read/modify/write PCIe Capability Register accessors for Link Control and Root Control - Use pci_dev_id() when possible instead of manually composing ID from dev->bus->number and dev->devfn Resource management: - Move prototypes for __weak sysfs resource files to linux/pci.h to fix 'no previous prototype' warnings - Make more I/O port accesses depend on HAS_IOPORT - Use devm_platform_get_and_ioremap_resource() instead of open-coding platform_get_resource() followed by devm_ioremap_resource() Power management: - Ensure devices are powered up while accessing VPD - If device is powered-up, keep it that way while polling for PME - Only read PCI_PM_CTRL register when available, to avoid reading the wrong register and corrupting dev->current_state Virtualization: - Avoid Secondary Bus Reset on NVIDIA T4 GPUs Error handling: - Remove unused pci_disable_pcie_error_reporting() - Unexport pci_enable_pcie_error_reporting(), used only by aer.c - Unexport pcie_port_bus_type, used only by PCI core VGA: - Simplify and clean up typos in VGA arbiter Apple PCIe controller driver: - Initialize pcie->nvecs (number of available MSIs) before use Broadcom iProc PCIe controller driver: - Use of_property_read_bool() instead of low-level accessors for boolean properties Broadcom STB PCIe controller driver: - Assert PERST# when probing BCM2711 because some bootloaders don't do it Freescale i.MX6 PCIe controller driver: - Add .host_deinit() callback so we can clean up things like regulators on probe failure or driver unload Freescale Layerscape PCIe controller driver: - Add support for link-down notification so the endpoint driver can process LINK_DOWN events - Add suspend/resume support, including manual PME_Turn_off/PME_TO_Ack handshake - Save Link Capabilities during probe so they can be restored when handling a link-up event, since the controller loses the Link Width and Link Speed values during reset Intel VMD host bridge driver: - Fix disable of bridge windows during domain reset; previously we cleared the base/limit registers, which actually left the windows enabled Marvell MVEBU PCIe controller driver: - Remove unused busn member Microchip PolarFlare PCIe controller driver: - Fix interrupt bit definitions so the SEC and DED interrupt handlers work correctly - Make driver buildable as a module - Read FPGA MSI configuration parameters from hardware instead of hard-coding them Microsoft Hyper-V host bridge driver: - To avoid a NULL pointer dereference, skip MSI restore after hibernate if MSI/MSI-X hasn't been enabled NVIDIA Tegra194 PCIe controller driver: - Revert 'PCI: tegra194: Enable support for 256 Byte payload' because Linux doesn't know how to reduce MPS from to 256 to 128 bytes for endpoints below a switch (because other devices below the switch might already be operating), which leads to 'Malformed TLP' errors Qualcomm PCIe controller driver: - Add DT and driver support for interconnect bandwidth voting for 'pcie-mem' and 'cpu-pcie' interconnects - Fix broken SDX65 'compatible' DT property - Configure controller so MHI bus master clock will be switched off while in ASPM L1.x states - Use alignment restriction from EPF core in EPF MHI driver - Add Endpoint eDMA support - Add MHI eDMA support - Add Snapdragon SM8450 support to the EPF MHI driversupport - Add MHI eDMA support - Add Snapdragon SM8450 support to the EPF MHI driversupport - Add MHI eDMA support - Add Snapdragon SM8450 support to the EPF MHI driversupport - Add MHI eDMA support - Add Snapdragon SM8450 support to the EPF MHI driver - Use iATU for EPF MHI transfers smaller than 4K to avoid eDMA setup latency - Add sa8775p DT binding and driver support Rockchip PCIe controller driver: - Use 64-bit mask on MSI 64-bit PCI address to avoid zeroing out the upper 32 bits SiFive FU740 PCIe controller driver: - Set the supported number of MSI vectors so we can use all available MSI interrupts Synopsys DesignWare PCIe controller driver: - Add generic dwc suspend/resume APIs (dw_pcie_suspend_noirq() and dw_pcie_resume_noirq()) to be called by controller driver suspend/resume ops, and a controller callback to send PME_Turn_Off MicroSemi Switchtec management driver: - Add support for PCIe Gen5 devices Miscellaneous: - Reorder and compress to reduce size of struct pci_dev - Fix race in DOE destroy_work_on_stack() - Add stubs to avoid casts between incompatible function types - Explicitly include correct DT includes to untangle headers" * tag 'pci-v6.6-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci: (96 commits) PCI: qcom-ep: Add ICC bandwidth voting support dt-bindings: PCI: qcom: ep: Add interconnects path PCI: qcom-ep: Treat unknown IRQ events as an error dt-bindings: PCI: qcom: Fix SDX65 compatible PCI: endpoint: Add kernel-doc for pci_epc_mem_init() API PCI: epf-mhi: Use iATU for small transfers PCI: epf-mhi: Add support for SM8450 PCI: epf-mhi: Add eDMA support PCI: qcom-ep: Add eDMA support PCI: epf-mhi: Make use of the alignment restriction from EPF core PCI/PM: Only read PCI_PM_CTRL register when available PCI: qcom: Add support for sa8775p SoC dt-bindings: PCI: qcom: Add sa8775p compatible PCI: qcom-ep: Pass alignment restriction to the EPF core PCI: Simplify pcie_capability_clear_and_set_word() control flow PCI: Tidy config space save/restore messages PCI: Fix code formatting inconsistencies PCI: Fix typos in docs and comments PCI: Fix pci_bus_resetable(), pci_slot_resetable() name typos PCI: Simplify pci_dev_driver() ...
2023-07-26Revert "PCI: dwc: Wait for link up only if link is started"Johan Hovold
This reverts commit da56a1bfbab55189595e588f1d984bdfb5cf5924. Bjorn Andersson, Fabio Estevam, Xiaolei Wang, and Jon Hunter reported that da56a1bfbab5 ("PCI: dwc: Wait for link up only if link is started") broke controller probing by returning an error in case the link does not come up during host initialisation, for example when the slot is empty. As explained in commit 886a9c134755 ("PCI: dwc: Move link handling into common code") and as indicated by the comment "Ignore errors, the link may come up later" in the code, waiting for link up and ignoring errors is the intended behaviour: Let's standardize this to succeed as there are usecases where devices (and the link) appear later even without hotplug. For example, a reconfigured FPGA device. Reverting the offending commit specifically fixes a regression on Qualcomm platforms like the Lenovo ThinkPad X13s which no longer reach the interconnect sync state if a slot does not have a device populated (e.g. an optional modem). Note that enabling asynchronous probing by default as was done for Qualcomm platforms by commit c0e1eb441b1d ("PCI: qcom: Enable async probe by default"), should take care of any related boot time concerns. Finally, note that the intel-gw driver is the only driver currently not providing a .start_link() callback and instead starts the link in its .host_init() callback, which may avoid an additional one-second timeout during probe by making the link-up wait conditional. If anyone cares, that can be done in a follow-up patch with a proper motivation. [bhelgaas: add Fabio Estevam, Xiaolei Wang, Jon Hunter reports] Fixes: da56a1bfbab5 ("PCI: dwc: Wait for link up only if link is started") Link: https://lore.kernel.org/r/20230706082610.26584-1-johan+linaro@kernel.org Reported-by: Bjorn Andersson <quic_bjorande@quicinc.com> Signed-off-by: Johan Hovold <johan+linaro@kernel.org> Reported-by: Fabio Estevam <festevam@gmail.com> Link: https://lore.kernel.org/r/20230704122635.1362156-1-festevam@gmail.com/ Reported-by: Xiaolei Wang <xiaolei.wang@windriver.com> Link: https://lore.kernel.org/r/20230705010624.3912934-1-xiaolei.wang@windriver.com/ Reported-by: Jon Hunter <jonathanh@nvidia.com> Link: https://lore.kernel.org/r/6ca287a1-6c7c-7b90-9022-9e73fb82b564@nvidia.com Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> Cc: Sajid Dalvi <sdalvi@google.com> Cc: Ajay Agarwal <ajayagarwal@google.com>
2023-07-18PCI: Explicitly include correct DT includesRob Herring
The DT of_device.h and of_platform.h date back to the separate of_platform_bus_type before it as merged into the regular platform bus. As part of that merge prepping Arm DT support 13 years ago, they "temporarily" include each other. They also include platform_device.h and of.h. As a result, there's a pretty much random mix of those include files used throughout the tree. In order to detangle these headers and replace the implicit includes with struct declarations, users need to explicitly include the correct includes. Link: https://lore.kernel.org/r/20230714174827.4061572-1-robh@kernel.org Signed-off-by: Rob Herring <robh@kernel.org> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
2023-07-06Merge tag 'dmaengine-6.5-rc1' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine Pull dmaengine updates from Vinod Koul: "New support: - TI J721S2 CSI BCDMA support Updates: - Native HDMI support for dw edma driver - ste dma40 updates for supporting proper SRAM handle in DT - removal of dma device chancnt setting in drivers" * tag 'dmaengine-6.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine: (28 commits) dmaengine: sprd: Don't set chancnt dmaengine: hidma: Don't set chancnt dmaengine: plx_dma: Don't set chancnt dmaengine: axi-dmac: Don't set chancnt dmaengine: dw-axi-dmac: Don't set chancnt dmaengine: qcom: bam_dma: allow omitting num-{channels,ees} dmaengine: dw-edma: Add HDMA DebugFS support dmaengine: dw-edma: Add support for native HDMA dmaengine: dw-edma: Create a new dw_edma_core_ops structure to abstract controller operation dmaengine: dw-edma: Rename dw_edma_core_ops structure to dw_edma_plat_ops dmaengine: ste_dma40: use proper format string for resource_size_t dmaengine: make QCOM_HIDMA depend on HAS_IOMEM dmaengine: ste_dma40: fix typo in enum documentation dmaengine: ste_dma40: use correct print specfier for resource_size_t MAINTAINERS: Add myself as the DW eDMA driver reviewer MAINTAINERS: Add Manivannan to DW eDMA driver maintainers list MAINTAINERS: Demote Gustavo Pimentel to DW EDMA driver reviewer dmaengine: ti: k3-udma: Add support for J721S2 CSI BCDMA instance dt-bindings: dma: ti: Add J721S2 BCDMA dmaengine: ti: k3-psil-j721s2: Add PSI-L thread map for main CPSW2G ...
2023-05-26PCI: dwc: Wait for link up only if link is startedAjay Agarwal
In dw_pcie_host_init() regardless of whether the link has been started or not, the code waits for the link to come up. Even in cases where start_link() is not defined the code ends up spinning in a loop for 1 second. Since in some systems dw_pcie_host_init() gets called during probe, this one second loop for each pcie interface instance ends up extending the boot time. Wait for the link up in only if the start_link() is defined. Link: https://lore.kernel.org/r/20230412093425.3659088-1-ajayagarwal@google.com Tested-by: Will McVicker <willmcvicker@google.com> Signed-off-by: Sajid Dalvi <sdalvi@google.com> Signed-off-by: Ajay Agarwal <ajayagarwal@google.com> Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
2023-05-24dmaengine: dw-edma: Rename dw_edma_core_ops structure to dw_edma_plat_opsCai Huoqing
The dw_edma_core_ops structure contains a set of the operations: device IRQ numbers getter, CPU/PCI address translation. Based on the functions semantics the structure name "dw_edma_plat_ops" looks more descriptive since indeed the operations are platform-specific. The "dw_edma_core_ops" name shall be used for a structure with the IP-core specific set of callbacks in order to abstract out DW eDMA and DW HDMA setups. Such structure will be added in one of the next commit in the framework of the set of changes adding the DW HDMA device support. Anyway the renaming was necessary to distinguish two types of the implementation callbacks: 1. DW eDMA/hDMA IP-core specific operations: device-specific CSR setups in one or another aspect of the DMA-engine initialization. 2. DW eDMA/hDMA platform specific operations: the DMA device environment configs like IRQs, address translation, etc. Signed-off-by: Cai Huoqing <cai.huoqing@linux.dev> Reviewed-by: Serge Semin <fancer.lancer@gmail.com> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> Tested-by: Serge Semin <fancer.lancer@gmail.com> Link: https://lore.kernel.org/r/20230520050854.73160-2-cai.huoqing@linux.dev Signed-off-by: Vinod Koul <vkoul@kernel.org>
2023-03-21PCI: dwc: Fix PORT_LINK_CONTROL update when CDM check enabledYoshihiro Shimoda
If CDM_CHECK is enabled (by the DT "snps,enable-cdm-check" property), 'val' is overwritten by PCIE_PL_CHK_REG_CONTROL_STATUS initialization. Commit ec7b952f453c ("PCI: dwc: Always enable CDM check if "snps,enable-cdm-check" exists") did not account for further usage of 'val', so we wrote improper values to PCIE_PORT_LINK_CONTROL when the CDM check is enabled. Move the PCIE_PORT_LINK_CONTROL update to be completely after the PCIE_PL_CHK_REG_CONTROL_STATUS register initialization. [bhelgaas: commit log adapted from Serge's version] Fixes: ec7b952f453c ("PCI: dwc: Always enable CDM check if "snps,enable-cdm-check" exists") Link: https://lore.kernel.org/r/20230310123510.675685-2-yoshihiro.shimoda.uh@renesas.com Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Serge Semin <fancer.lancer@gmail.com>
2023-02-22PCI: dwc: Add Root Port and Endpoint controller eDMA engine supportSerge Semin
Since the DW eDMA core now supports eDMA controllers embedded in locally accessible DW PCIe Root Ports and Endpoints, register these controllers when possible. To do that the DW PCIe core driver needs to perform some preparations first. First of all, it needs to find the eDMA controller CSRs base address, whether they are accessible over the Port Logic or iATU unrolled space. Afterwards it can try to auto-detect the eDMA controller availability and number of read/write channels. If none are found the procedure silently returns without error. Secondly, the platform is supposed to provide either combined or per-channel IRQ signals. If no valid IRQs set is found, the procedure returns without error to be backward compatible with platforms where DW PCIe controllers have eDMA but lack the IRQ description. Finally, before actually probing the eDMA device we need to allocate LLP items buffers. After that the DW eDMA can be registered. If registration is successful, a message regarding the number of detected Read/Write eDMA channels will be printed to the system as is done for the iATU settings. Note: the DW PCI controller driver (either host or endpoint mode) is currently always built-in, so if the DW eDMA core is built as a module (CONFIG_DW_EDMA=m), eDMA controllers will not be registered even if the dw-edma module is later loaded. Link: https://lore.kernel.org/r/20230113171409.30470-28-Sergey.Semin@baikalelectronics.ru Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> Acked-by: Vinod Koul <vkoul@kernel.org>
2022-11-23PCI: dwc: Introduce generic platform clocks and resetsSerge Semin
Currently almost each platform driver uses its own resets and clocks naming in order to get the corresponding descriptors. It makes the code harder to maintain and comprehend especially seeing the DWC PCIe core main resets and clocks signals set hasn't changed much for about at least one major IP-core release. So in order to organize things around these signals we suggest to create a generic interface for them in accordance with the naming introduced in the DWC PCIe IP-core reference manual: Application clocks: - "dbi" - data bus interface clock (on some DWC PCIe platforms it's referred as "pclk", "pcie", "sys", "ahb", "cfg", "iface", "gio", "reg", "pcie_apb_sys"); - "mstr" - AXI-bus master interface clock (some DWC PCIe glue drivers refer to this clock as "port", "bus", "pcie_bus", "bus_master/master_bus/axi_m", "pcie_aclk"); - "slv" - AXI-bus slave interface clock (also called as "port", "bus", "pcie_bus", "bus_slave/slave_bus/axi_s", "pcie_aclk", "pcie_inbound_axi"). Core clocks: - "pipe" - core-PCS PIPE interface clock coming from external PHY (it's normally named by the platform drivers as just "pipe"); - "core" - primary clock of the controller (none of the platform drivers declare such a clock but in accordance with the ref. manual the devices may have it separately specified); - "aux" - auxiliary PMC domain clock (it is named by some platforms as "pcie_aux" and just "aux"); - "ref" - Generic reference clock (it is a generic clock source, which can be used as a signal source for multiple interfaces, some platforms call it as "ref", "general", "pcie_phy", "pcie_phy_ref"). Application resets: - "dbi" - Data-bus interface reset (it's CSR interface clock and is normally called as "apb" though technically it's not APB but DWC PCIe-specific interface); - "mstr" - AXI-bus master reset (some platforms call it as "port", "apps", "bus", "axi_m"); - "slv" - ABI-bus slave reset (some platforms call it as "port", "apps", "bus", "axi_s"). Core resets: - "non-sticky" - non-sticky CSR flags reset; - "sticky" - sticky CSR flags reset; - "pipe" - PIPE-interface (Core-PCS) logic reset (some platforms call it just "pipe"); - "core" - controller primary reset (resets everything except PMC module, some platforms refer to this signal as "soft", "pci"); - "phy" - PCS/PHY block reset (strictly speaking it is normally connected to the input of an external block, but the reference manual says it must be available for the PMC working correctly, some existing platforms call it "pciephy", "phy", "link"); - "hot" - PMC hot reset signal (also called as "sleep"); - "pwr" - cold reset signal (can be referred as "pwr", "turnoff"). Bus reset: - "perst" - PCIe standard signal used to reset the PCIe peripheral devices. As you can see each platform uses it's own naming for basically the same set of the signals. In the framework of this commit we suggest to add a set of the clocks and reset signals resources, corresponding names and identifiers for each denoted entity. At current stage the platforms will be able to use the provided infrastructure to automatically request all these resources and manipulate with them in the Host/EP init callbacks. Alas it isn't that easy to create a common cold/hot reset procedure due to too many platform-specifics in the procedure, like the external flags exposure and the delays requirement. Link: https://lore.kernel.org/r/20221113191301.5526-20-Sergey.Semin@baikalelectronics.ru Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
2022-11-23PCI: dwc: Combine iATU detection proceduresSerge Semin
Since the iATU CSR region is now retrieved in the DW PCIe resources getter there is no much benefits in the iATU detection procedures splitting up. Therefore let's join the iATU unroll/viewport detection procedure with the rest of the iATU parameters detection code. The resultant method will be as coherent as before, while the redundant functions will be eliminated thus producing more readable code. Link: https://lore.kernel.org/r/20221113191301.5526-19-Sergey.Semin@baikalelectronics.ru Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org> Reviewed-by: Rob Herring <robh@kernel.org> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
2022-11-23PCI: dwc: Introduce generic resources getterSerge Semin
Currently the DW PCIe Root Port and Endpoint CSR spaces are retrieved in the separate parts of the DW PCIe core driver. It doesn't really make sense since the both controller types have identical set of the core CSR regions: DBI, DBI CS2 and iATU/eDMA. Thus we can simplify the DW PCIe Host and EP initialization methods by moving the platform-specific registers space getting and mapping into a common method. It gets to be even more justified seeing the CSRs base address pointers are preserved in the common DW PCIe descriptor. Note all the OF-based common DW PCIe settings initialization will be moved to the new method too in order to have a single function for all the generic platform properties handling in single place. A nice side-effect of this change is that the pcie-designware-host.c and pcie-designware-ep.c drivers are cleaned up from all the direct dw_pcie storage modification, which makes the DW PCIe core, Root Port and Endpoint modules more coherent. Link: https://lore.kernel.org/r/20221113191301.5526-18-Sergey.Semin@baikalelectronics.ru Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org> Reviewed-by: Rob Herring <robh@kernel.org>
2022-11-23PCI: dwc: Introduce generic controller capabilities interfaceSerge Semin
Since in addition to the already available iATU unrolled mapping we are about to add a few more DW PCIe platform-specific capabilities (CDM-check and generic clocks/resets resources) let's add a generic interface to set and get the flags indicating their availability. The new interface shall improve maintainability of the platform-specific code. Link: https://lore.kernel.org/r/20221113191301.5526-17-Sergey.Semin@baikalelectronics.ru Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org> Reviewed-by: Rob Herring <robh@kernel.org> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
2022-11-23PCI: dwc: Introduce dma-ranges property support for RC-hostSerge Semin
In accordance with the generic PCIe Root Port DT-bindings the "dma-ranges" property has the same format as the "ranges" property. The only difference is in their semantics. The "dma-ranges" property describes the PCIe-to-CPU memory mapping in opposite to the CPU-to-PCIe mapping of the "ranges" property. Even though the DW PCIe controllers are normally equipped with the internal Address Translation Unit which inbound and outbound tables can be used to implement both properties semantics, it was surprising for me to discover that the host-related part of the DW PCIe driver currently supports the "ranges" property only while the "dma-ranges" windows are just ignored. Having the "dma-ranges" supported in the driver would be very handy for the platforms, that don't tolerate the 1:1 CPU-PCIe memory mapping and require a customized PCIe memory layout. So let's fix that by introducing the "dma-ranges" property support. First of all we suggest to rename the dw_pcie_prog_inbound_atu() method to dw_pcie_prog_ep_inbound_atu() and create a new version of the dw_pcie_prog_inbound_atu() function. Thus we'll have two methods for the RC and EP controllers respectively in the same way as it has been developed for the outbound ATU setup methods. Secondly aside with the memory window index and type the new dw_pcie_prog_inbound_atu() function will accept CPU address, PCIe address and size as its arguments. These parameters define the PCIe and CPU memory ranges which will be used to setup the respective inbound ATU mapping. The passed parameters need to be verified against the ATU ranges constraints in the same way as it is done for the outbound ranges. Finally the DMA-ranges detected for the PCIe controller need to be converted to the inbound ATU entries during the host controller initialization procedure. It will be done in the framework of the dw_pcie_iatu_setup() method. Note before setting the inbound ranges up we need to disable all the inbound ATU entries in order to prevent unexpected PCIe TLPs translations defined by some third party software like bootloaders. Link: https://lore.kernel.org/r/20221113191301.5526-16-Sergey.Semin@baikalelectronics.ru Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org> Reviewed-by: Rob Herring <robh@kernel.org> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
2022-11-10PCI: dwc: Use dev_info for PCIe link down event loggingVidya Sagar
Some of the platforms (like Tegra194 and Tegra234) have open slots and not having an endpoint connected to the slot is not an error. So, changing the macro from dev_err to dev_info to log the event. Link: https://lore.kernel.org/r/20220913101237.4337-1-vidyas@nvidia.com Tested-by: Jon Hunter <jonathanh@nvidia.com> Signed-off-by: Vidya Sagar <vidyas@nvidia.com> Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org> Acked-by: Jon Hunter <jonathanh@nvidia.com> Acked-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
2022-10-27PCI: dwc: Fix n_fts[] array overrunVidya Sagar
commit aeaa0bfe89654 ("PCI: dwc: Move N_FTS setup to common setup") incorrectly uses pci->link_gen in deriving the index to the n_fts[] array also introducing the issue of accessing beyond the boundaries of array for greater than Gen-2 speeds. This change fixes that issue. Link: https://lore.kernel.org/r/20220926111923.22487-1-vidyas@nvidia.com Fixes: aeaa0bfe8965 ("PCI: dwc: Move N_FTS setup to common setup") Signed-off-by: Vidya Sagar <vidyas@nvidia.com> Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org> Reviewed-by: Rob Herring <robh@kernel.org> Acked-by: Jingoo Han <jingoohan1@gmail.com>
2022-08-01PCI: dwc: Validate iATU outbound mappings against hardware constraintsSerge Semin
Make __dw_pcie_prog_outbound_atu() check the requested region base and size against what the hardware can support. Return error if the region is not correctly aligned or of a supported size. [bhelgaas: commit log] Link: https://lore.kernel.org/r/20220624143947.8991-14-Sergey.Semin@baikalelectronics.ru Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Rob Herring <robh@kernel.org> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
2022-08-01PCI: dwc: Add iATU regions size detection procedureSerge Semin
The DWC PCIe RC/EP/DM IP core configuration parameters determine the number of inbound and outbound iATU windows, alignment requirements (which is also the minimum window size), minimum and maximum sizes. If internal ATU is enabled, the former settings are determined by CX_ATU_MIN_REGION_SIZE; the latter are determined by CX_ATU_MAX_REGION_SIZE. Determine the required alignment and maximum size supported by the controller and log it to help verify whether the requested inbound or outbound memory mappings can be fully created. Note 1. The extended iATU regions have been supported since DWC PCIe v4.60a. There is no need in testing the upper limit register availability for the older cores. Note 2. The regions alignment is determined with using the fls() method since the lower four bits of the ATU Limit register can be occupied with the Circular Buffer Increment setting, which can be initialized with zeros. Link: https://lore.kernel.org/r/20220624143947.8991-13-Sergey.Semin@baikalelectronics.ru Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Rob Herring <robh@kernel.org> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
2022-08-01PCI: dwc: Simplify in/outbound iATU setup methodsSerge Semin
Previously __dw_pcie_prog_outbound_atu() duplicated a lot of code between the iatu_unroll_enabled version and the PCIE_ATU_VIEWPORT version: __dw_pcie_prog_outbound_atu if (iatu_unroll_enabled) dw_pcie_prog_outbound_atu_unroll dw_pcie_writel_ob_unroll(PCIE_ATU_UNR_LOWER_BASE, ...) dw_pcie_writel_ob_unroll(PCIE_ATU_UNR_UPPER_BASE, ...) ... return dw_pcie_writel_dbi(PCIE_ATU_VIEWPORT, ...) dw_pcie_writel_dbi(PCIE_ATU_LOWER_BASE, ...) dw_pcie_writel_dbi(PCIE_ATU_UPPER_BASE, ...) ... Unify those by pushing the unroll address computation and viewport selection down into dw_pcie_writel_atu() so we can use the same dw_pcie_writel_atu_ob() accessor for both paths: __dw_pcie_prog_outbound_atu dw_pcie_writel_atu_ob(PCIE_ATU_LOWER_BASE, ...) dw_pcie_writel_atu dw_pcie_select_atu # new if (iatu_unroll_enabled) return pci->atu_base + PCIE_ATU_UNROLL_BASE(...) dw_pcie_writel_dbi(PCIE_ATU_VIEWPORT, ...) return pci->atu_base dw_pcie_write(base + reg) dw_pcie_writel_atu_ob(PCIE_ATU_UPPER_BASE, ...) ... In the non-unroll case, this does involve more MMIO writes to PCIE_ATU_VIEWPORT, but it's mainly in initialization paths and the code simplification is significant. [bhelgaas: commit log, simplify dw_pcie_select_atu()] Link: https://lore.kernel.org/r/20220624143947.8991-12-Sergey.Semin@baikalelectronics.ru Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
2022-08-01PCI: dwc: Drop enum dw_pcie_region_type in favor of PCIE_ATU_REGION_DIR_IB/OBSerge Semin
Previously callers of dw_pcie_disable_atu() supplied enum dw_pcie_region_type (DW_PCIE_REGION_INBOUND, DW_PCIE_REGION_OUTBOUND), which dw_pcie_disable_atu() converted to the PCIE_ATU_REGION_DIR_IB or PCIE_ATU_REGION_DIR_OB values needed to program the ATU registers. Simplify the code by dropping the dw_pcie_region_type enum and passing PCIE_ATU_REGION_DIR_IB or PCIE_ATU_REGION_DIR_OB directly. Reorder dw_pcie_disable_atu() arguments to (dir, index) since "index" indicates an ATU window in the regions of the corresponding direction. [bhelgaas: commit log] Link: https://lore.kernel.org/r/20220624143947.8991-11-Sergey.Semin@baikalelectronics.ru Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Rob Herring <robh@kernel.org> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
2022-08-01PCI: dwc: Drop enum dw_pcie_as_type in favor of PCIE_ATU_TYPE_MEM/IOSerge Semin
Previously dw_pcie_ep_set_bar() converted the BAR PCI_BASE_ADDRESS_SPACE bit to the internal dw_pcie_as_type enum (DW_PCIE_AS_MEM, DW_PCIE_AS_IO) and passed it down to dw_pcie_prog_inbound_atu(), which converted the enum to the PCIE_ATU_TYPE_MEM/PCIE_ATU_TYPE_IO values needed to program the ATU registers. Simplify the code by dropping the dw_pcie_as_type enum and passing PCIE_ATU_TYPE_MEM or PCIE_ATU_TYPE_IO directly. Reorder inbound ATU function arguments to match the outbound functions, with address-related parameters at the end. [bhelgaas: commit log] Link: https://lore.kernel.org/r/20220624143947.8991-10-Sergey.Semin@baikalelectronics.ru Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Rob Herring <robh@kernel.org> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
2022-08-01PCI: dwc: Add macros to compare Synopsys IP core versionsSerge Semin
Add macros to compare DWC IP core versions: dw_pcie_ver_is() dw_pcie_ver_is_ge() dw_pcie_ver_type_is() dw_pcie_ver_type_is_ge() These are along the lines of DWC3_VER_IS() and dw_spi_ver_is(). [bhelgaas: commit log] Link: https://lore.kernel.org/r/20220624143947.8991-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Rob Herring <robh@kernel.org>
2022-08-01PCI: dwc: Read DWC IP core version from registerSerge Semin
Since DWC PCIe v4.70a, the controller version and version type can be read from the PORT_LOGIC.PCIE_VERSION_OFF and PORT_LOGIC.PCIE_VERSION_TYPE_OFF registers respectively. Read the version from those registers and warn if if's different from the version we got from the device tree. We can only read the version after platform-specific drivers have done any DBI-related initialization, such as reference clock activation. [bhelgaas: commit log] Link: https://lore.kernel.org/r/20220624143947.8991-5-Sergey.Semin@baikalelectronics.ru Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Rob Herring <robh@kernel.org> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
2022-08-01PCI: dwc: Use native DWC IP core version representationSerge Semin
Save the DWC IP core version in the same format as the PORT_LOGIC.PCIE_VERSION_OFF register, similar to what other drivers for DWC IP do (dw_spi_hw_init(), dwc3_core_is_valid(), stmmac_hwif_init()). [bhelgaas: trim commit log] Link: https://lore.kernel.org/r/20220624143947.8991-4-Sergey.Semin@baikalelectronics.ru Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Rob Herring <robh@kernel.org> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
2022-08-01PCI: dwc: Log link speed and width if it comes upSerge Semin
Printing just "link up" isn't very informative for PCI Express. Even if the link is up, bus performance can degrade to slower speeds or to narrower width than both Root Port and its partner is capable of. In that case it would be handy to know the link specifications as early as possible. If the link comes up, log the link speed (PCIe generation) and width. Link: https://lore.kernel.org/r/20220624143947.8991-2-Sergey.Semin@baikalelectronics.ru Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Rob Herring <robh@kernel.org> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
2022-07-05PCI: dwc: Organize local variable usageSerge Semin
There are several places in the common DW PCIe code with incoherent local variable usage: a variable is defined and initialized with a structure field, but the structure pointer is dereferenced to access that field anyway; the local variable is defined and initialized but either used just once or not used afterwards in the main part of the subsequent method. It mainly concerns the pcie_port.dev field. Fix that in the relevant places. Link: https://lore.kernel.org/r/20220624143428.8334-12-Sergey.Semin@baikalelectronics.ru Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Rob Herring <robh@kernel.org> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
2022-07-05PCI: dwc: Convert dw_pcie_link_up() to use dw_pcie_readl_dbi()Serge Semin
While the rest of the generic DWC PCIe code uses the dedicated IO-mem accessors, the dw_pcie_link_up() method for some unobvious reason directly calls readl() to get PortLogic.DEBUG1 register content. Since the way the DBI bus is accessed can be platform-specific, use dw_pcie_readl_dbi() instead so dw_pcie_link_up() is slightly more generic. Link: https://lore.kernel.org/r/20220624143428.8334-11-Sergey.Semin@baikalelectronics.ru Tested-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> Reviewed-by: Rob Herring <robh@kernel.org>