- Remove unused struct dw_edma_chip.irq (Frank Li)
- Move eDMA private data from struct dw_edma to struct dw_edma_chip (Frank
Li)
- Convert "struct dw_edma_region rg_region" to "void __iomem *reg_base"
since only the virtual address (not physical address or size) is used
(Frank Li)
- Rename "*_ch_cnt" to "ll_*_cnt" to reflect actual usage (Frank Li)
- Drop dma_slave_config.direction field usage (Serge Semin)
- Fix eDMA Rd/Wr-channels and DMA-direction semantics (Serge Semin)
- Add chip-specific DW_EDMA_CHIP_LOCAL flag to indicate that local eDMA
doesn't require generating MSIs to remote (Frank Li)
- Enable DMA tests for endpoints that support it (Frank Li)
* pci/ctrl/dwc-edma:
PCI: endpoint: Enable DMA tests for endpoints with DMA capabilities
dmaengine: dw-edma: Add support for chip-specific flags
dmaengine: dw-edma: Fix eDMA Rd/Wr-channels and DMA-direction semantics
dmaengine: dw-edma: Drop dma_slave_config.direction field usage
dmaengine: dw-edma: Rename wr(rd)_ch_cnt to ll_wr(rd)_cnt in struct dw_edma_chip
dmaengine: dw-edma: Change rg_region to reg_base in struct dw_edma_chip
dmaengine: dw-edma: Detach the private data and chip info structures
dmaengine: dw-edma: Remove unused irq field in struct dw_edma_chip
- Stop link on host_init errors and de-initialization (Serge Semin)
- Add support for unrolled iATU register space in dw_pcie_disable_atu()
(Serge Semin)
- Disable outbound windows only for controllers that use iATU (Serge Semin)
- Set INCREASE_REGION_SIZE flag based on limit address, not on the size,
since even a small size may cross a 4GB boundary (Serge Semin)
- Deallocate EPC memory on dw_pcie_ep_init() errors to avoid a leak (Serge
Semin)
- Always enable CDM check if "snps,enable-cdm-check" exists instead of
exiting early if the optional "num-lanes" was absent (Serge Semin)
- Simplify detection of whether we're using unrolled iATU registers (Serge
Semin)
- Make dw_pcie_link_up() more generic by using dw_pcie_readl_dbi() instead
of readl() (Serge Semin)
- Add dw_pcie_start_link() and dw_pcie_stop_link() wrappers to factor out
checks for ops being implemented (Serge Semin)
- Move io_cfg_atu_shared to struct pcie_port and rename to cfg0_io_shared,
since it's not used by dwc common code or dwc endpoint code (Serge Semin)
- Rename struct pcie_port to dw_pcie_rp to indicate that it's
DesignWare-specific (Serge Semin)
- Drop unused struct dw_plat_pcie regmap pointer (Serge Semin)
- Fix some coding style issues (Serge Semin)
- Log link speed and width if it comes up (Serge Semin)
- Save DWC IP core version in native format as read from
PORT_LOGIC.PCIE_VERSION_OFF register (Serge Semin)
- Read DWC IP core version from PORT_LOGIC.PCIE_VERSION_OFF (Serge Semin)
- Add macros to compare Synopsys IP core versions (Serge Semin)
- Drop manual DWC IP core version setup from intel-gw and tegra194 (Serge
Semin)
- Add dw_pcie_ops.host_deinit() callback (Serge Semin)
- Drop enum dw_pcie_as_type in favor of PCIE_ATU_TYPE_MEM/IO (Serge Semin)
- Drop enum dw_pcie_region_type in favor of PCIE_ATU_REGION_DIR_IB/OB
(Serge Semin)
- Simplify in/outbound iATU setup methods and reduce duplicated code (Serge
Semin)
- Detect iATU region size from hardware (Serge Semin)
- Validate iATU outbound mappings against hardware constraints (Serge
Semin)
- Check for errors in iATU setup (Serge Semin)
- Allocate a 32-bit DMA-able page to be MSI target instead of using a
driver data structure that may not be addressable with 32-bit address
(Will McVicker)
- Use the bitmap API to allocate bitmaps instead of open-coding it
(Christophe JAILLET)
- Correct dw_pcie_free_msi() checking for when to remove IRQ handler and
data (Dmitry Baryshkov)
- Split MSI init to new dw_pcie_msi_host_init() function (Dmitry Baryshkov)
- Convert struct pcie_port.msi_irq to an array so we can support more than
32 MSI interrupts (Dmitry Baryshkov)
- Handle MSIs routed to multiple GIC interrupts for Qualcomm platforms with
groups of 32 MSI vectors (Dmitry Baryshkov)
- Add additional MSI interrupts to qcom DT (Dmitry Baryshkov)
* pci/ctrl/dwc:
dt-bindings: PCI: qcom: Support additional MSI vectors
PCI: dwc: Handle MSIs routed to multiple GIC interrupts
PCI: dwc: Convert struct pcie_port.msi_irq to an array
PCI: dwc: Split MSI IRQ parsing/allocation to a separate function
PCI: dwc: Correct msi_irq condition in dw_pcie_free_msi()
PCI: dwc: Use the bitmap API to allocate bitmaps
PCI: dwc: Fix MSI msi_msg DMA mapping
PCI: dwc: Check iATU in/outbound range setup status
PCI: dwc: Validate iATU outbound mappings against hardware constraints
PCI: dwc: Add iATU regions size detection procedure
PCI: dwc: Simplify in/outbound iATU setup methods
PCI: dwc: Drop enum dw_pcie_region_type in favor of PCIE_ATU_REGION_DIR_IB/OB
PCI: dwc: Drop enum dw_pcie_as_type in favor of PCIE_ATU_TYPE_MEM/IO
PCI: dwc: Add dw_pcie_ops.host_deinit() callback
PCI: tegra194: Drop manual DW PCIe controller version setup
PCI: intel-gw: Drop manual DW PCIe controller version setup
PCI: dwc: Add macros to compare Synopsys IP core versions
PCI: dwc: Read DWC IP core version from register
PCI: dwc: Use native DWC IP core version representation
PCI: dwc: Detect iATU settings after getting "addr_space" resource
PCI: dwc: Log link speed and width if it comes up
PCI: dwc-plat: Drop dw_plat_pcie_of_match[] forward declaration
PCI: dwc-plat: Drop unused regmap pointer
PCI: dwc-plat: Simplify dw_plat_pcie_probe() return values
PCI: dwc: Rename struct pcie_port to dw_pcie_rp
PCI: dwc: Move io_cfg_atu_shared to struct pcie_port
PCI: dwc: Add start_link/stop_link inlines
PCI: dwc: Reuse local pointer to the resource data
PCI: dwc: Organize local variable usage
PCI: dwc: Convert dw_pcie_link_up() to use dw_pcie_readl_dbi()
PCI: dwc: Simplify unrolled iATU detection
PCI: dwc: Add newlines to log messages
PCI: dwc: Add braces to multi-line if-else statements
PCI: dwc: Always enable CDM check if "snps,enable-cdm-check" exists
PCI: dwc: Deallocate EPC memory on dw_pcie_ep_init() errors
PCI: dwc: Set INCREASE_REGION_SIZE flag based on limit address
PCI: dwc: Disable outbound windows only for controllers using iATU
PCI: dwc: Add unroll iATU space support to dw_pcie_disable_atu()
PCI: dwc: Stop link on host_init errors and de-initialization
- Remove unnecessary forward declarations (Jim Quinlan)
- Prevent config space access when link is down (Jim Quinlan)
- Split post-link up initialization to brcm_pcie_start_link() (Jim Quinlan)
- Enable child bus device regulators described under Root Ports in DT (Jim
Quinlan)
- Disable/enable regulators in suspend/resume (Jim Quinlan)
- Rename .map_bus() functions to end with 'map_bus' as they do in other
drivers (Jim Quinlan)
* pci/ctrl/brcmstb:
PCI: brcmstb: Rename .map_bus() functions to end with 'map_bus'
PCI: brcmstb: Disable/enable regulators in suspend/resume
PCI: brcmstb: Enable child bus device regulators from DT
PCI: brcmstb: Split post-link up initialization to brcm_pcie_start_link()
PCI: brcmstb: Prevent config space access when link is down
PCI: brcmstb: Remove unnecessary forward declarations
- Add support for AER capability on emulated bridge (Pali Rohár)
- Add support for Slot capability on emulated bridge (Pali Rohár)
* pci/ctrl/aardvark:
PCI: aardvark: Fix reporting Slot capabilities on emulated bridge
PCI: aardvark: Add support for AER registers on emulated bridge
- Replace sparc pci_mmap_page_range() wrapper. This still leaves a
sparc-specific pci_mmap_resource_range(), but it's only one interface
instead of two (Arnd Bergmann)
- Remove sparc-specific pci_mmap_resource_range() by implementing
pci_iobar_pfn(). This removes the ability to map the entire PCI I/O
space using /proc/bus/pci, but we believe that's already been broken
since v2.6.28 (Arnd Bergmann)
* pci/resource:
sparc: Use generic pci_mmap_resource_range()
PCI: Remove pci_mmap_page_range() wrapper
- Recognize disconnected devices so we don't bother trying to set them to
"frozen" or "normal" state (Christoph Hellwig)
- Clear PCI Status register during enumeration in case firmware left errors
logged (Kai-Heng Feng)
- Configure ECRC for every device, including hot-added ones (Stefan Roese)
- Keep AER error reporting enabled for switches (Stefan Roese)
- Enable error reporting for all devices that support AER (Stefan Roese)
- Iterate over error counters instead of error strings to avoid printing
junk in AER sysfs counters (Mohamed Khalfella)
* pci/err:
PCI/AER: Iterate over error counters instead of error strings
PCI/AER: Enable error reporting when AER is native
PCI/portdrv: Don't disable AER reporting in get_port_device_capability()
PCI/AER: Configure ECRC for every device
PCI: Clear PCI_STATUS when setting up device
PCI/ERR: Recognize disconnected devices in report_error_detected()
- Split out ARI "next function" handling from the traditional one (Niklas
Schnelle)
- Move jailhouse "isolated function" (non-zero functions where function 0
doesn't exist) handling to pci_scan_slot() to avoid duplicating
multi-function scanning in pci_scan_child_bus_extend() (Niklas Schnelle)
- Extend "isolated function" probing to s390 (Niklas Schnelle).
- Allow s390 zPCI zbus without a function 0 (Niklas Schnelle)
* pci/enumeration:
s390/pci: allow zPCI zbus without a function zero
PCI: Extend isolated function probing to s390
PCI: Move jailhouse's isolated function handling to pci_scan_slot()
PCI: Split out next_ari_fn() from next_fn()
PCI: Clean up pci_scan_slot()
On Qualcomm platforms each group of 32 MSI vectors is routed to the
separate GIC interrupt. Document mapping of additional interrupts.
Link: https://lore.kernel.org/r/20220707134733.2436629-6-dmitry.baryshkov@linaro.org
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Reviewed-by: Rob Herring <robh@kernel.org>
Reviewed-by: Johan Hovold <johan+linaro@kernel.org>
Acked-by: Stanimir Varbanov <svarbanov@mm-sol.com>
On some Qualcomm platforms each group of 32 MSI vectors is routed to a
separate GIC interrupt. Implement support for such configurations by
parsing "msi0" ... "msiX" interrupts and attaching them to the chained
handler.
Note that if DT doesn't list an array of MSI interrupts and uses a single
"msi" IRQ, the driver will limit the number of supported MSI vectors to 32.
Link: https://lore.kernel.org/r/20220707134733.2436629-5-dmitry.baryshkov@linaro.org
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Rob Herring <robh@kernel.org>
Reviewed-by: Johan Hovold <johan+linaro@kernel.org>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
The Qualcomm DWC PCIe controller supports more than 32 MSI interrupts, but
they are routed to separate interrupts in groups of 32 vectors. To support
this configuration, change the msi_irq field to an array. Let the DWC core
handle all interrupts that were set in this array.
[bhelgaas: reorder, drop "irq" temporary to make patch cleaner]
Link: https://lore.kernel.org/r/20220707134733.2436629-3-dmitry.baryshkov@linaro.org
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Rob Herring <robh@kernel.org>
Reviewed-by: Johan Hovold <johan+linaro@kernel.org>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Split handling of MSI host IRQs to a separate dw_pcie_msi_host_init()
function. The code is complex enough to warrant a separate function.
[bhelgaas: reorder patch earlier]
Link: https://lore.kernel.org/r/20220707134733.2436629-4-dmitry.baryshkov@linaro.org
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Rob Herring <robh@kernel.org>
Reviewed-by: Johan Hovold <johan+linaro@kernel.org>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
The dwc-based drivers set pp->msi_irq to -ENODEV if they do not want the
dwc core to do anything with pp->msi_irq.
dw_pcie_host_init() sets the handler and data when "pp->msi_irq > 0", so
use the same condition when removing the handler and data in
dw_pcie_free_msi().
Link: https://lore.kernel.org/r/20220707134733.2436629-2-dmitry.baryshkov@linaro.org
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Rob Herring <robh@kernel.org>
Reviewed-by: Johan Hovold <johan+linaro@kernel.org>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
As of 07940c369a ("PCI: dwc: Fix MSI page leakage in suspend/resume"),
the PCIe designware host driver has been using the driver data allocation
for the msi_msg DMA mapping which can result in a DMA_MAPPING_ERROR due to
the DMA overflow check in dma_direct_map_page() when the address is greater
than 32 bits (reported in [1]). The commit was trying to address a memory
leak on suspend/resume by moving the MSI mapping to dw_pcie_host_init(),
but subsequently dropped the page allocation thinking it wasn't needed.
To fix the DMA mapping issue as well as make msi_msg DMA'able, switch back
to allocating a 32-bit page for the msi_msg. To avoid the suspend/resume
leak, allocate the page in dw_pcie_host_init() since that shouldn't be
called during suspend/resume.
[1] https://lore.kernel.org/all/Yo0soniFborDl7+C@google.com/
Signed-off-by: Will McVicker <willmcvicker@google.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Rob Herring <robh@kernel.org>
Make the DWC PCIe RC/EP safer and more verbose for invalid or failed
inbound and outbound iATU window setups. Silently ignoring iATU regions
setup errors may cause unpredictable errors. For instance if a cfg or IO
window fails to be activated, then any CFG/IO requested won't reach target
PCIe devices and the corresponding accessors will return platform-specific
random values.
[bhelgaas: trim commit log]
Link: https://lore.kernel.org/r/20220624143947.8991-15-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>
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>
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>
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>
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>
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>
dw_pcie_host_init() calls the dw_pcie_ops.host_init() callback to do
platform-specific host initialization.
Add a dw_pcie_ops.host_deinit() callback to perform the corresponding
cleanups in dw_pcie_host_deinit() and in dw_pcie_host_init() failure paths.
Link: https://lore.kernel.org/r/20220624143947.8991-9-Sergey.Semin@baikalelectronics.ru
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>
Since the DW PCIe common code (dw_pcie_version_detect()) now reads the IP
core version directly from the hardware, there is no point manually setting
the version for controllers newer than v4.70a.
Tegra194 only supports v4.90a, so remove the now-superfluous code that sets
struct dw_pcie.version.
Suggested-by: Rob Herring <robh@kernel.org>
Link: https://lore.kernel.org/r/20220624143947.8991-8-Sergey.Semin@baikalelectronics.ru
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>
Since the DW PCIe common code (dw_pcie_version_detect()) now reads the IP
core version directly from the hardware, there is no point manually setting
the version for controllers newer than v4.70a.
Remove the now-superfluous intel-gw code that sets struct dw_pcie.version.
Suggested-by: Rob Herring <robh@kernel.org>
Link: https://lore.kernel.org/r/20220624143947.8991-7-Sergey.Semin@baikalelectronics.ru
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>
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>
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>
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>
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>
The main feature of the sparc-specific implementation of
pci_mmap_resource_range() is that it allows mapping the entire PCI I/O
space for a PCI host bridge using the /proc/bus/pci interface on a bridge
device.
The generic implementation cannot do this, but it also appears that this
got broken for sparc by commit 9eff02e204 ("PCI: check mmap range of
/proc/bus/pci files too"), which enforces that each address is part of a
BAR for kernels after 2.6.28.
Remove it all, assuming that the corresponding user space code has already
been changed to access /dev/ioport instead a long time ago. Add
pci_iobar_pfn() to make it possible to map I/O resources. This is adapted
from the powerpc version.
Link: https://lore.kernel.org/lkml/1519887203.622.3.camel@infradead.org/t/
Link: https://lore.kernel.org/r/20220715153617.3393420-2-arnd@kernel.org
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
The ARCH_GENERIC_PCI_MMAP_RESOURCE symbol came up in a recent discussion,
and I noticed that this was left behind by an unfinished cleanup from 2017.
The only architecture that still relies on providing its own
pci_mmap_page_range() helper instead of using the generic
pci_mmap_resource_range() is sparc. Presumably the reasons for this have
not changed, but at least this can be simplified by converting sparc to use
the same interface as the others.
The only difference between the two is the device-specific offset that gets
added to or subtracted from vma->vm_pgoff.
Change the only caller of pci_mmap_page_range() in common code to subtract
this offset and call the modern interface, while adding it back in the
sparc implementation to preserve the existing behavior.
This removes the complexities of the dual interfaces from the common code,
and keeps it all specific to the sparc architecture code. According to
David Miller, the sparc code lets user space poke into the VGA I/O port
registers by mmapping the I/O space of the parent bridge device, which is
something that the generic pci_mmap_resource_range() code apparently does
not.
Link: https://lore.kernel.org/lkml/1519887203.622.3.camel@infradead.org/t/
Link: https://lore.kernel.org/lkml/20220714214657.2402250-3-shorne@gmail.com/
Link: https://lore.kernel.org/r/20220715153617.3393420-1-arnd@kernel.org
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: David S. Miller <davem@davemloft.net>
Cc: Stafford Horne <shorne@gmail.com>
Rename the .map_bus() functions to end with 'map_bus' so they're easy to
find with, e.g., 'git grep "^static.*_map_bus" drivers/pci/'.
[bhelgaas: rename brcm_pcie_map_bus32() to brcm7425_pcie_map_bus() for
better cscope-ability (".*_map_bus" is not the same as ".*_map_bus.*")]
Link: https://lore.kernel.org/r/20220725151258.42574-8-jim2101024@gmail.com
Signed-off-by: Jim Quinlan <jim2101024@gmail.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Florian Fainelli <f.fainelli@gmail.com>
If we found power regulators for a device below the Root Port, disable them
during suspend and re-enable them during resume.
If any downstream device can be a wakeup device, do not turn off the
regulators as the device will need them on.
[bhelgaas: drop unused regulator_oops, skip wrapping of .add_bus()/
.remove_bus(), move brcm_pcie_start_link() to .add_bus() in previous patch,
squash WOL checking into this patch]
Link: https://lore.kernel.org/r/20220725151258.42574-6-jim2101024@gmail.com
Link: https://lore.kernel.org/r/20220725151258.42574-7-jim2101024@gmail.com
Signed-off-by: Jim Quinlan <jim2101024@gmail.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Florian Fainelli <f.fainelli@gmail.com>
Some platforms have power regulators for slots or devices below Root Ports.
On platforms like Raspberry Pi 4, these regulators are described in the
Root Port device tree node, since they logically belong to the Root Port,
not to the host bridge itself.
Add an .add_bus() hook (called when pci_alloc_child_bus() allocates the
secondary ("child") bus for a bridge), and look for such regulators. If we
find some, enable them before bringing up the link and enumerating devices
on the child bus.
Similarly, when pci_remove_bus() calls the ops->remove_bus() hook, disable
the regulators.
The regulators that may be described in a Root Port DT device are:
vpcie3v3
vpcie3v3aux
vpcie12v
These control power to the device downstream from the Root Port.
[bhelgaas: commit log, name hooks brcm_pcie_add_bus(), etc, since we only
support one set of subregulator info, save info in struct brcm_pcie instead
of dev->driver_data, move brcm_pcie_start_link() from probe to .add_bus()
(from subsequent patch)]
Link: https://lore.kernel.org/r/20220725151258.42574-5-jim2101024@gmail.com
Signed-off-by: Jim Quinlan <jim2101024@gmail.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Florian Fainelli <f.fainelli@gmail.com>
Previously brcm_pcie_setup() initialized the Root Port itself as well as
doing the actual link-up. Split brcm_pcie_setup() into two functions:
- brcm_pcie_setup(), which initializes everything that does not require
the link itself to be up, and
- brcm_pcie_start_link(), which brings up the link and initializes things
that depend on the link being up.
[bhelgaas: condense commit log, deferring details for future changes]
Link: https://lore.kernel.org/r/20220725151258.42574-3-jim2101024@gmail.com
Signed-off-by: Jim Quinlan <jim2101024@gmail.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Florian Fainelli <f.fainelli@gmail.com>
When the link is down, config accesses to downstream devices cause CPU
aborts. Allow config accesses only when the link is up.
As the following scenario shows, this check is racy and cannot completely
avoid CPU aborts, but it makes them less likely:
pci_generic_config_read
addr = brcm_pcie_map_conf # bus->ops->map_bus()
brcm_pcie_link_up # returns "true"; link is up
<link goes down>
*val = readb(addr) # link is now down
<CPU abort>
Note that config space accesses to the Root Port are not affected by link
status.
[bhelgaas: commit log, use PCIE_ECAM_REG() instead of magic 0xfff masks;
note that pci_generic_config_read32() masks low two bits already]
Link: https://lore.kernel.org/r/20220725151258.42574-4-jim2101024@gmail.com
Signed-off-by: Jim Quinlan <jim2101024@gmail.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Florian Fainelli <f.fainelli@gmail.com>
Remove forward function declarations in this driver. Also move some
constant structure definitions lower in the file. There are no changes to
the code that has been moved.
Link: https://lore.kernel.org/r/20220725151258.42574-2-jim2101024@gmail.com
Signed-off-by: Jim Quinlan <jim2101024@gmail.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Florian Fainelli <f.fainelli@gmail.com>
Currently the zPCI code blocks PCI bus creation and probing of a zPCI zbus
unless there is a PCI function with devfn 0. This is always the case for
the PCI functions with hidden RID, but may keep PCI functions from a
multi-function PCI device with RID information invisible until the function
0 becomes visible. Worse, as a PCI bus is necessary to even present a PCI
hotplug slot, even that remains invisible.
With the probing of these so-called isolated PCI functions enabled for s390
in common code, this restriction is no longer necessary. On network cards
with multiple ports and a PF per port this also allows using each port on
its own while still providing the physical PCI topology information in the
devfn needed to associate VFs with their parent PF.
Link: https://lore.kernel.org/r/20220628143100.3228092-6-schnelle@linux.ibm.com
Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Pierre Morel <pmorel@linux.ibm.com>
Like the jailhouse hypervisor, s390's PCI architecture allows passing
isolated PCI functions to a guest OS instance. As of now this is was not
utilized even with multi-function support as the s390 PCI code makes sure
that only virtual PCI busses including a function with devfn 0 are
presented to the PCI subsystem. A subsequent change will remove this
restriction.
Allow probing such functions by replacing the existing check for
jailhouse_paravirt() with a new hypervisor_isolated_pci_functions() helper.
Link: https://lore.kernel.org/r/20220628143100.3228092-5-schnelle@linux.ibm.com
Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Pierre Morel <pmorel@linux.ibm.com>
Cc: Jan Kiszka <jan.kiszka@siemens.com>
The special case of the jailhouse hypervisor passing through individual PCI
functions handles scanning for PCI functions even if function 0 does not
exist. Previously this was done with an extra loop duplicating the one in
pci_scan_slot(). By incorporating the check for jailhouse_paravirt() into
pci_scan_slot() we can instead do this as part of the normal slot scan.
Note that with the assignment of dev->multifunction gated by fn > 0 we set
dev->multifunction unconditionally for all functions if function 0 is
missing just as in the existing jailhouse loop.
The only functional change is that we now call pcie_aspm_init_link_state()
for these functions, but this already happened if function 0 was passed
through and should not be a problem.
Link: https://lore.kernel.org/linux-pci/20220408224514.GA353445@bhelgaas/
Suggested-by: Bjorn Helgaas <bhelgaas@google.com>
Link: https://lore.kernel.org/r/20220628143100.3228092-4-schnelle@linux.ibm.com
Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Pierre Morel <pmorel@linux.ibm.com>
Cc: Jan Kiszka <jan.kiszka@siemens.com>
In commit b1bd58e448 ("PCI: Consolidate "next-function" functions") the
next_fn() function subsumed the traditional and ARI-based next function
determination. This got rid of some needlessly complex function pointer
handling but also reduced the separation between these very different
methods of finding the next function. With the next_fn() cleaned up a bit
we can re-introduce this separation by moving out the ARI handling while
sticking with direct function calls.
Link: https://lore.kernel.org/r/20220628143100.3228092-3-schnelle@linux.ibm.com
Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Pierre Morel <pmorel@linux.ibm.com>
While determining the next PCI function is factored out of pci_scan_slot()
into next_fn(), the former still handles the first function as a special
case, which duplicates the code from the scan loop.
Furthermore the non-ARI branch of next_fn() is generally hard to understand
and especially the check for multifunction devices is hidden in the
handling of NULL devices for non-contiguous multifunction. It also signals
that no further functions need to be scanned by returning 0 via wraparound
and this is a valid function number.
Improve upon this by transforming the conditions in next_fn() to be easier
to understand.
By changing next_fn() to return -ENODEV instead of 0 when there is no next
function we can then handle the initial function inside the loop and
deduplicate the shared handling. This also makes it more explicit that only
function 0 must exist.
No functional change is intended.
Link: https://lore.kernel.org/r/20220628143100.3228092-2-schnelle@linux.ibm.com
Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: Jan Kiszka <jan.kiszka@siemens.com>
Previously we iterated over AER stat *names*, e.g.,
aer_correctable_error_string[32], but the actual stat *counters* may not be
that large, e.g., pdev->aer_stats->dev_cor_errs[16], which means that we
printed junk in the sysfs stats files.
Iterate over the stat counter arrays instead of the names to avoid this
junk.
Also, added a build time check to make sure all
counters have entries in strings array.
Fixes: 0678e3109a ("PCI/AER: Simplify __aer_print_error()")
Link: https://lore.kernel.org/r/20220509181441.31884-1-mkhalfella@purestorage.com
Reported-by: Meeta Saggi <msaggi@purestorage.com>
Signed-off-by: Mohamed Khalfella <mkhalfella@purestorage.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Meeta Saggi <msaggi@purestorage.com>
Reviewed-by: Eric Badger <ebadger@purestorage.com>
Cc: stable@vger.kernel.org
If we have native control of AER, set the following error reporting enable
bits:
- Correctable Error Reporting Enable
- Non-Fatal Error Reporting Enable
- Fatal Error Reporting Enable
- Unsupported Request Reporting Enable
Note that these bits are all in the Device Control register and are not
AER-specific.
This affects all devices with an AER capability, including hot-added
devices.
Please note that this change is quite invasive, as error reporting now will
be enabled for all available PCIe Endpoints, which was previously not the
case.
When "pci=noaer" is selected, error reporting stays disabled of course.
[bhelgaas: commit log, note error reporting is not AER-specific]
Link: https://lore.kernel.org/r/20220125071820.2247260-4-sr@denx.de
Signed-off-by: Stefan Roese <sr@denx.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Pali Rohár <pali@kernel.org>
Cc: Bharat Kumar Gogada <bharat.kumar.gogada@xilinx.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Yao Hongbo <yaohongbo@linux.alibaba.com>
Cc: Naveen Naidu <naveennaidu479@gmail.com>
AER reporting is currently disabled in the DevCtl registers of all non Root
Port PCIe devices on systems using pcie_ports_native || host->native_aer,
disabling AER completely in such systems. This is because 2bd50dd800
("PCI: PCIe: Disable PCIe port services during port initialization"), added
a call to pci_disable_pcie_error_reporting() *after* the AER setup was
completed for the PCIe device tree.
Here a longer analysis about the current status of AER enabling /
disabling upon bootup provided by Bjorn:
pcie_portdrv_probe
pcie_port_device_register
get_port_device_capability
pci_disable_pcie_error_reporting
clear CERE NFERE FERE URRE # <-- disable for RP USP DSP
pcie_device_init
device_register # new AER service device
aer_probe
aer_enable_rootport # RP only
set_downstream_devices_error_reporting
set_device_error_reporting # self (RP)
if (RP || USP || DSP)
pci_enable_pcie_error_reporting
set CERE NFERE FERE URRE # <-- enable for RP
pci_walk_bus
set_device_error_reporting
if (RP || USP || DSP)
pci_enable_pcie_error_reporting
set CERE NFERE FERE URRE # <-- enable for USP DSP
In a typical Root Port -> Endpoint hierarchy, the above:
- Disables Error Reporting for the Root Port,
- Enables Error Reporting for the Root Port,
- Does NOT enable Error Reporting for the Endpoint because it is not a
Root Port or Switch Port.
In a deeper Root Port -> Upstream Switch Port -> Downstream Switch
Port -> Endpoint hierarchy:
- Disables Error Reporting for the Root Port,
- Enables Error Reporting for the Root Port,
- Enables Error Reporting for both Switch Ports,
- Does NOT enable Error Reporting for the Endpoint because it is not a
Root Port or Switch Port,
- Disables Error Reporting for the Switch Ports when pcie_portdrv_probe()
claims them. AER does not re-enable it because these are not Root
Ports.
Remove this call to pci_disable_pcie_error_reporting() from
get_port_device_capability(), leaving the already enabled AER configuration
intact. With this change, AER is enabled in the Root Port and the PCIe
switch upstream and downstream ports. Only the PCIe Endpoints don't have
AER enabled yet. A follow-up patch will take care of this Endpoint
enabling.
Fixes: 2bd50dd800 ("PCI: PCIe: Disable PCIe port services during port initialization")
Link: https://lore.kernel.org/r/20220125071820.2247260-3-sr@denx.de
Signed-off-by: Stefan Roese <sr@denx.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Pali Rohár <pali@kernel.org>
Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
Cc: Bharat Kumar Gogada <bharat.kumar.gogada@xilinx.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Yao Hongbo <yaohongbo@linux.alibaba.com>
Cc: Naveen Naidu <naveennaidu479@gmail.com>
pcie_aspm_support_enabled() is used only by the acpi/pci_root.c driver,
which cannot be built as a module, so it does not need to be exported.
Unexport it.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Some PCI Endpoint controllers integrate an eDMA (embedded DMA). eDMA can
bypass the outbound memory address translation unit to access all RC memory
space.
Add eDMA support for pci-epf-test.
Depending on HW availability, the EPF test can use either eDMA or general
system DMA controllers to perform DMA. The test tries to use eDMA first and
falls back to general system DMA controllers if there's no eDMA
Separate dma_chan to dma_chan_tx and dma_chan_rx. Search for an eDMA
channel first, then search for a memory-to-memory DMA channel. If general
memory to memory channels are used, dma_chan_rx = dma_chan_tx.
Add dma_addr_t dma_remote in pci_epf_test_data_transfer() because eDMA uses
remote RC physical address directly.
Add enum dma_transfer_direction dir in pci_epf_test_data_transfer() because
eDMA chooses the correct RX/TX channel by dir.
The overall steps are:
1. Execute dma_request_channel() and filter function to find correct eDMA
RX and TX Channel. If a channel does not exist, fallback to try to
allocate general memory to memory DMA channel.
2. Execute dmaengine_slave_config() to configure remote side physical
address.
3. Execute dmaengine_prep_slave_single() to create transfer descriptor.
4. Execute tx_submit().
5. Execute dma_async_issue_pending()
[bhelgaas: squash in fix from Dan Carpenter <dan.carpenter@oracle.com>:
https://lore.kernel.org/r/Ys2GSTnZhuLzzQG5@kili, also previously posted by
Peng Wu <wupeng58@huawei.com>:
https://lore.kernel.org/all/CANXvt5rK98-cEMgpzopY9POOK8a5=VDib8uKPLgJakOG=hRfwQ@mail.gmail.com/]
Link: https://lore.kernel.org/r/20220524152159.2370739-9-Frank.Li@nxp.com
Signed-off-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Acked-by: Kishon Vijay Abraham I <kishon@ti.com>
Acked-By: Vinod Koul <vkoul@kernel.org>