forked from mirrors/linux
pci-v6.16-changes
-----BEGIN PGP SIGNATURE-----
iQJIBAABCgAyFiEEgMe7l+5h9hnxdsnuWYigwDrT+vwFAmhAa9EUHGJoZWxnYWFz
QGdvb2dsZS5jb20ACgkQWYigwDrT+vyA3w//aX8d73z/xVxkYLMN/6XQA5fdmd4d
Dv4n0Pjf0WCMKbsgRCdXEYLvcHV8VhH5iCR/b2UsFm9LjxSIRuqE5XosY3bNhrHn
xVKEh2prq2XZOibWrFkJ+RZ0FF7Ogq1Uy5gUBbBHbE1q1byZzrOALaF3FWGaDIZQ
6QLLAFtd3UtqOOUu8J8P9N15uFR8gunyfuM9U7TLMcy4B8txk6T6m/9xAWtRURuJ
I6WN8lO+g8Nl2mL9m27+wyWiVT3tKqoMwp8rVtym/L5JQOmHycYhn0WQAr2dPCMs
Xbgmoeei0je7mZvk5btpt68NAKQ3ZnCVkxbbINBkUxAjI0dbI6h37EhW18ShYVUk
CCo4fmaFtwP8qNN9tSvDN8vZdGB44fN5tIz4lmGzKk5gt+oV50RC/APrzC+PJBQ0
+2SdDVKj71Gr2H1VnI6uLB7oQ+tp7TOdhg+DGV4bdc6QFnsM+BpKWRq5f1UQcau/
XVDmorM/2t6z0DNktAv3NFwSodUjk1loWESr/pRBH1AqAWZTK98PWIg97XYsal59
zbJ3dLrnCqUNozeVgjtZo1LWD2FZaVTvhq2NY7D+QPpnMGhFUhHxNliZUXiQa1q4
boI2hEFdu3IQP/OC2a1zGJyMRLU43d5rhZ1U5xQSVtM0c3lgCY7rn/t26LymQVPA
SYdg2jBcnhe6gXo=
=eWJw
-----END PGP SIGNATURE-----
Merge tag 'pci-v6.16-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci
Pull pci updates from Bjorn Helgaas:
"Enumeration:
- Print the actual delay time in pci_bridge_wait_for_secondary_bus()
instead of assuming it was 1000ms (Wilfred Mallawa)
- Revert 'iommu/amd: Prevent binding other PCI drivers to IOMMU PCI
devices', which broke resume from system sleep on AMD platforms and
has been fixed by other commits (Lukas Wunner)
Resource management:
- Remove mtip32xx use of pcim_iounmap_regions(), which is deprecated
and unnecessary (Philipp Stanner)
- Remove pcim_iounmap_regions() and pcim_request_region_exclusive()
and related flags since all uses have been removed (Philipp
Stanner)
- Rework devres 'request' functions so they are no longer 'hybrid',
i.e., their behavior no longer depends on whether
pcim_enable_device or pci_enable_device() was used, and remove
related code (Philipp Stanner)
- Warn (not BUG()) about failure to assign optional resources (Ilpo
Järvinen)
Error handling:
- Log the DPC Error Source ID only when it's actually valid (when
ERR_FATAL or ERR_NONFATAL was received from a downstream device)
and decode into bus/device/function (Bjorn Helgaas)
- Determine AER log level once and save it so all related messages
use the same level (Karolina Stolarek)
- Use KERN_WARNING, not KERN_ERR, when logging PCIe Correctable
Errors (Karolina Stolarek)
- Ratelimit PCIe Correctable and Non-Fatal error logging, with sysfs
controls on interval and burst count, to avoid flooding logs and
RCU stall warnings (Jon Pan-Doh)
Power management:
- Increment PM usage counter when probing reset methods so we don't
try to read config space of a powered-off device (Alex Williamson)
- Set all devices to D0 during enumeration to ensure ACPI opregion is
connected via _REG (Mario Limonciello)
Power control:
- Rename pwrctrl Kconfig symbols from 'PWRCTL' to 'PWRCTRL' to match
the filename paths. Retain old deprecated symbols for
compatibility, except for the pwrctrl slot driver
(PCI_PWRCTRL_SLOT) (Johan Hovold)
- When unregistering pwrctrl, cancel outstanding rescan work before
cleaning up data structures to avoid use-after-free issues (Brian
Norris)
Bandwidth control:
- Simplify link bandwidth controller by replacing the count of Link
Bandwidth Management Status (LBMS) events with a PCI_LINK_LBMS_SEEN
flag (Ilpo Järvinen)
- Update the Link Speed after retraining, since the Link Speed may
have changed (Ilpo Järvinen)
PCIe native device hotplug:
- Ignore Presence Detect Changed caused by DPC.
pciehp already ignores Link Down/Up events caused by DPC, but on
slots using in-band presence detect, DPC causes a spurious Presence
Detect Changed event (Lukas Wunner)
- Ignore Link Down/Up caused by Secondary Bus Reset.
On hotplug ports using in-band presence detect, the reset causes a
Presence Detect Changed event, which mistakenly caused teardown and
re-enumeration of the device. Drivers may need to annotate code
that resets their device (Lukas Wunner)
Virtualization:
- Add an ACS quirk for Loongson Root Ports that don't advertise ACS
but don't allow peer-to-peer transactions between Root Ports; the
quirk allows each Root Port to be in a separate IOMMU group (Huacai
Chen)
Endpoint framework:
- For fixed-size BARs, retain both the actual size and the possibly
larger size allocated to accommodate iATU alignment requirements
(Jerome Brunet)
- Simplify ctrl/SPAD space allocation and avoid allocating more space
than needed (Jerome Brunet)
- Correct MSI-X PBA offset calculations for DesignWare and Cadence
endpoint controllers (Niklas Cassel)
- Align the return value (number of interrupts) encoding for
pci_epc_get_msi()/pci_epc_ops::get_msi() and
pci_epc_get_msix()/pci_epc_ops::get_msix() (Niklas Cassel)
- Align the nr_irqs parameter encoding for
pci_epc_set_msi()/pci_epc_ops::set_msi() and
pci_epc_set_msix()/pci_epc_ops::set_msix() (Niklas Cassel)
Common host controller library:
- Convert pci-host-common to a library so platforms that don't need
native host controller drivers don't need to include these helper
functions (Manivannan Sadhasivam)
Apple PCIe controller driver:
- Extract ECAM bridge creation helper from pci_host_common_probe() to
separate driver-specific things like MSI from PCI things (Marc
Zyngier)
- Dynamically allocate RID-to_SID bitmap to prepare for SoCs with
varying capabilities (Marc Zyngier)
- Skip ports disabled in DT when setting up ports (Janne Grunau)
- Add t6020 compatible string (Alyssa Rosenzweig)
- Add T602x PCIe support (Hector Martin)
- Directly set/clear INTx mask bits because T602x dropped the
accessors that could do this without locking (Marc Zyngier)
- Move port PHY registers to their own reg items to accommodate
T602x, which moves them around; retain default offsets for existing
DTs that lack phy%d entries with the reg offsets (Hector Martin)
- Stop polling for core refclk, which doesn't work on T602x and the
bootloader has already done anyway (Hector Martin)
- Use gpiod_set_value_cansleep() when asserting PERST# in probe
because we're allowed to sleep there (Hector Martin)
Cadence PCIe controller driver:
- Drop a runtime PM 'put' to resolve a runtime atomic count underflow
(Hans Zhang)
- Make the cadence core buildable as a module (Kishon Vijay Abraham I)
- Add cdns_pcie_host_disable() and cdns_pcie_ep_disable() for use by
loadable drivers when they are removed (Siddharth Vadapalli)
Freescale i.MX6 PCIe controller driver:
- Apply link training workaround only on IMX6Q, IMX6SX, IMX6SP
(Richard Zhu)
- Remove redundant dw_pcie_wait_for_link() from
imx_pcie_start_link(); since the DWC core does this, imx6 only
needs it when retraining for a faster link speed (Richard Zhu)
- Toggle i.MX95 core reset to align with PHY powerup (Richard Zhu)
- Set SYS_AUX_PWR_DET to work around i.MX95 ERR051624 erratum: in
some cases, the controller can't exit 'L23 Ready' through Beacon or
PERST# deassertion (Richard Zhu)
- Clear GEN3_ZRXDC_NONCOMPL to work around i.MX95 ERR051586 erratum:
controller can't meet 2.5 GT/s ZRX-DC timing when operating at 8
GT/s, causing timeouts in L1 (Richard Zhu)
- Wait for i.MX95 PLL lock before enabling controller (Richard Zhu)
- Save/restore i.MX95 LUT for suspend/resume (Richard Zhu)
Mobiveil PCIe controller driver:
- Return bool (not int) for link-up check in
mobiveil_pab_ops.link_up() and layerscape-gen4, mobiveil (Hans
Zhang)
NVIDIA Tegra194 PCIe controller driver:
- Create debugfs directory for 'aspm_state_cnt' only when
CONFIG_PCIEASPM is enabled, since there are no other entries (Hans
Zhang)
Qualcomm PCIe controller driver:
- Add OF support for parsing DT 'eq-presets-<N>gts' property for lane
equalization presets (Krishna Chaitanya Chundru)
- Read Maximum Link Width from the Link Capabilities register if DT
lacks 'num-lanes' property (Krishna Chaitanya Chundru)
- Add Physical Layer 64 GT/s Capability ID and register offsets for
8, 32, and 64 GT/s lane equalization registers (Krishna Chaitanya
Chundru)
- Add generic dwc support for configuring lane equalization presets
(Krishna Chaitanya Chundru)
- Add DT and driver support for PCIe on IPQ5018 SoC (Nitheesh Sekar)
Renesas R-Car PCIe controller driver:
- Describe endpoint BAR 4 as being fixed size (Jerome Brunet)
- Document how to obtain R-Car V4H (r8a779g0) controller firmware
(Yoshihiro Shimoda)
Rockchip PCIe controller driver:
- Reorder rockchip_pci_core_rsts because
reset_control_bulk_deassert() deasserts in reverse order, to fix a
link training regression (Jensen Huang)
- Mark RK3399 as being capable of raising INTx interrupts (Niklas
Cassel)
Rockchip DesignWare PCIe controller driver:
- Check only PCIE_LINKUP, not LTSSM status, to determine whether the
link is up (Shawn Lin)
- Increase N_FTS (used in L0s->L0 transitions) and enable ASPM L0s
for Root Complex and Endpoint modes (Shawn Lin)
- Hide the broken ATS Capability in rockchip_pcie_ep_init() instead
of rockchip_pcie_ep_pre_init() so it stays hidden after PERST#
resets non-sticky registers (Shawn Lin)
- Call phy_power_off() before phy_exit() in rockchip_pcie_phy_deinit()
(Diederik de Haas)
Synopsys DesignWare PCIe controller driver:
- Set PORT_LOGIC_LINK_WIDTH to one lane to make initial link training
more robust; this will not affect the intended link width if all
lanes are functional (Wenbin Yao)
- Return bool (not int) for link-up check in dw_pcie_ops.link_up()
and armada8k, dra7xx, dw-rockchip, exynos, histb, keembay,
keystone, kirin, meson, qcom, qcom-ep, rcar_gen4, spear13xx,
tegra194, uniphier, visconti (Hans Zhang)
- Add debugfs support for exposing DWC device-specific PTM context
(Manivannan Sadhasivam)
TI J721E PCIe driver:
- Make j721e buildable as a loadable and removable module (Siddharth
Vadapalli)
- Fix j721e host/endpoint dependencies that result in link failures
in some configs (Arnd Bergmann)
Device tree bindings:
- Add qcom DT binding for 'global' interrupt (PCIe controller and
link-specific events) for ipq8074, ipq8074-gen3, ipq6018, sa8775p,
sc7280, sc8180x sdm845, sm8150, sm8250, sm8350 (Manivannan
Sadhasivam)
- Add qcom DT binding for 8 MSI SPI interrupts for msm8998, ipq8074,
ipq8074-gen3, ipq6018 (Manivannan Sadhasivam)
- Add dw rockchip DT binding for rk3576 and rk3562 (Kever Yang)
- Correct indentation and style of examples in brcm,stb-pcie,
cdns,cdns-pcie-ep, intel,keembay-pcie-ep, intel,keembay-pcie,
microchip,pcie-host, rcar-pci-ep, rcar-pci-host, xilinx-versal-cpm
(Krzysztof Kozlowski)
- Convert Marvell EBU (dove, kirkwood, armada-370, armada-xp) and
armada8k from text to schema DT bindings (Rob Herring)
- Remove obsolete .txt DT bindings for content that has been moved to
schemas (Rob Herring)
- Add qcom DT binding for MHI registers in IPQ5332, IPQ6018, IPQ8074
and IPQ9574 (Varadarajan Narayanan)
- Convert v3,v360epc-pci from text to DT schema binding (Rob Herring)
- Change microchip,pcie-host DT binding to be 'dma-noncoherent' since
PolarFire may be configured that way (Conor Dooley)
Miscellaneous:
- Drop 'pci' suffix from intel_mid_pci.c filename to match similar
files (Andy Shevchenko)
- All platforms with PCI have an MMU, so add PCI Kconfig dependency
on MMU to simplify build testing and avoid inadvertent build
regressions (Arnd Bergmann)
- Update Krzysztof Wilczyński's email address in MAINTAINERS
(Krzysztof Wilczyński)
- Update Manivannan Sadhasivam's email address in MAINTAINERS
(Manivannan Sadhasivam)"
* tag 'pci-v6.16-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci: (147 commits)
MAINTAINERS: Update Manivannan Sadhasivam email address
PCI: j721e: Fix host/endpoint dependencies
PCI: j721e: Add support to build as a loadable module
PCI: cadence-ep: Introduce cdns_pcie_ep_disable() helper for cleanup
PCI: cadence-host: Introduce cdns_pcie_host_disable() helper for cleanup
PCI: cadence: Add support to build pcie-cadence library as a kernel module
MAINTAINERS: Update Krzysztof Wilczyński email address
PCI: Remove unnecessary linesplit in __pci_setup_bridge()
PCI: WARN (not BUG()) when we fail to assign optional resources
PCI: Remove unused pci_printk()
PCI: qcom: Replace PERST# sleep time with proper macro
PCI: dw-rockchip: Replace PERST# sleep time with proper macro
PCI: host-common: Convert to library for host controller drivers
PCI/ERR: Remove misleading TODO regarding kernel panic
PCI: cadence: Remove duplicate message code definitions
PCI: endpoint: Align pci_epc_set_msix(), pci_epc_ops::set_msix() nr_irqs encoding
PCI: endpoint: Align pci_epc_set_msi(), pci_epc_ops::set_msi() nr_irqs encoding
PCI: endpoint: Align pci_epc_get_msix(), pci_epc_ops::get_msix() return value encoding
PCI: endpoint: Align pci_epc_get_msi(), pci_epc_ops::get_msi() return value encoding
PCI: cadence-ep: Correct PBA offset in .set_msix() callback
...
This commit is contained in:
commit
3719a04a80
148 changed files with 3401 additions and 2220 deletions
3
.mailmap
3
.mailmap
|
|
@ -419,6 +419,8 @@ Krishna Manikandan <quic_mkrishn@quicinc.com> <mkrishn@codeaurora.org>
|
|||
Krzysztof Kozlowski <krzk@kernel.org> <k.kozlowski.k@gmail.com>
|
||||
Krzysztof Kozlowski <krzk@kernel.org> <k.kozlowski@samsung.com>
|
||||
Krzysztof Kozlowski <krzk@kernel.org> <krzysztof.kozlowski@canonical.com>
|
||||
Krzysztof Wilczyński <kwilczynski@kernel.org> <krzysztof.wilczynski@linux.com>
|
||||
Krzysztof Wilczyński <kwilczynski@kernel.org> <kw@linux.com>
|
||||
Kshitiz Godara <quic_kgodara@quicinc.com> <kgodara@codeaurora.org>
|
||||
Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
|
||||
Kuogee Hsieh <quic_khsieh@quicinc.com> <khsieh@codeaurora.org>
|
||||
|
|
@ -461,6 +463,7 @@ Maheshwar Ajja <quic_majja@quicinc.com> <majja@codeaurora.org>
|
|||
Malathi Gottam <quic_mgottam@quicinc.com> <mgottam@codeaurora.org>
|
||||
Manikanta Pubbisetty <quic_mpubbise@quicinc.com> <mpubbise@codeaurora.org>
|
||||
Manivannan Sadhasivam <mani@kernel.org> <manivannanece23@gmail.com>
|
||||
Manivannan Sadhasivam <mani@kernel.org> <manivannan.sadhasivam@linaro.org>
|
||||
Manoj Basapathi <quic_manojbm@quicinc.com> <manojbm@codeaurora.org>
|
||||
Marcin Nowakowski <marcin.nowakowski@mips.com> <marcin.nowakowski@imgtec.com>
|
||||
Marc Zyngier <maz@kernel.org> <marc.zyngier@arm.com>
|
||||
|
|
|
|||
70
Documentation/ABI/testing/debugfs-pcie-ptm
Normal file
70
Documentation/ABI/testing/debugfs-pcie-ptm
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
What: /sys/kernel/debug/pcie_ptm_*/local_clock
|
||||
Date: May 2025
|
||||
Contact: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
Description:
|
||||
(RO) PTM local clock in nanoseconds. Applicable for both Root
|
||||
Complex and Endpoint controllers.
|
||||
|
||||
What: /sys/kernel/debug/pcie_ptm_*/master_clock
|
||||
Date: May 2025
|
||||
Contact: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
Description:
|
||||
(RO) PTM master clock in nanoseconds. Applicable only for
|
||||
Endpoint controllers.
|
||||
|
||||
What: /sys/kernel/debug/pcie_ptm_*/t1
|
||||
Date: May 2025
|
||||
Contact: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
Description:
|
||||
(RO) PTM T1 timestamp in nanoseconds. Applicable only for
|
||||
Endpoint controllers.
|
||||
|
||||
What: /sys/kernel/debug/pcie_ptm_*/t2
|
||||
Date: May 2025
|
||||
Contact: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
Description:
|
||||
(RO) PTM T2 timestamp in nanoseconds. Applicable only for
|
||||
Root Complex controllers.
|
||||
|
||||
What: /sys/kernel/debug/pcie_ptm_*/t3
|
||||
Date: May 2025
|
||||
Contact: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
Description:
|
||||
(RO) PTM T3 timestamp in nanoseconds. Applicable only for
|
||||
Root Complex controllers.
|
||||
|
||||
What: /sys/kernel/debug/pcie_ptm_*/t4
|
||||
Date: May 2025
|
||||
Contact: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
Description:
|
||||
(RO) PTM T4 timestamp in nanoseconds. Applicable only for
|
||||
Endpoint controllers.
|
||||
|
||||
What: /sys/kernel/debug/pcie_ptm_*/context_update
|
||||
Date: May 2025
|
||||
Contact: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
Description:
|
||||
(RW) Control the PTM context update mode. Applicable only for
|
||||
Endpoint controllers.
|
||||
|
||||
Following values are supported:
|
||||
|
||||
* auto = PTM context auto update trigger for every 10ms
|
||||
|
||||
* manual = PTM context manual update. Writing 'manual' to this
|
||||
file triggers PTM context update (default)
|
||||
|
||||
What: /sys/kernel/debug/pcie_ptm_*/context_valid
|
||||
Date: May 2025
|
||||
Contact: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
Description:
|
||||
(RW) Control the PTM context validity (local clock timing).
|
||||
Applicable only for Root Complex controllers. PTM context is
|
||||
invalidated by hardware if the Root Complex enters low power
|
||||
mode or changes link frequency.
|
||||
|
||||
Following values are supported:
|
||||
|
||||
* 0 = PTM context invalid (default)
|
||||
|
||||
* 1 = PTM context valid
|
||||
|
|
@ -117,3 +117,47 @@ Date: July 2018
|
|||
KernelVersion: 4.19.0
|
||||
Contact: linux-pci@vger.kernel.org, rajatja@google.com
|
||||
Description: Total number of ERR_NONFATAL messages reported to rootport.
|
||||
|
||||
PCIe AER ratelimits
|
||||
-------------------
|
||||
|
||||
These attributes show up under all the devices that are AER capable.
|
||||
They represent configurable ratelimits of logs per error type.
|
||||
|
||||
See Documentation/PCI/pcieaer-howto.rst for more info on ratelimits.
|
||||
|
||||
What: /sys/bus/pci/devices/<dev>/aer/correctable_ratelimit_interval_ms
|
||||
Date: May 2025
|
||||
KernelVersion: 6.16.0
|
||||
Contact: linux-pci@vger.kernel.org
|
||||
Description: Writing 0 disables AER correctable error log ratelimiting.
|
||||
Writing a positive value sets the ratelimit interval in ms.
|
||||
Default is DEFAULT_RATELIMIT_INTERVAL (5000 ms).
|
||||
|
||||
What: /sys/bus/pci/devices/<dev>/aer/correctable_ratelimit_burst
|
||||
Date: May 2025
|
||||
KernelVersion: 6.16.0
|
||||
Contact: linux-pci@vger.kernel.org
|
||||
Description: Ratelimit burst for correctable error logs. Writing a value
|
||||
changes the number of errors (burst) allowed per interval
|
||||
before ratelimiting. Reading gets the current ratelimit
|
||||
burst. Default is DEFAULT_RATELIMIT_BURST (10).
|
||||
|
||||
What: /sys/bus/pci/devices/<dev>/aer/nonfatal_ratelimit_interval_ms
|
||||
Date: May 2025
|
||||
KernelVersion: 6.16.0
|
||||
Contact: linux-pci@vger.kernel.org
|
||||
Description: Writing 0 disables AER non-fatal uncorrectable error log
|
||||
ratelimiting. Writing a positive value sets the ratelimit
|
||||
interval in ms. Default is DEFAULT_RATELIMIT_INTERVAL
|
||||
(5000 ms).
|
||||
|
||||
What: /sys/bus/pci/devices/<dev>/aer/nonfatal_ratelimit_burst
|
||||
Date: May 2025
|
||||
KernelVersion: 6.16.0
|
||||
Contact: linux-pci@vger.kernel.org
|
||||
Description: Ratelimit burst for non-fatal uncorrectable error logs.
|
||||
Writing a value changes the number of errors (burst)
|
||||
allowed per interval before ratelimiting. Reading gets the
|
||||
current ratelimit burst. Default is DEFAULT_RATELIMIT_BURST
|
||||
(10).
|
||||
10
Documentation/PCI/controller/index.rst
Normal file
10
Documentation/PCI/controller/index.rst
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
===========================================
|
||||
PCI Native Host Bridge and Endpoint Drivers
|
||||
===========================================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
rcar-pcie-firmware
|
||||
32
Documentation/PCI/controller/rcar-pcie-firmware.rst
Normal file
32
Documentation/PCI/controller/rcar-pcie-firmware.rst
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
=================================================
|
||||
Firmware of PCIe controller for Renesas R-Car V4H
|
||||
=================================================
|
||||
|
||||
Renesas R-Car V4H (r8a779g0) has a PCIe controller, requiring a specific
|
||||
firmware download during startup.
|
||||
|
||||
However, Renesas currently cannot distribute the firmware free of charge.
|
||||
|
||||
The firmware file "104_PCIe_fw_addr_data_ver1.05.txt" (note that the file name
|
||||
might be different between different datasheet revisions) can be found in the
|
||||
datasheet encoded as text, and as such, the file's content must be converted
|
||||
back to binary form. This can be achieved using the following example script:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
$ awk '/^\s*0x[0-9A-Fa-f]{4}\s+0x[0-9A-Fa-f]{4}/ { print substr($2,5,2) substr($2,3,2) }' \
|
||||
104_PCIe_fw_addr_data_ver1.05.txt | \
|
||||
xxd -p -r > rcar_gen4_pcie.bin
|
||||
|
||||
Once the text content has been converted into a binary firmware file, verify
|
||||
its checksum as follows:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
$ sha1sum rcar_gen4_pcie.bin
|
||||
1d0bd4b189b4eb009f5d564b1f93a79112994945 rcar_gen4_pcie.bin
|
||||
|
||||
The resulting binary file called "rcar_gen4_pcie.bin" should be placed in the
|
||||
"/lib/firmware" directory before the driver runs.
|
||||
|
|
@ -8,6 +8,6 @@ PCI NVMe Function
|
|||
|
||||
The PCI NVMe endpoint function implements a PCI NVMe controller using the NVMe
|
||||
subsystem target core code. The driver for this function resides with the NVMe
|
||||
subsystem as drivers/nvme/target/nvmet-pciep.c.
|
||||
subsystem as drivers/nvme/target/pci-epf.c.
|
||||
|
||||
See Documentation/nvme/nvme-pci-endpoint-target.rst for more details.
|
||||
|
|
|
|||
|
|
@ -17,5 +17,6 @@ PCI Bus Subsystem
|
|||
pci-error-recovery
|
||||
pcieaer-howto
|
||||
endpoint/index
|
||||
controller/index
|
||||
boot-interrupts
|
||||
tph
|
||||
|
|
|
|||
|
|
@ -85,12 +85,27 @@ In the example, 'Requester ID' means the ID of the device that sent
|
|||
the error message to the Root Port. Please refer to PCIe specs for other
|
||||
fields.
|
||||
|
||||
AER Ratelimits
|
||||
--------------
|
||||
|
||||
Since error messages can be generated for each transaction, we may see
|
||||
large volumes of errors reported. To prevent spammy devices from flooding
|
||||
the console/stalling execution, messages are throttled by device and error
|
||||
type (correctable vs. non-fatal uncorrectable). Fatal errors, including
|
||||
DPC errors, are not ratelimited.
|
||||
|
||||
AER uses the default ratelimit of DEFAULT_RATELIMIT_BURST (10 events) over
|
||||
DEFAULT_RATELIMIT_INTERVAL (5 seconds).
|
||||
|
||||
Ratelimits are exposed in the form of sysfs attributes and configurable.
|
||||
See Documentation/ABI/testing/sysfs-bus-pci-devices-aer.
|
||||
|
||||
AER Statistics / Counters
|
||||
-------------------------
|
||||
|
||||
When PCIe AER errors are captured, the counters / statistics are also exposed
|
||||
in the form of sysfs attributes which are documented at
|
||||
Documentation/ABI/testing/sysfs-bus-pci-devices-aer_stats
|
||||
Documentation/ABI/testing/sysfs-bus-pci-devices-aer.
|
||||
|
||||
Developer Guide
|
||||
===============
|
||||
|
|
|
|||
|
|
@ -17,6 +17,10 @@ description: |
|
|||
implements its root ports. But the ATU found on most DesignWare
|
||||
PCIe host bridges is absent.
|
||||
|
||||
On systems derived from T602x, the PHY registers are in a region
|
||||
separate from the port registers. In that case, there is one PHY
|
||||
register range per port register range.
|
||||
|
||||
All root ports share a single ECAM space, but separate GPIOs are
|
||||
used to take the PCI devices on those ports out of reset. Therefore
|
||||
the standard "reset-gpios" and "max-link-speed" properties appear on
|
||||
|
|
@ -30,16 +34,18 @@ description: |
|
|||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- apple,t8103-pcie
|
||||
- apple,t8112-pcie
|
||||
- apple,t6000-pcie
|
||||
- const: apple,pcie
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- apple,t8103-pcie
|
||||
- apple,t8112-pcie
|
||||
- apple,t6000-pcie
|
||||
- const: apple,pcie
|
||||
- const: apple,t6020-pcie
|
||||
|
||||
reg:
|
||||
minItems: 3
|
||||
maxItems: 6
|
||||
maxItems: 10
|
||||
|
||||
reg-names:
|
||||
minItems: 3
|
||||
|
|
@ -50,6 +56,10 @@ properties:
|
|||
- const: port1
|
||||
- const: port2
|
||||
- const: port3
|
||||
- const: phy0
|
||||
- const: phy1
|
||||
- const: phy2
|
||||
- const: phy3
|
||||
|
||||
ranges:
|
||||
minItems: 2
|
||||
|
|
@ -98,6 +108,15 @@ allOf:
|
|||
maxItems: 5
|
||||
interrupts:
|
||||
maxItems: 3
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: apple,t6020-pcie
|
||||
then:
|
||||
properties:
|
||||
reg-names:
|
||||
minItems: 10
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
|
|
|||
|
|
@ -186,49 +186,48 @@ examples:
|
|||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
scb {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <1>;
|
||||
pcie0: pcie@7d500000 {
|
||||
compatible = "brcm,bcm2711-pcie";
|
||||
reg = <0x0 0x7d500000 0x9310>;
|
||||
device_type = "pci";
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
#interrupt-cells = <1>;
|
||||
interrupts = <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "pcie", "msi";
|
||||
interrupt-map-mask = <0x0 0x0 0x0 0x7>;
|
||||
interrupt-map = <0 0 0 1 &gicv2 GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH
|
||||
0 0 0 2 &gicv2 GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH
|
||||
0 0 0 3 &gicv2 GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH
|
||||
0 0 0 4 &gicv2 GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
|
||||
#address-cells = <2>;
|
||||
#size-cells = <1>;
|
||||
pcie0: pcie@7d500000 {
|
||||
compatible = "brcm,bcm2711-pcie";
|
||||
reg = <0x0 0x7d500000 0x9310>;
|
||||
device_type = "pci";
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
#interrupt-cells = <1>;
|
||||
interrupts = <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "pcie", "msi";
|
||||
interrupt-map-mask = <0x0 0x0 0x0 0x7>;
|
||||
interrupt-map = <0 0 0 1 &gicv2 GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH
|
||||
0 0 0 2 &gicv2 GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH
|
||||
0 0 0 3 &gicv2 GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH
|
||||
0 0 0 4 &gicv2 GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
|
||||
|
||||
msi-parent = <&pcie0>;
|
||||
msi-controller;
|
||||
ranges = <0x02000000 0x0 0xf8000000 0x6 0x00000000 0x0 0x04000000>;
|
||||
dma-ranges = <0x42000000 0x1 0x00000000 0x0 0x40000000 0x0 0x80000000>,
|
||||
<0x42000000 0x1 0x80000000 0x3 0x00000000 0x0 0x80000000>;
|
||||
brcm,enable-ssc;
|
||||
brcm,scb-sizes = <0x0000000080000000 0x0000000080000000>;
|
||||
msi-parent = <&pcie0>;
|
||||
msi-controller;
|
||||
ranges = <0x02000000 0x0 0xf8000000 0x6 0x00000000 0x0 0x04000000>;
|
||||
dma-ranges = <0x42000000 0x1 0x00000000 0x0 0x40000000 0x0 0x80000000>,
|
||||
<0x42000000 0x1 0x80000000 0x3 0x00000000 0x0 0x80000000>;
|
||||
brcm,enable-ssc;
|
||||
brcm,scb-sizes = <0x0000000080000000 0x0000000080000000>;
|
||||
|
||||
/* PCIe bridge, Root Port */
|
||||
pci@0,0 {
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
reg = <0x0 0x0 0x0 0x0 0x0>;
|
||||
compatible = "pciclass,0604";
|
||||
device_type = "pci";
|
||||
vpcie3v3-supply = <&vreg7>;
|
||||
ranges;
|
||||
/* PCIe bridge, Root Port */
|
||||
pci@0,0 {
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
reg = <0x0 0x0 0x0 0x0 0x0>;
|
||||
compatible = "pciclass,0604";
|
||||
device_type = "pci";
|
||||
vpcie3v3-supply = <&vreg7>;
|
||||
ranges;
|
||||
|
||||
/* PCIe endpoint */
|
||||
pci-ep@0,0 {
|
||||
assigned-addresses =
|
||||
<0x82010000 0x0 0xf8000000 0x6 0x00000000 0x0 0x2000>;
|
||||
reg = <0x0 0x0 0x0 0x0 0x0>;
|
||||
compatible = "pci14e4,1688";
|
||||
};
|
||||
};
|
||||
/* PCIe endpoint */
|
||||
pci-ep@0,0 {
|
||||
assigned-addresses = <0x82010000 0x0 0xf8000000 0x6 0x00000000 0x0 0x2000>;
|
||||
reg = <0x0 0x0 0x0 0x0 0x0>;
|
||||
compatible = "pci14e4,1688";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -37,14 +37,14 @@ examples:
|
|||
#size-cells = <2>;
|
||||
|
||||
pcie-ep@fc000000 {
|
||||
compatible = "cdns,cdns-pcie-ep";
|
||||
reg = <0x0 0xfc000000 0x0 0x01000000>,
|
||||
<0x0 0x80000000 0x0 0x40000000>;
|
||||
reg-names = "reg", "mem";
|
||||
cdns,max-outbound-regions = <16>;
|
||||
max-functions = /bits/ 8 <8>;
|
||||
phys = <&pcie_phy0>;
|
||||
phy-names = "pcie-phy";
|
||||
compatible = "cdns,cdns-pcie-ep";
|
||||
reg = <0x0 0xfc000000 0x0 0x01000000>,
|
||||
<0x0 0x80000000 0x0 0x40000000>;
|
||||
reg-names = "reg", "mem";
|
||||
cdns,max-outbound-regions = <16>;
|
||||
max-functions = /bits/ 8 <8>;
|
||||
phys = <&pcie_phy0>;
|
||||
phy-names = "pcie-phy";
|
||||
};
|
||||
};
|
||||
...
|
||||
|
|
|
|||
|
|
@ -53,17 +53,17 @@ examples:
|
|||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
pcie-ep@37000000 {
|
||||
compatible = "intel,keembay-pcie-ep";
|
||||
reg = <0x37000000 0x00001000>,
|
||||
<0x37100000 0x00001000>,
|
||||
<0x37300000 0x00001000>,
|
||||
<0x36000000 0x01000000>,
|
||||
<0x37800000 0x00000200>;
|
||||
reg-names = "dbi", "dbi2", "atu", "addr_space", "apb";
|
||||
interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 108 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "pcie", "pcie_ev", "pcie_err", "pcie_mem_access";
|
||||
num-lanes = <2>;
|
||||
compatible = "intel,keembay-pcie-ep";
|
||||
reg = <0x37000000 0x00001000>,
|
||||
<0x37100000 0x00001000>,
|
||||
<0x37300000 0x00001000>,
|
||||
<0x36000000 0x01000000>,
|
||||
<0x37800000 0x00000200>;
|
||||
reg-names = "dbi", "dbi2", "atu", "addr_space", "apb";
|
||||
interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 108 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "pcie", "pcie_ev", "pcie_err", "pcie_mem_access";
|
||||
num-lanes = <2>;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -75,23 +75,23 @@ examples:
|
|||
#define KEEM_BAY_A53_PCIE
|
||||
#define KEEM_BAY_A53_AUX_PCIE
|
||||
pcie@37000000 {
|
||||
compatible = "intel,keembay-pcie";
|
||||
reg = <0x37000000 0x00001000>,
|
||||
<0x37300000 0x00001000>,
|
||||
<0x36e00000 0x00200000>,
|
||||
<0x37800000 0x00000200>;
|
||||
reg-names = "dbi", "atu", "config", "apb";
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
device_type = "pci";
|
||||
ranges = <0x02000000 0 0x36000000 0x36000000 0 0x00e00000>;
|
||||
interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "pcie", "pcie_ev", "pcie_err";
|
||||
clocks = <&scmi_clk KEEM_BAY_A53_PCIE>,
|
||||
<&scmi_clk KEEM_BAY_A53_AUX_PCIE>;
|
||||
clock-names = "master", "aux";
|
||||
reset-gpios = <&pca2 9 GPIO_ACTIVE_LOW>;
|
||||
num-lanes = <2>;
|
||||
compatible = "intel,keembay-pcie";
|
||||
reg = <0x37000000 0x00001000>,
|
||||
<0x37300000 0x00001000>,
|
||||
<0x36e00000 0x00200000>,
|
||||
<0x37800000 0x00000200>;
|
||||
reg-names = "dbi", "atu", "config", "apb";
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
device_type = "pci";
|
||||
ranges = <0x02000000 0 0x36000000 0x36000000 0 0x00e00000>;
|
||||
interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "pcie", "pcie_ev", "pcie_err";
|
||||
clocks = <&scmi_clk KEEM_BAY_A53_PCIE>,
|
||||
<&scmi_clk KEEM_BAY_A53_AUX_PCIE>;
|
||||
clock-names = "master", "aux";
|
||||
reset-gpios = <&pca2 9 GPIO_ACTIVE_LOW>;
|
||||
num-lanes = <2>;
|
||||
};
|
||||
|
|
|
|||
100
Documentation/devicetree/bindings/pci/marvell,armada8k-pcie.yaml
Normal file
100
Documentation/devicetree/bindings/pci/marvell,armada8k-pcie.yaml
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/pci/marvell,armada8k-pcie.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Marvell Armada 7K/8K PCIe interface
|
||||
|
||||
maintainers:
|
||||
- Thomas Petazzoni <thomas.petazzoni@bootlin.com>
|
||||
|
||||
description:
|
||||
This PCIe host controller is based on the Synopsys DesignWare PCIe IP.
|
||||
|
||||
select:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- marvell,armada8k-pcie
|
||||
required:
|
||||
- compatible
|
||||
|
||||
allOf:
|
||||
- $ref: snps,dw-pcie.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- marvell,armada8k-pcie
|
||||
- const: snps,dw-pcie
|
||||
|
||||
reg:
|
||||
maxItems: 2
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: ctrl
|
||||
- const: config
|
||||
|
||||
clocks:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: core
|
||||
- const: reg
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
msi-parent:
|
||||
maxItems: 1
|
||||
|
||||
phys:
|
||||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
phy-names:
|
||||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
marvell,reset-gpio:
|
||||
maxItems: 1
|
||||
deprecated: true
|
||||
|
||||
required:
|
||||
- interrupt-map
|
||||
- clocks
|
||||
- msi-parent
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
pcie@f2600000 {
|
||||
compatible = "marvell,armada8k-pcie", "snps,dw-pcie";
|
||||
reg = <0xf2600000 0x10000>, <0xf6f00000 0x80000>;
|
||||
reg-names = "ctrl", "config";
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
#interrupt-cells = <1>;
|
||||
device_type = "pci";
|
||||
dma-coherent;
|
||||
msi-parent = <&gic_v2m0>;
|
||||
|
||||
ranges = <0x81000000 0 0xf9000000 0xf9000000 0 0x10000>, /* downstream I/O */
|
||||
<0x82000000 0 0xf6000000 0xf6000000 0 0xf00000>; /* non-prefetchable memory */
|
||||
interrupt-map-mask = <0 0 0 0>;
|
||||
interrupt-map = <0 0 0 0 &gic 0 GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
|
||||
num-lanes = <1>;
|
||||
clocks = <&cpm_syscon0 1 13>;
|
||||
};
|
||||
...
|
||||
277
Documentation/devicetree/bindings/pci/marvell,kirkwood-pcie.yaml
Normal file
277
Documentation/devicetree/bindings/pci/marvell,kirkwood-pcie.yaml
Normal file
|
|
@ -0,0 +1,277 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/pci/marvell,kirkwood-pcie.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Marvell EBU PCIe interfaces
|
||||
|
||||
maintainers:
|
||||
- Thomas Petazzoni <thomas.petazzoni@bootlin.com>
|
||||
- Pali Rohár <pali@kernel.org>
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/pci/pci-host-bridge.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- marvell,armada-370-pcie
|
||||
- marvell,armada-xp-pcie
|
||||
- marvell,dove-pcie
|
||||
- marvell,kirkwood-pcie
|
||||
|
||||
ranges:
|
||||
description: >
|
||||
The ranges describing the MMIO registers have the following layout:
|
||||
|
||||
0x82000000 0 r MBUS_ID(0xf0, 0x01) r 0 s
|
||||
|
||||
where:
|
||||
|
||||
* r is a 32-bits value that gives the offset of the MMIO registers of
|
||||
this PCIe interface, from the base of the internal registers.
|
||||
|
||||
* s is a 32-bits value that give the size of this MMIO registers area.
|
||||
This range entry translates the '0x82000000 0 r' PCI address into the
|
||||
'MBUS_ID(0xf0, 0x01) r' CPU address, which is part of the internal
|
||||
register window (as identified by MBUS_ID(0xf0, 0x01)).
|
||||
|
||||
The ranges describing the MBus windows have the following layout:
|
||||
|
||||
0x8t000000 s 0 MBUS_ID(w, a) 0 1 0
|
||||
|
||||
where:
|
||||
|
||||
* t is the type of the MBus window (as defined by the standard PCI DT
|
||||
bindings), 1 for I/O and 2 for memory.
|
||||
|
||||
* s is the PCI slot that corresponds to this PCIe interface
|
||||
|
||||
* w is the 'target ID' value for the MBus window
|
||||
|
||||
* a the 'attribute' value for the MBus window.
|
||||
|
||||
Since the location and size of the different MBus windows is not fixed in
|
||||
hardware, and only determined in runtime, those ranges cover the full first
|
||||
4 GB of the physical address space, and do not translate into a valid CPU
|
||||
address.
|
||||
|
||||
msi-parent:
|
||||
maxItems: 1
|
||||
|
||||
patternProperties:
|
||||
'^pcie@':
|
||||
type: object
|
||||
allOf:
|
||||
- $ref: /schemas/pci/pci-bus-common.yaml#
|
||||
- $ref: /schemas/pci/pci-device.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
properties:
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
interrupt-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: intx
|
||||
- const: error
|
||||
|
||||
reset-delay-us:
|
||||
default: 100000
|
||||
description: todo
|
||||
|
||||
marvell,pcie-port:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
maximum: 3
|
||||
description: todo
|
||||
|
||||
marvell,pcie-lane:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
maximum: 3
|
||||
description: todo
|
||||
|
||||
interrupt-controller:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
|
||||
properties:
|
||||
interrupt-controller: true
|
||||
|
||||
'#interrupt-cells':
|
||||
const: 1
|
||||
|
||||
required:
|
||||
- assigned-addresses
|
||||
- clocks
|
||||
- interrupt-map
|
||||
- marvell,pcie-port
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#define MBUS_ID(target,attributes) (((target) << 24) | ((attributes) << 16))
|
||||
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
pcie@f001000000000000 {
|
||||
compatible = "marvell,armada-xp-pcie";
|
||||
device_type = "pci";
|
||||
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
|
||||
bus-range = <0x00 0xff>;
|
||||
msi-parent = <&mpic>;
|
||||
|
||||
ranges =
|
||||
<0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000 /* Port 0.0 registers */
|
||||
0x82000000 0 0x42000 MBUS_ID(0xf0, 0x01) 0x42000 0 0x00002000 /* Port 2.0 registers */
|
||||
0x82000000 0 0x44000 MBUS_ID(0xf0, 0x01) 0x44000 0 0x00002000 /* Port 0.1 registers */
|
||||
0x82000000 0 0x48000 MBUS_ID(0xf0, 0x01) 0x48000 0 0x00002000 /* Port 0.2 registers */
|
||||
0x82000000 0 0x4c000 MBUS_ID(0xf0, 0x01) 0x4c000 0 0x00002000 /* Port 0.3 registers */
|
||||
0x82000000 0 0x80000 MBUS_ID(0xf0, 0x01) 0x80000 0 0x00002000 /* Port 1.0 registers */
|
||||
0x82000000 0 0x82000 MBUS_ID(0xf0, 0x01) 0x82000 0 0x00002000 /* Port 3.0 registers */
|
||||
0x82000000 0 0x84000 MBUS_ID(0xf0, 0x01) 0x84000 0 0x00002000 /* Port 1.1 registers */
|
||||
0x82000000 0 0x88000 MBUS_ID(0xf0, 0x01) 0x88000 0 0x00002000 /* Port 1.2 registers */
|
||||
0x82000000 0 0x8c000 MBUS_ID(0xf0, 0x01) 0x8c000 0 0x00002000 /* Port 1.3 registers */
|
||||
0x82000000 0x1 0 MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 0.0 MEM */
|
||||
0x81000000 0x1 0 MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 0.0 IO */
|
||||
0x82000000 0x2 0 MBUS_ID(0x04, 0xd8) 0 1 0 /* Port 0.1 MEM */
|
||||
0x81000000 0x2 0 MBUS_ID(0x04, 0xd0) 0 1 0 /* Port 0.1 IO */
|
||||
0x82000000 0x3 0 MBUS_ID(0x04, 0xb8) 0 1 0 /* Port 0.2 MEM */
|
||||
0x81000000 0x3 0 MBUS_ID(0x04, 0xb0) 0 1 0 /* Port 0.2 IO */
|
||||
0x82000000 0x4 0 MBUS_ID(0x04, 0x78) 0 1 0 /* Port 0.3 MEM */
|
||||
0x81000000 0x4 0 MBUS_ID(0x04, 0x70) 0 1 0 /* Port 0.3 IO */
|
||||
|
||||
0x82000000 0x5 0 MBUS_ID(0x08, 0xe8) 0 1 0 /* Port 1.0 MEM */
|
||||
0x81000000 0x5 0 MBUS_ID(0x08, 0xe0) 0 1 0 /* Port 1.0 IO */
|
||||
0x82000000 0x6 0 MBUS_ID(0x08, 0xd8) 0 1 0 /* Port 1.1 MEM */
|
||||
0x81000000 0x6 0 MBUS_ID(0x08, 0xd0) 0 1 0 /* Port 1.1 IO */
|
||||
0x82000000 0x7 0 MBUS_ID(0x08, 0xb8) 0 1 0 /* Port 1.2 MEM */
|
||||
0x81000000 0x7 0 MBUS_ID(0x08, 0xb0) 0 1 0 /* Port 1.2 IO */
|
||||
0x82000000 0x8 0 MBUS_ID(0x08, 0x78) 0 1 0 /* Port 1.3 MEM */
|
||||
0x81000000 0x8 0 MBUS_ID(0x08, 0x70) 0 1 0 /* Port 1.3 IO */
|
||||
|
||||
0x82000000 0x9 0 MBUS_ID(0x04, 0xf8) 0 1 0 /* Port 2.0 MEM */
|
||||
0x81000000 0x9 0 MBUS_ID(0x04, 0xf0) 0 1 0 /* Port 2.0 IO */
|
||||
|
||||
0x82000000 0xa 0 MBUS_ID(0x08, 0xf8) 0 1 0 /* Port 3.0 MEM */
|
||||
0x81000000 0xa 0 MBUS_ID(0x08, 0xf0) 0 1 0 /* Port 3.0 IO */>;
|
||||
|
||||
pcie@1,0 {
|
||||
device_type = "pci";
|
||||
assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
|
||||
reg = <0x0800 0 0 0 0>;
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
#interrupt-cells = <1>;
|
||||
ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0
|
||||
0x81000000 0 0 0x81000000 0x1 0 1 0>;
|
||||
interrupt-map-mask = <0 0 0 0>;
|
||||
interrupt-map = <0 0 0 0 &mpic 58>;
|
||||
marvell,pcie-port = <0>;
|
||||
marvell,pcie-lane = <0>;
|
||||
num-lanes = <1>;
|
||||
/* low-active PERST# reset on GPIO 25 */
|
||||
reset-gpios = <&gpio0 25 1>;
|
||||
/* wait 20ms for device settle after reset deassertion */
|
||||
reset-delay-us = <20000>;
|
||||
clocks = <&gateclk 5>;
|
||||
};
|
||||
|
||||
pcie@2,0 {
|
||||
device_type = "pci";
|
||||
assigned-addresses = <0x82001000 0 0x44000 0 0x2000>;
|
||||
reg = <0x1000 0 0 0 0>;
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
#interrupt-cells = <1>;
|
||||
ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0
|
||||
0x81000000 0 0 0x81000000 0x2 0 1 0>;
|
||||
interrupt-map-mask = <0 0 0 0>;
|
||||
interrupt-map = <0 0 0 0 &mpic 59>;
|
||||
marvell,pcie-port = <0>;
|
||||
marvell,pcie-lane = <1>;
|
||||
num-lanes = <1>;
|
||||
clocks = <&gateclk 6>;
|
||||
};
|
||||
|
||||
pcie@3,0 {
|
||||
device_type = "pci";
|
||||
assigned-addresses = <0x82001800 0 0x48000 0 0x2000>;
|
||||
reg = <0x1800 0 0 0 0>;
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
#interrupt-cells = <1>;
|
||||
ranges = <0x82000000 0 0 0x82000000 0x3 0 1 0
|
||||
0x81000000 0 0 0x81000000 0x3 0 1 0>;
|
||||
interrupt-map-mask = <0 0 0 0>;
|
||||
interrupt-map = <0 0 0 0 &mpic 60>;
|
||||
marvell,pcie-port = <0>;
|
||||
marvell,pcie-lane = <2>;
|
||||
num-lanes = <1>;
|
||||
clocks = <&gateclk 7>;
|
||||
};
|
||||
|
||||
pcie@4,0 {
|
||||
device_type = "pci";
|
||||
assigned-addresses = <0x82002000 0 0x4c000 0 0x2000>;
|
||||
reg = <0x2000 0 0 0 0>;
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
#interrupt-cells = <1>;
|
||||
ranges = <0x82000000 0 0 0x82000000 0x4 0 1 0
|
||||
0x81000000 0 0 0x81000000 0x4 0 1 0>;
|
||||
interrupt-map-mask = <0 0 0 0>;
|
||||
interrupt-map = <0 0 0 0 &mpic 61>;
|
||||
marvell,pcie-port = <0>;
|
||||
marvell,pcie-lane = <3>;
|
||||
num-lanes = <1>;
|
||||
clocks = <&gateclk 8>;
|
||||
};
|
||||
|
||||
pcie@5,0 {
|
||||
device_type = "pci";
|
||||
assigned-addresses = <0x82002800 0 0x80000 0 0x2000>;
|
||||
reg = <0x2800 0 0 0 0>;
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
#interrupt-cells = <1>;
|
||||
ranges = <0x82000000 0 0 0x82000000 0x5 0 1 0
|
||||
0x81000000 0 0 0x81000000 0x5 0 1 0>;
|
||||
interrupt-map-mask = <0 0 0 0>;
|
||||
interrupt-map = <0 0 0 0 &mpic 62>;
|
||||
marvell,pcie-port = <1>;
|
||||
marvell,pcie-lane = <0>;
|
||||
num-lanes = <1>;
|
||||
clocks = <&gateclk 9>;
|
||||
};
|
||||
|
||||
pcie@6,0 {
|
||||
device_type = "pci";
|
||||
assigned-addresses = <0x82003000 0 0x84000 0 0x2000>;
|
||||
reg = <0x3000 0 0 0 0>;
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
#interrupt-cells = <1>;
|
||||
ranges = <0x82000000 0 0 0x82000000 0x6 0 1 0
|
||||
0x81000000 0 0 0x81000000 0x6 0 1 0>;
|
||||
interrupt-map-mask = <0 0 0 0>;
|
||||
interrupt-map = <0 0 0 0 &mpic 63>;
|
||||
marvell,pcie-port = <1>;
|
||||
marvell,pcie-lane = <1>;
|
||||
num-lanes = <1>;
|
||||
clocks = <&gateclk 10>;
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
||||
|
|
@ -50,7 +50,7 @@ properties:
|
|||
items:
|
||||
pattern: '^fic[0-3]$'
|
||||
|
||||
dma-coherent: true
|
||||
dma-noncoherent: true
|
||||
|
||||
ranges:
|
||||
minItems: 1
|
||||
|
|
@ -65,33 +65,33 @@ unevaluatedProperties: false
|
|||
examples:
|
||||
- |
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
pcie0: pcie@2030000000 {
|
||||
compatible = "microchip,pcie-host-1.0";
|
||||
reg = <0x0 0x70000000 0x0 0x08000000>,
|
||||
<0x0 0x43008000 0x0 0x00002000>,
|
||||
<0x0 0x4300a000 0x0 0x00002000>;
|
||||
reg-names = "cfg", "bridge", "ctrl";
|
||||
device_type = "pci";
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
pcie0: pcie@2030000000 {
|
||||
compatible = "microchip,pcie-host-1.0";
|
||||
reg = <0x0 0x70000000 0x0 0x08000000>,
|
||||
<0x0 0x43008000 0x0 0x00002000>,
|
||||
<0x0 0x4300a000 0x0 0x00002000>;
|
||||
reg-names = "cfg", "bridge", "ctrl";
|
||||
device_type = "pci";
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
#interrupt-cells = <1>;
|
||||
interrupts = <119>;
|
||||
interrupt-map-mask = <0x0 0x0 0x0 0x7>;
|
||||
interrupt-map = <0 0 0 1 &pcie_intc0 0>,
|
||||
<0 0 0 2 &pcie_intc0 1>,
|
||||
<0 0 0 3 &pcie_intc0 2>,
|
||||
<0 0 0 4 &pcie_intc0 3>;
|
||||
interrupt-parent = <&plic0>;
|
||||
msi-parent = <&pcie0>;
|
||||
msi-controller;
|
||||
bus-range = <0x00 0x7f>;
|
||||
ranges = <0x03000000 0x0 0x78000000 0x0 0x78000000 0x0 0x04000000>;
|
||||
pcie_intc0: interrupt-controller {
|
||||
#address-cells = <0>;
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-controller;
|
||||
};
|
||||
#interrupt-cells = <1>;
|
||||
interrupts = <119>;
|
||||
interrupt-map-mask = <0x0 0x0 0x0 0x7>;
|
||||
interrupt-map = <0 0 0 1 &pcie_intc0 0>,
|
||||
<0 0 0 2 &pcie_intc0 1>,
|
||||
<0 0 0 3 &pcie_intc0 2>,
|
||||
<0 0 0 4 &pcie_intc0 3>;
|
||||
interrupt-parent = <&plic0>;
|
||||
msi-parent = <&pcie0>;
|
||||
msi-controller;
|
||||
bus-range = <0x00 0x7f>;
|
||||
ranges = <0x03000000 0x0 0x78000000 0x0 0x78000000 0x0 0x04000000>;
|
||||
pcie_intc0: interrupt-controller {
|
||||
#address-cells = <0>;
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-controller;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,310 +0,0 @@
|
|||
* Marvell EBU PCIe interfaces
|
||||
|
||||
Mandatory properties:
|
||||
|
||||
- compatible: one of the following values:
|
||||
marvell,armada-370-pcie
|
||||
marvell,armada-xp-pcie
|
||||
marvell,dove-pcie
|
||||
marvell,kirkwood-pcie
|
||||
- #address-cells, set to <3>
|
||||
- #size-cells, set to <2>
|
||||
- #interrupt-cells, set to <1>
|
||||
- bus-range: PCI bus numbers covered
|
||||
- device_type, set to "pci"
|
||||
- ranges: ranges describing the MMIO registers to control the PCIe
|
||||
interfaces, and ranges describing the MBus windows needed to access
|
||||
the memory and I/O regions of each PCIe interface.
|
||||
- msi-parent: Link to the hardware entity that serves as the Message
|
||||
Signaled Interrupt controller for this PCI controller.
|
||||
|
||||
The ranges describing the MMIO registers have the following layout:
|
||||
|
||||
0x82000000 0 r MBUS_ID(0xf0, 0x01) r 0 s
|
||||
|
||||
where:
|
||||
|
||||
* r is a 32-bits value that gives the offset of the MMIO
|
||||
registers of this PCIe interface, from the base of the internal
|
||||
registers.
|
||||
|
||||
* s is a 32-bits value that give the size of this MMIO
|
||||
registers area. This range entry translates the '0x82000000 0 r' PCI
|
||||
address into the 'MBUS_ID(0xf0, 0x01) r' CPU address, which is part
|
||||
of the internal register window (as identified by MBUS_ID(0xf0,
|
||||
0x01)).
|
||||
|
||||
The ranges describing the MBus windows have the following layout:
|
||||
|
||||
0x8t000000 s 0 MBUS_ID(w, a) 0 1 0
|
||||
|
||||
where:
|
||||
|
||||
* t is the type of the MBus window (as defined by the standard PCI DT
|
||||
bindings), 1 for I/O and 2 for memory.
|
||||
|
||||
* s is the PCI slot that corresponds to this PCIe interface
|
||||
|
||||
* w is the 'target ID' value for the MBus window
|
||||
|
||||
* a the 'attribute' value for the MBus window.
|
||||
|
||||
Since the location and size of the different MBus windows is not fixed in
|
||||
hardware, and only determined in runtime, those ranges cover the full first
|
||||
4 GB of the physical address space, and do not translate into a valid CPU
|
||||
address.
|
||||
|
||||
In addition, the device tree node must have sub-nodes describing each
|
||||
PCIe interface, having the following mandatory properties:
|
||||
|
||||
- reg: used only for interrupt mapping, so only the first four bytes
|
||||
are used to refer to the correct bus number and device number.
|
||||
- assigned-addresses: reference to the MMIO registers used to control
|
||||
this PCIe interface.
|
||||
- clocks: the clock associated to this PCIe interface
|
||||
- marvell,pcie-port: the physical PCIe port number
|
||||
- status: either "disabled" or "okay"
|
||||
- device_type, set to "pci"
|
||||
- #address-cells, set to <3>
|
||||
- #size-cells, set to <2>
|
||||
- #interrupt-cells, set to <1>
|
||||
- ranges, translating the MBus windows ranges of the parent node into
|
||||
standard PCI addresses.
|
||||
- interrupt-map-mask and interrupt-map, standard PCI properties to
|
||||
define the mapping of the PCIe interface to interrupt numbers.
|
||||
|
||||
and the following optional properties:
|
||||
- marvell,pcie-lane: the physical PCIe lane number, for ports having
|
||||
multiple lanes. If this property is not found, we assume that the
|
||||
value is 0.
|
||||
- num-lanes: number of SerDes PCIe lanes for this link (1 or 4)
|
||||
- reset-gpios: optional GPIO to PERST#
|
||||
- reset-delay-us: delay in us to wait after reset de-assertion, if not
|
||||
specified will default to 100ms, as required by the PCIe specification.
|
||||
- interrupt-names: list of interrupt names, supported are:
|
||||
- "intx" - interrupt line triggered by one of the legacy interrupt
|
||||
- interrupts or interrupts-extended: List of the interrupt sources which
|
||||
corresponding to the "interrupt-names". If non-empty then also additional
|
||||
'interrupt-controller' subnode must be defined.
|
||||
|
||||
Example:
|
||||
|
||||
pcie-controller {
|
||||
compatible = "marvell,armada-xp-pcie";
|
||||
device_type = "pci";
|
||||
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
|
||||
bus-range = <0x00 0xff>;
|
||||
msi-parent = <&mpic>;
|
||||
|
||||
ranges =
|
||||
<0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000 /* Port 0.0 registers */
|
||||
0x82000000 0 0x42000 MBUS_ID(0xf0, 0x01) 0x42000 0 0x00002000 /* Port 2.0 registers */
|
||||
0x82000000 0 0x44000 MBUS_ID(0xf0, 0x01) 0x44000 0 0x00002000 /* Port 0.1 registers */
|
||||
0x82000000 0 0x48000 MBUS_ID(0xf0, 0x01) 0x48000 0 0x00002000 /* Port 0.2 registers */
|
||||
0x82000000 0 0x4c000 MBUS_ID(0xf0, 0x01) 0x4c000 0 0x00002000 /* Port 0.3 registers */
|
||||
0x82000000 0 0x80000 MBUS_ID(0xf0, 0x01) 0x80000 0 0x00002000 /* Port 1.0 registers */
|
||||
0x82000000 0 0x82000 MBUS_ID(0xf0, 0x01) 0x82000 0 0x00002000 /* Port 3.0 registers */
|
||||
0x82000000 0 0x84000 MBUS_ID(0xf0, 0x01) 0x84000 0 0x00002000 /* Port 1.1 registers */
|
||||
0x82000000 0 0x88000 MBUS_ID(0xf0, 0x01) 0x88000 0 0x00002000 /* Port 1.2 registers */
|
||||
0x82000000 0 0x8c000 MBUS_ID(0xf0, 0x01) 0x8c000 0 0x00002000 /* Port 1.3 registers */
|
||||
0x82000000 0x1 0 MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 0.0 MEM */
|
||||
0x81000000 0x1 0 MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 0.0 IO */
|
||||
0x82000000 0x2 0 MBUS_ID(0x04, 0xd8) 0 1 0 /* Port 0.1 MEM */
|
||||
0x81000000 0x2 0 MBUS_ID(0x04, 0xd0) 0 1 0 /* Port 0.1 IO */
|
||||
0x82000000 0x3 0 MBUS_ID(0x04, 0xb8) 0 1 0 /* Port 0.2 MEM */
|
||||
0x81000000 0x3 0 MBUS_ID(0x04, 0xb0) 0 1 0 /* Port 0.2 IO */
|
||||
0x82000000 0x4 0 MBUS_ID(0x04, 0x78) 0 1 0 /* Port 0.3 MEM */
|
||||
0x81000000 0x4 0 MBUS_ID(0x04, 0x70) 0 1 0 /* Port 0.3 IO */
|
||||
|
||||
0x82000000 0x5 0 MBUS_ID(0x08, 0xe8) 0 1 0 /* Port 1.0 MEM */
|
||||
0x81000000 0x5 0 MBUS_ID(0x08, 0xe0) 0 1 0 /* Port 1.0 IO */
|
||||
0x82000000 0x6 0 MBUS_ID(0x08, 0xd8) 0 1 0 /* Port 1.1 MEM */
|
||||
0x81000000 0x6 0 MBUS_ID(0x08, 0xd0) 0 1 0 /* Port 1.1 IO */
|
||||
0x82000000 0x7 0 MBUS_ID(0x08, 0xb8) 0 1 0 /* Port 1.2 MEM */
|
||||
0x81000000 0x7 0 MBUS_ID(0x08, 0xb0) 0 1 0 /* Port 1.2 IO */
|
||||
0x82000000 0x8 0 MBUS_ID(0x08, 0x78) 0 1 0 /* Port 1.3 MEM */
|
||||
0x81000000 0x8 0 MBUS_ID(0x08, 0x70) 0 1 0 /* Port 1.3 IO */
|
||||
|
||||
0x82000000 0x9 0 MBUS_ID(0x04, 0xf8) 0 1 0 /* Port 2.0 MEM */
|
||||
0x81000000 0x9 0 MBUS_ID(0x04, 0xf0) 0 1 0 /* Port 2.0 IO */
|
||||
|
||||
0x82000000 0xa 0 MBUS_ID(0x08, 0xf8) 0 1 0 /* Port 3.0 MEM */
|
||||
0x81000000 0xa 0 MBUS_ID(0x08, 0xf0) 0 1 0 /* Port 3.0 IO */>;
|
||||
|
||||
pcie@1,0 {
|
||||
device_type = "pci";
|
||||
assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
|
||||
reg = <0x0800 0 0 0 0>;
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
#interrupt-cells = <1>;
|
||||
ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0
|
||||
0x81000000 0 0 0x81000000 0x1 0 1 0>;
|
||||
interrupt-map-mask = <0 0 0 0>;
|
||||
interrupt-map = <0 0 0 0 &mpic 58>;
|
||||
marvell,pcie-port = <0>;
|
||||
marvell,pcie-lane = <0>;
|
||||
num-lanes = <1>;
|
||||
/* low-active PERST# reset on GPIO 25 */
|
||||
reset-gpios = <&gpio0 25 1>;
|
||||
/* wait 20ms for device settle after reset deassertion */
|
||||
reset-delay-us = <20000>;
|
||||
clocks = <&gateclk 5>;
|
||||
};
|
||||
|
||||
pcie@2,0 {
|
||||
device_type = "pci";
|
||||
assigned-addresses = <0x82001000 0 0x44000 0 0x2000>;
|
||||
reg = <0x1000 0 0 0 0>;
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
#interrupt-cells = <1>;
|
||||
ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0
|
||||
0x81000000 0 0 0x81000000 0x2 0 1 0>;
|
||||
interrupt-map-mask = <0 0 0 0>;
|
||||
interrupt-map = <0 0 0 0 &mpic 59>;
|
||||
marvell,pcie-port = <0>;
|
||||
marvell,pcie-lane = <1>;
|
||||
num-lanes = <1>;
|
||||
clocks = <&gateclk 6>;
|
||||
};
|
||||
|
||||
pcie@3,0 {
|
||||
device_type = "pci";
|
||||
assigned-addresses = <0x82001800 0 0x48000 0 0x2000>;
|
||||
reg = <0x1800 0 0 0 0>;
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
#interrupt-cells = <1>;
|
||||
ranges = <0x82000000 0 0 0x82000000 0x3 0 1 0
|
||||
0x81000000 0 0 0x81000000 0x3 0 1 0>;
|
||||
interrupt-map-mask = <0 0 0 0>;
|
||||
interrupt-map = <0 0 0 0 &mpic 60>;
|
||||
marvell,pcie-port = <0>;
|
||||
marvell,pcie-lane = <2>;
|
||||
num-lanes = <1>;
|
||||
clocks = <&gateclk 7>;
|
||||
};
|
||||
|
||||
pcie@4,0 {
|
||||
device_type = "pci";
|
||||
assigned-addresses = <0x82002000 0 0x4c000 0 0x2000>;
|
||||
reg = <0x2000 0 0 0 0>;
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
#interrupt-cells = <1>;
|
||||
ranges = <0x82000000 0 0 0x82000000 0x4 0 1 0
|
||||
0x81000000 0 0 0x81000000 0x4 0 1 0>;
|
||||
interrupt-map-mask = <0 0 0 0>;
|
||||
interrupt-map = <0 0 0 0 &mpic 61>;
|
||||
marvell,pcie-port = <0>;
|
||||
marvell,pcie-lane = <3>;
|
||||
num-lanes = <1>;
|
||||
clocks = <&gateclk 8>;
|
||||
};
|
||||
|
||||
pcie@5,0 {
|
||||
device_type = "pci";
|
||||
assigned-addresses = <0x82002800 0 0x80000 0 0x2000>;
|
||||
reg = <0x2800 0 0 0 0>;
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
#interrupt-cells = <1>;
|
||||
ranges = <0x82000000 0 0 0x82000000 0x5 0 1 0
|
||||
0x81000000 0 0 0x81000000 0x5 0 1 0>;
|
||||
interrupt-map-mask = <0 0 0 0>;
|
||||
interrupt-map = <0 0 0 0 &mpic 62>;
|
||||
marvell,pcie-port = <1>;
|
||||
marvell,pcie-lane = <0>;
|
||||
num-lanes = <1>;
|
||||
clocks = <&gateclk 9>;
|
||||
};
|
||||
|
||||
pcie@6,0 {
|
||||
device_type = "pci";
|
||||
assigned-addresses = <0x82003000 0 0x84000 0 0x2000>;
|
||||
reg = <0x3000 0 0 0 0>;
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
#interrupt-cells = <1>;
|
||||
ranges = <0x82000000 0 0 0x82000000 0x6 0 1 0
|
||||
0x81000000 0 0 0x81000000 0x6 0 1 0>;
|
||||
interrupt-map-mask = <0 0 0 0>;
|
||||
interrupt-map = <0 0 0 0 &mpic 63>;
|
||||
marvell,pcie-port = <1>;
|
||||
marvell,pcie-lane = <1>;
|
||||
num-lanes = <1>;
|
||||
clocks = <&gateclk 10>;
|
||||
};
|
||||
|
||||
pcie@7,0 {
|
||||
device_type = "pci";
|
||||
assigned-addresses = <0x82003800 0 0x88000 0 0x2000>;
|
||||
reg = <0x3800 0 0 0 0>;
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
#interrupt-cells = <1>;
|
||||
ranges = <0x82000000 0 0 0x82000000 0x7 0 1 0
|
||||
0x81000000 0 0 0x81000000 0x7 0 1 0>;
|
||||
interrupt-map-mask = <0 0 0 0>;
|
||||
interrupt-map = <0 0 0 0 &mpic 64>;
|
||||
marvell,pcie-port = <1>;
|
||||
marvell,pcie-lane = <2>;
|
||||
num-lanes = <1>;
|
||||
clocks = <&gateclk 11>;
|
||||
};
|
||||
|
||||
pcie@8,0 {
|
||||
device_type = "pci";
|
||||
assigned-addresses = <0x82004000 0 0x8c000 0 0x2000>;
|
||||
reg = <0x4000 0 0 0 0>;
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
#interrupt-cells = <1>;
|
||||
ranges = <0x82000000 0 0 0x82000000 0x8 0 1 0
|
||||
0x81000000 0 0 0x81000000 0x8 0 1 0>;
|
||||
interrupt-map-mask = <0 0 0 0>;
|
||||
interrupt-map = <0 0 0 0 &mpic 65>;
|
||||
marvell,pcie-port = <1>;
|
||||
marvell,pcie-lane = <3>;
|
||||
num-lanes = <1>;
|
||||
clocks = <&gateclk 12>;
|
||||
};
|
||||
|
||||
pcie@9,0 {
|
||||
device_type = "pci";
|
||||
assigned-addresses = <0x82004800 0 0x42000 0 0x2000>;
|
||||
reg = <0x4800 0 0 0 0>;
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
#interrupt-cells = <1>;
|
||||
ranges = <0x82000000 0 0 0x82000000 0x9 0 1 0
|
||||
0x81000000 0 0 0x81000000 0x9 0 1 0>;
|
||||
interrupt-map-mask = <0 0 0 0>;
|
||||
interrupt-map = <0 0 0 0 &mpic 99>;
|
||||
marvell,pcie-port = <2>;
|
||||
marvell,pcie-lane = <0>;
|
||||
num-lanes = <1>;
|
||||
clocks = <&gateclk 26>;
|
||||
};
|
||||
|
||||
pcie@a,0 {
|
||||
device_type = "pci";
|
||||
assigned-addresses = <0x82005000 0 0x82000 0 0x2000>;
|
||||
reg = <0x5000 0 0 0 0>;
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
#interrupt-cells = <1>;
|
||||
ranges = <0x82000000 0 0 0x82000000 0xa 0 1 0
|
||||
0x81000000 0 0 0x81000000 0xa 0 1 0>;
|
||||
interrupt-map-mask = <0 0 0 0>;
|
||||
interrupt-map = <0 0 0 0 &mpic 103>;
|
||||
marvell,pcie-port = <3>;
|
||||
marvell,pcie-lane = <0>;
|
||||
num-lanes = <1>;
|
||||
clocks = <&gateclk 27>;
|
||||
};
|
||||
};
|
||||
|
|
@ -74,7 +74,7 @@ properties:
|
|||
|
||||
reset-gpios:
|
||||
description: Must contain a phandle to a GPIO controller followed by GPIO
|
||||
that is being used as PERST input signal. Please refer to pci.txt.
|
||||
that is being used as PERST input signal.
|
||||
|
||||
phys:
|
||||
minItems: 1
|
||||
|
|
|
|||
|
|
@ -1,48 +0,0 @@
|
|||
* Marvell Armada 7K/8K PCIe interface
|
||||
|
||||
This PCIe host controller is based on the Synopsys DesignWare PCIe IP
|
||||
and thus inherits all the common properties defined in snps,dw-pcie.yaml.
|
||||
|
||||
Required properties:
|
||||
- compatible: "marvell,armada8k-pcie"
|
||||
- reg: must contain two register regions
|
||||
- the control register region
|
||||
- the config space region
|
||||
- reg-names:
|
||||
- "ctrl" for the control register region
|
||||
- "config" for the config space region
|
||||
- interrupts: Interrupt specifier for the PCIe controller
|
||||
- clocks: reference to the PCIe controller clocks
|
||||
- clock-names: mandatory if there is a second clock, in this case the
|
||||
name must be "core" for the first clock and "reg" for the second
|
||||
one
|
||||
|
||||
Optional properties:
|
||||
- phys: phandle(s) to PHY node(s) following the generic PHY bindings.
|
||||
Either 1, 2 or 4 PHYs might be needed depending on the number of
|
||||
PCIe lanes.
|
||||
- phy-names: names of the PHYs corresponding to the number of lanes.
|
||||
Must be "cp0-pcie0-x4-lane0-phy", "cp0-pcie0-x4-lane1-phy" for
|
||||
2 PHYs.
|
||||
|
||||
Example:
|
||||
|
||||
pcie@f2600000 {
|
||||
compatible = "marvell,armada8k-pcie", "snps,dw-pcie";
|
||||
reg = <0 0xf2600000 0 0x10000>, <0 0xf6f00000 0 0x80000>;
|
||||
reg-names = "ctrl", "config";
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
#interrupt-cells = <1>;
|
||||
device_type = "pci";
|
||||
dma-coherent;
|
||||
|
||||
bus-range = <0 0xff>;
|
||||
ranges = <0x81000000 0 0xf9000000 0 0xf9000000 0 0x10000 /* downstream I/O */
|
||||
0x82000000 0 0xf6000000 0 0xf6000000 0 0xf00000>; /* non-prefetchable memory */
|
||||
interrupt-map-mask = <0 0 0 0>;
|
||||
interrupt-map = <0 0 0 0 &gic 0 GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
|
||||
num-lanes = <1>;
|
||||
clocks = <&cpm_syscon0 1 13>;
|
||||
};
|
||||
|
|
@ -1,171 +0,0 @@
|
|||
This document describes the generic device tree binding for describing the
|
||||
relationship between PCI(e) devices and IOMMU(s).
|
||||
|
||||
Each PCI(e) device under a root complex is uniquely identified by its Requester
|
||||
ID (AKA RID). A Requester ID is a triplet of a Bus number, Device number, and
|
||||
Function number.
|
||||
|
||||
For the purpose of this document, when treated as a numeric value, a RID is
|
||||
formatted such that:
|
||||
|
||||
* Bits [15:8] are the Bus number.
|
||||
* Bits [7:3] are the Device number.
|
||||
* Bits [2:0] are the Function number.
|
||||
* Any other bits required for padding must be zero.
|
||||
|
||||
IOMMUs may distinguish PCI devices through sideband data derived from the
|
||||
Requester ID. While a given PCI device can only master through one IOMMU, a
|
||||
root complex may split masters across a set of IOMMUs (e.g. with one IOMMU per
|
||||
bus).
|
||||
|
||||
The generic 'iommus' property is insufficient to describe this relationship,
|
||||
and a mechanism is required to map from a PCI device to its IOMMU and sideband
|
||||
data.
|
||||
|
||||
For generic IOMMU bindings, see
|
||||
Documentation/devicetree/bindings/iommu/iommu.txt.
|
||||
|
||||
|
||||
PCI root complex
|
||||
================
|
||||
|
||||
Optional properties
|
||||
-------------------
|
||||
|
||||
- iommu-map: Maps a Requester ID to an IOMMU and associated IOMMU specifier
|
||||
data.
|
||||
|
||||
The property is an arbitrary number of tuples of
|
||||
(rid-base,iommu,iommu-base,length).
|
||||
|
||||
Any RID r in the interval [rid-base, rid-base + length) is associated with
|
||||
the listed IOMMU, with the IOMMU specifier (r - rid-base + iommu-base).
|
||||
|
||||
- iommu-map-mask: A mask to be applied to each Requester ID prior to being
|
||||
mapped to an IOMMU specifier per the iommu-map property.
|
||||
|
||||
|
||||
Example (1)
|
||||
===========
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
iommu: iommu@a {
|
||||
reg = <0xa 0x1>;
|
||||
compatible = "vendor,some-iommu";
|
||||
#iommu-cells = <1>;
|
||||
};
|
||||
|
||||
pci: pci@f {
|
||||
reg = <0xf 0x1>;
|
||||
compatible = "vendor,pcie-root-complex";
|
||||
device_type = "pci";
|
||||
|
||||
/*
|
||||
* The sideband data provided to the IOMMU is the RID,
|
||||
* identity-mapped.
|
||||
*/
|
||||
iommu-map = <0x0 &iommu 0x0 0x10000>;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
Example (2)
|
||||
===========
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
iommu: iommu@a {
|
||||
reg = <0xa 0x1>;
|
||||
compatible = "vendor,some-iommu";
|
||||
#iommu-cells = <1>;
|
||||
};
|
||||
|
||||
pci: pci@f {
|
||||
reg = <0xf 0x1>;
|
||||
compatible = "vendor,pcie-root-complex";
|
||||
device_type = "pci";
|
||||
|
||||
/*
|
||||
* The sideband data provided to the IOMMU is the RID with the
|
||||
* function bits masked out.
|
||||
*/
|
||||
iommu-map = <0x0 &iommu 0x0 0x10000>;
|
||||
iommu-map-mask = <0xfff8>;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
Example (3)
|
||||
===========
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
iommu: iommu@a {
|
||||
reg = <0xa 0x1>;
|
||||
compatible = "vendor,some-iommu";
|
||||
#iommu-cells = <1>;
|
||||
};
|
||||
|
||||
pci: pci@f {
|
||||
reg = <0xf 0x1>;
|
||||
compatible = "vendor,pcie-root-complex";
|
||||
device_type = "pci";
|
||||
|
||||
/*
|
||||
* The sideband data provided to the IOMMU is the RID,
|
||||
* but the high bits of the bus number are flipped.
|
||||
*/
|
||||
iommu-map = <0x0000 &iommu 0x8000 0x8000>,
|
||||
<0x8000 &iommu 0x0000 0x8000>;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
Example (4)
|
||||
===========
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
iommu_a: iommu@a {
|
||||
reg = <0xa 0x1>;
|
||||
compatible = "vendor,some-iommu";
|
||||
#iommu-cells = <1>;
|
||||
};
|
||||
|
||||
iommu_b: iommu@b {
|
||||
reg = <0xb 0x1>;
|
||||
compatible = "vendor,some-iommu";
|
||||
#iommu-cells = <1>;
|
||||
};
|
||||
|
||||
iommu_c: iommu@c {
|
||||
reg = <0xc 0x1>;
|
||||
compatible = "vendor,some-iommu";
|
||||
#iommu-cells = <1>;
|
||||
};
|
||||
|
||||
pci: pci@f {
|
||||
reg = <0xf 0x1>;
|
||||
compatible = "vendor,pcie-root-complex";
|
||||
device_type = "pci";
|
||||
|
||||
/*
|
||||
* Devices with bus number 0-127 are mastered via IOMMU
|
||||
* a, with sideband data being RID[14:0].
|
||||
* Devices with bus number 128-255 are mastered via
|
||||
* IOMMU b, with sideband data being RID[14:0].
|
||||
* No devices master via IOMMU c.
|
||||
*/
|
||||
iommu-map = <0x0000 &iommu_a 0x0000 0x8000>,
|
||||
<0x8000 &iommu_b 0x0000 0x8000>;
|
||||
};
|
||||
};
|
||||
|
|
@ -1,220 +0,0 @@
|
|||
This document describes the generic device tree binding for describing the
|
||||
relationship between PCI devices and MSI controllers.
|
||||
|
||||
Each PCI device under a root complex is uniquely identified by its Requester ID
|
||||
(AKA RID). A Requester ID is a triplet of a Bus number, Device number, and
|
||||
Function number.
|
||||
|
||||
For the purpose of this document, when treated as a numeric value, a RID is
|
||||
formatted such that:
|
||||
|
||||
* Bits [15:8] are the Bus number.
|
||||
* Bits [7:3] are the Device number.
|
||||
* Bits [2:0] are the Function number.
|
||||
* Any other bits required for padding must be zero.
|
||||
|
||||
MSIs may be distinguished in part through the use of sideband data accompanying
|
||||
writes. In the case of PCI devices, this sideband data may be derived from the
|
||||
Requester ID. A mechanism is required to associate a device with both the MSI
|
||||
controllers it can address, and the sideband data that will be associated with
|
||||
its writes to those controllers.
|
||||
|
||||
For generic MSI bindings, see
|
||||
Documentation/devicetree/bindings/interrupt-controller/msi.txt.
|
||||
|
||||
|
||||
PCI root complex
|
||||
================
|
||||
|
||||
Optional properties
|
||||
-------------------
|
||||
|
||||
- msi-map: Maps a Requester ID to an MSI controller and associated
|
||||
msi-specifier data. The property is an arbitrary number of tuples of
|
||||
(rid-base,msi-controller,msi-base,length), where:
|
||||
|
||||
* rid-base is a single cell describing the first RID matched by the entry.
|
||||
|
||||
* msi-controller is a single phandle to an MSI controller
|
||||
|
||||
* msi-base is an msi-specifier describing the msi-specifier produced for the
|
||||
first RID matched by the entry.
|
||||
|
||||
* length is a single cell describing how many consecutive RIDs are matched
|
||||
following the rid-base.
|
||||
|
||||
Any RID r in the interval [rid-base, rid-base + length) is associated with
|
||||
the listed msi-controller, with the msi-specifier (r - rid-base + msi-base).
|
||||
|
||||
- msi-map-mask: A mask to be applied to each Requester ID prior to being mapped
|
||||
to an msi-specifier per the msi-map property.
|
||||
|
||||
- msi-parent: Describes the MSI parent of the root complex itself. Where
|
||||
the root complex and MSI controller do not pass sideband data with MSI
|
||||
writes, this property may be used to describe the MSI controller(s)
|
||||
used by PCI devices under the root complex, if defined as such in the
|
||||
binding for the root complex.
|
||||
|
||||
|
||||
Example (1)
|
||||
===========
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
msi: msi-controller@a {
|
||||
reg = <0xa 0x1>;
|
||||
compatible = "vendor,some-controller";
|
||||
msi-controller;
|
||||
#msi-cells = <1>;
|
||||
};
|
||||
|
||||
pci: pci@f {
|
||||
reg = <0xf 0x1>;
|
||||
compatible = "vendor,pcie-root-complex";
|
||||
device_type = "pci";
|
||||
|
||||
/*
|
||||
* The sideband data provided to the MSI controller is
|
||||
* the RID, identity-mapped.
|
||||
*/
|
||||
msi-map = <0x0 &msi_a 0x0 0x10000>,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
Example (2)
|
||||
===========
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
msi: msi-controller@a {
|
||||
reg = <0xa 0x1>;
|
||||
compatible = "vendor,some-controller";
|
||||
msi-controller;
|
||||
#msi-cells = <1>;
|
||||
};
|
||||
|
||||
pci: pci@f {
|
||||
reg = <0xf 0x1>;
|
||||
compatible = "vendor,pcie-root-complex";
|
||||
device_type = "pci";
|
||||
|
||||
/*
|
||||
* The sideband data provided to the MSI controller is
|
||||
* the RID, masked to only the device and function bits.
|
||||
*/
|
||||
msi-map = <0x0 &msi_a 0x0 0x100>,
|
||||
msi-map-mask = <0xff>
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
Example (3)
|
||||
===========
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
msi: msi-controller@a {
|
||||
reg = <0xa 0x1>;
|
||||
compatible = "vendor,some-controller";
|
||||
msi-controller;
|
||||
#msi-cells = <1>;
|
||||
};
|
||||
|
||||
pci: pci@f {
|
||||
reg = <0xf 0x1>;
|
||||
compatible = "vendor,pcie-root-complex";
|
||||
device_type = "pci";
|
||||
|
||||
/*
|
||||
* The sideband data provided to the MSI controller is
|
||||
* the RID, but the high bit of the bus number is
|
||||
* ignored.
|
||||
*/
|
||||
msi-map = <0x0000 &msi 0x0000 0x8000>,
|
||||
<0x8000 &msi 0x0000 0x8000>;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
Example (4)
|
||||
===========
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
msi: msi-controller@a {
|
||||
reg = <0xa 0x1>;
|
||||
compatible = "vendor,some-controller";
|
||||
msi-controller;
|
||||
#msi-cells = <1>;
|
||||
};
|
||||
|
||||
pci: pci@f {
|
||||
reg = <0xf 0x1>;
|
||||
compatible = "vendor,pcie-root-complex";
|
||||
device_type = "pci";
|
||||
|
||||
/*
|
||||
* The sideband data provided to the MSI controller is
|
||||
* the RID, but the high bit of the bus number is
|
||||
* negated.
|
||||
*/
|
||||
msi-map = <0x0000 &msi 0x8000 0x8000>,
|
||||
<0x8000 &msi 0x0000 0x8000>;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
Example (5)
|
||||
===========
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
msi_a: msi-controller@a {
|
||||
reg = <0xa 0x1>;
|
||||
compatible = "vendor,some-controller";
|
||||
msi-controller;
|
||||
#msi-cells = <1>;
|
||||
};
|
||||
|
||||
msi_b: msi-controller@b {
|
||||
reg = <0xb 0x1>;
|
||||
compatible = "vendor,some-controller";
|
||||
msi-controller;
|
||||
#msi-cells = <1>;
|
||||
};
|
||||
|
||||
msi_c: msi-controller@c {
|
||||
reg = <0xc 0x1>;
|
||||
compatible = "vendor,some-controller";
|
||||
msi-controller;
|
||||
#msi-cells = <1>;
|
||||
};
|
||||
|
||||
pci: pci@f {
|
||||
reg = <0xf 0x1>;
|
||||
compatible = "vendor,pcie-root-complex";
|
||||
device_type = "pci";
|
||||
|
||||
/*
|
||||
* The sideband data provided to MSI controller a is the
|
||||
* RID, but the high bit of the bus number is negated.
|
||||
* The sideband data provided to MSI controller b is the
|
||||
* RID, identity-mapped.
|
||||
* MSI controller c is not addressable.
|
||||
*/
|
||||
msi-map = <0x0000 &msi_a 0x8000 0x08000>,
|
||||
<0x8000 &msi_a 0x0000 0x08000>,
|
||||
<0x0000 &msi_b 0x0000 0x10000>;
|
||||
};
|
||||
};
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
PCI bus bridges have standardized Device Tree bindings:
|
||||
|
||||
PCI Bus Binding to: IEEE Std 1275-1994
|
||||
https://www.devicetree.org/open-firmware/bindings/pci/pci2_1.pdf
|
||||
|
||||
And for the interrupt mapping part:
|
||||
|
||||
Open Firmware Recommended Practice: Interrupt Mapping
|
||||
https://www.devicetree.org/open-firmware/practice/imap/imap0_9d.pdf
|
||||
|
||||
Additionally to the properties specified in the above standards a host bridge
|
||||
driver implementation may support the following properties:
|
||||
|
||||
- linux,pci-domain:
|
||||
If present this property assigns a fixed PCI domain number to a host bridge,
|
||||
otherwise an unstable (across boots) unique number will be assigned.
|
||||
It is required to either not set this property at all or set it for all
|
||||
host bridges in the system, otherwise potentially conflicting domain numbers
|
||||
may be assigned to root buses behind different host bridges. The domain
|
||||
number for each host bridge in the system must be unique.
|
||||
- max-link-speed:
|
||||
If present this property specifies PCI gen for link capability. Host
|
||||
drivers could add this as a strategy to avoid unnecessary operation for
|
||||
unsupported link speed, for instance, trying to do training for
|
||||
unsupported link speed, etc. Must be '4' for gen4, '3' for gen3, '2'
|
||||
for gen2, and '1' for gen1. Any other values are invalid.
|
||||
- reset-gpios:
|
||||
If present this property specifies PERST# GPIO. Host drivers can parse the
|
||||
GPIO and apply fundamental reset to endpoints.
|
||||
- supports-clkreq:
|
||||
If present this property specifies that CLKREQ signal routing exists from
|
||||
root port to downstream device and host bridge drivers can do programming
|
||||
which depends on CLKREQ signal existence. For example, programming root port
|
||||
not to advertise ASPM L1 Sub-States support if there is no CLKREQ signal.
|
||||
|
||||
PCI-PCI Bridge properties
|
||||
-------------------------
|
||||
|
||||
PCIe root ports and switch ports may be described explicitly in the device
|
||||
tree, as children of the host bridge node. Even though those devices are
|
||||
discoverable by probing, it might be necessary to describe properties that
|
||||
aren't provided by standard PCIe capabilities.
|
||||
|
||||
Required properties:
|
||||
|
||||
- reg:
|
||||
Identifies the PCI-PCI bridge. As defined in the IEEE Std 1275-1994
|
||||
document, it is a five-cell address encoded as (phys.hi phys.mid
|
||||
phys.lo size.hi size.lo). phys.hi should contain the device's BDF as
|
||||
0b00000000 bbbbbbbb dddddfff 00000000. The other cells should be zero.
|
||||
|
||||
The bus number is defined by firmware, through the standard bridge
|
||||
configuration mechanism. If this port is a switch port, then firmware
|
||||
allocates the bus number and writes it into the Secondary Bus Number
|
||||
register of the bridge directly above this port. Otherwise, the bus
|
||||
number of a root port is the first number in the bus-range property,
|
||||
defaulting to zero.
|
||||
|
||||
If firmware leaves the ARI Forwarding Enable bit set in the bridge
|
||||
above this port, then phys.hi contains the 8-bit function number as
|
||||
0b00000000 bbbbbbbb ffffffff 00000000. Note that the PCIe specification
|
||||
recommends that firmware only leaves ARI enabled when it knows that the
|
||||
OS is ARI-aware.
|
||||
|
||||
Optional properties:
|
||||
|
||||
- external-facing:
|
||||
When present, the port is external-facing. All bridges and endpoints
|
||||
downstream of this port are external to the machine. The OS can, for
|
||||
example, use this information to identify devices that cannot be
|
||||
trusted with relaxed DMA protection, as users could easily attach
|
||||
malicious devices to this port.
|
||||
|
||||
Example:
|
||||
|
||||
pcie@10000000 {
|
||||
compatible = "pci-host-ecam-generic";
|
||||
...
|
||||
pcie@0008 {
|
||||
/* Root port 00:01.0 is external-facing */
|
||||
reg = <0x00000800 0 0 0 0>;
|
||||
external-facing;
|
||||
};
|
||||
};
|
||||
|
|
@ -45,9 +45,10 @@ properties:
|
|||
|
||||
interrupts:
|
||||
minItems: 8
|
||||
maxItems: 8
|
||||
maxItems: 9
|
||||
|
||||
interrupt-names:
|
||||
minItems: 8
|
||||
items:
|
||||
- const: msi0
|
||||
- const: msi1
|
||||
|
|
@ -57,6 +58,7 @@ properties:
|
|||
- const: msi5
|
||||
- const: msi6
|
||||
- const: msi7
|
||||
- const: global
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
|
@ -129,7 +131,8 @@ examples:
|
|||
<GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>;
|
||||
<GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "msi0",
|
||||
"msi1",
|
||||
"msi2",
|
||||
|
|
@ -137,7 +140,8 @@ examples:
|
|||
"msi4",
|
||||
"msi5",
|
||||
"msi6",
|
||||
"msi7";
|
||||
"msi7",
|
||||
"global";
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-map-mask = <0 0 0 0x7>;
|
||||
interrupt-map = <0 0 0 1 &intc GIC_SPI 434 IRQ_TYPE_LEVEL_HIGH>,
|
||||
|
|
|
|||
|
|
@ -54,9 +54,10 @@ properties:
|
|||
|
||||
interrupts:
|
||||
minItems: 8
|
||||
maxItems: 8
|
||||
maxItems: 9
|
||||
|
||||
interrupt-names:
|
||||
minItems: 8
|
||||
items:
|
||||
- const: msi0
|
||||
- const: msi1
|
||||
|
|
@ -66,6 +67,7 @@ properties:
|
|||
- const: msi5
|
||||
- const: msi6
|
||||
- const: msi7
|
||||
- const: global
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
|
@ -149,9 +151,10 @@ examples:
|
|||
<GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>;
|
||||
<GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "msi0", "msi1", "msi2", "msi3",
|
||||
"msi4", "msi5", "msi6", "msi7";
|
||||
"msi4", "msi5", "msi6", "msi7", "global";
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-map-mask = <0 0 0 0x7>;
|
||||
interrupt-map = <0 0 0 1 &intc 0 0 0 434 IRQ_TYPE_LEVEL_HIGH>,
|
||||
|
|
|
|||
|
|
@ -49,9 +49,10 @@ properties:
|
|||
|
||||
interrupts:
|
||||
minItems: 8
|
||||
maxItems: 8
|
||||
maxItems: 9
|
||||
|
||||
interrupt-names:
|
||||
minItems: 8
|
||||
items:
|
||||
- const: msi0
|
||||
- const: msi1
|
||||
|
|
@ -61,6 +62,7 @@ properties:
|
|||
- const: msi5
|
||||
- const: msi6
|
||||
- const: msi7
|
||||
- const: global
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
|
@ -136,7 +138,8 @@ examples:
|
|||
<GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
|
||||
<GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "msi0",
|
||||
"msi1",
|
||||
"msi2",
|
||||
|
|
@ -144,7 +147,8 @@ examples:
|
|||
"msi4",
|
||||
"msi5",
|
||||
"msi6",
|
||||
"msi7";
|
||||
"msi7",
|
||||
"global";
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-map-mask = <0 0 0 0x7>;
|
||||
interrupt-map = <0 0 0 1 &intc 0 149 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
|
||||
|
|
|
|||
|
|
@ -49,9 +49,10 @@ properties:
|
|||
|
||||
interrupts:
|
||||
minItems: 8
|
||||
maxItems: 8
|
||||
maxItems: 9
|
||||
|
||||
interrupt-names:
|
||||
minItems: 8
|
||||
items:
|
||||
- const: msi0
|
||||
- const: msi1
|
||||
|
|
@ -61,6 +62,7 @@ properties:
|
|||
- const: msi5
|
||||
- const: msi6
|
||||
- const: msi7
|
||||
- const: global
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
|
@ -128,9 +130,10 @@ examples:
|
|||
<GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
|
||||
<GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "msi0", "msi1", "msi2", "msi3",
|
||||
"msi4", "msi5", "msi6", "msi7";
|
||||
"msi4", "msi5", "msi6", "msi7", "global";
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-map-mask = <0 0 0 0x7>;
|
||||
interrupt-map = <0 0 0 1 &intc 0 149 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
|
||||
|
|
|
|||
|
|
@ -61,9 +61,10 @@ properties:
|
|||
|
||||
interrupts:
|
||||
minItems: 8
|
||||
maxItems: 8
|
||||
maxItems: 9
|
||||
|
||||
interrupt-names:
|
||||
minItems: 8
|
||||
items:
|
||||
- const: msi0
|
||||
- const: msi1
|
||||
|
|
@ -73,6 +74,7 @@ properties:
|
|||
- const: msi5
|
||||
- const: msi6
|
||||
- const: msi7
|
||||
- const: global
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
|
@ -143,9 +145,10 @@ examples:
|
|||
<GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
|
||||
<GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "msi0", "msi1", "msi2", "msi3",
|
||||
"msi4", "msi5", "msi6", "msi7";
|
||||
"msi4", "msi5", "msi6", "msi7", "global";
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-map-mask = <0 0 0 0x7>;
|
||||
interrupt-map = <0 0 0 1 &intc 0 149 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
|
||||
|
|
|
|||
|
|
@ -51,9 +51,10 @@ properties:
|
|||
|
||||
interrupts:
|
||||
minItems: 8
|
||||
maxItems: 8
|
||||
maxItems: 9
|
||||
|
||||
interrupt-names:
|
||||
minItems: 8
|
||||
items:
|
||||
- const: msi0
|
||||
- const: msi1
|
||||
|
|
@ -63,6 +64,7 @@ properties:
|
|||
- const: msi5
|
||||
- const: msi6
|
||||
- const: msi7
|
||||
- const: global
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
|
@ -132,9 +134,10 @@ examples:
|
|||
<GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
|
||||
<GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "msi0", "msi1", "msi2", "msi3",
|
||||
"msi4", "msi5", "msi6", "msi7";
|
||||
"msi4", "msi5", "msi6", "msi7", "global";
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-map-mask = <0 0 0 0x7>;
|
||||
interrupt-map = <0 0 0 1 &intc 0 149 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ properties:
|
|||
- qcom,pcie-apq8064
|
||||
- qcom,pcie-apq8084
|
||||
- qcom,pcie-ipq4019
|
||||
- qcom,pcie-ipq5018
|
||||
- qcom,pcie-ipq6018
|
||||
- qcom,pcie-ipq8064
|
||||
- qcom,pcie-ipq8064-v2
|
||||
|
|
@ -168,6 +169,7 @@ allOf:
|
|||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,pcie-ipq5018
|
||||
- qcom,pcie-ipq6018
|
||||
- qcom,pcie-ipq8074-gen3
|
||||
- qcom,pcie-ipq9574
|
||||
|
|
@ -175,14 +177,16 @@ allOf:
|
|||
properties:
|
||||
reg:
|
||||
minItems: 5
|
||||
maxItems: 5
|
||||
maxItems: 6
|
||||
reg-names:
|
||||
minItems: 5
|
||||
items:
|
||||
- const: dbi # DesignWare PCIe registers
|
||||
- const: elbi # External local bus interface registers
|
||||
- const: atu # ATU address space
|
||||
- const: parf # Qualcomm specific registers
|
||||
- const: config # PCIe configuration space
|
||||
- const: mhi # MHI registers
|
||||
|
||||
- if:
|
||||
properties:
|
||||
|
|
@ -322,6 +326,53 @@ allOf:
|
|||
- const: ahb # AHB reset
|
||||
- const: phy_ahb # PHY AHB reset
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,pcie-ipq5018
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 6
|
||||
maxItems: 6
|
||||
clock-names:
|
||||
items:
|
||||
- const: iface # PCIe to SysNOC BIU clock
|
||||
- const: axi_m # AXI Master clock
|
||||
- const: axi_s # AXI Slave clock
|
||||
- const: ahb # AHB clock
|
||||
- const: aux # Auxiliary clock
|
||||
- const: axi_bridge # AXI bridge clock
|
||||
resets:
|
||||
minItems: 8
|
||||
maxItems: 8
|
||||
reset-names:
|
||||
items:
|
||||
- const: pipe # PIPE reset
|
||||
- const: sleep # Sleep reset
|
||||
- const: sticky # Core sticky reset
|
||||
- const: axi_m # AXI master reset
|
||||
- const: axi_s # AXI slave reset
|
||||
- const: ahb # AHB reset
|
||||
- const: axi_m_sticky # AXI master sticky reset
|
||||
- const: axi_s_sticky # AXI slave sticky reset
|
||||
interrupts:
|
||||
minItems: 9
|
||||
maxItems: 9
|
||||
interrupt-names:
|
||||
items:
|
||||
- const: msi0
|
||||
- const: msi1
|
||||
- const: msi2
|
||||
- const: msi3
|
||||
- const: msi4
|
||||
- const: msi5
|
||||
- const: msi6
|
||||
- const: msi7
|
||||
- const: global
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
|
|
@ -562,6 +613,7 @@ allOf:
|
|||
enum:
|
||||
- qcom,pcie-apq8064
|
||||
- qcom,pcie-ipq4019
|
||||
- qcom,pcie-ipq5018
|
||||
- qcom,pcie-ipq8064
|
||||
- qcom,pcie-ipq8064v2
|
||||
- qcom,pcie-ipq8074
|
||||
|
|
@ -589,7 +641,11 @@ allOf:
|
|||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,pcie-ipq6018
|
||||
- qcom,pcie-ipq8074
|
||||
- qcom,pcie-ipq8074-gen3
|
||||
- qcom,pcie-msm8996
|
||||
- qcom,pcie-msm8998
|
||||
- qcom,pcie-sdm845
|
||||
then:
|
||||
oneOf:
|
||||
|
|
@ -602,8 +658,9 @@ allOf:
|
|||
- properties:
|
||||
interrupts:
|
||||
minItems: 8
|
||||
maxItems: 8
|
||||
maxItems: 9
|
||||
interrupt-names:
|
||||
minItems: 8
|
||||
items:
|
||||
- const: msi0
|
||||
- const: msi1
|
||||
|
|
@ -613,6 +670,7 @@ allOf:
|
|||
- const: msi5
|
||||
- const: msi6
|
||||
- const: msi7
|
||||
- const: global
|
||||
|
||||
- if:
|
||||
properties:
|
||||
|
|
@ -622,11 +680,8 @@ allOf:
|
|||
- qcom,pcie-apq8064
|
||||
- qcom,pcie-apq8084
|
||||
- qcom,pcie-ipq4019
|
||||
- qcom,pcie-ipq6018
|
||||
- qcom,pcie-ipq8064
|
||||
- qcom,pcie-ipq8064-v2
|
||||
- qcom,pcie-ipq8074
|
||||
- qcom,pcie-ipq8074-gen3
|
||||
- qcom,pcie-qcs404
|
||||
then:
|
||||
properties:
|
||||
|
|
|
|||
|
|
@ -73,21 +73,21 @@ examples:
|
|||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/power/r8a774c0-sysc.h>
|
||||
|
||||
pcie0_ep: pcie-ep@fe000000 {
|
||||
compatible = "renesas,r8a774c0-pcie-ep",
|
||||
"renesas,rcar-gen3-pcie-ep";
|
||||
reg = <0xfe000000 0x80000>,
|
||||
<0xfe100000 0x100000>,
|
||||
<0xfe200000 0x200000>,
|
||||
<0x30000000 0x8000000>,
|
||||
<0x38000000 0x8000000>;
|
||||
reg-names = "apb-base", "memory0", "memory1", "memory2", "memory3";
|
||||
interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
|
||||
resets = <&cpg 319>;
|
||||
power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
|
||||
clocks = <&cpg CPG_MOD 319>;
|
||||
clock-names = "pcie";
|
||||
max-functions = /bits/ 8 <1>;
|
||||
pcie0_ep: pcie-ep@fe000000 {
|
||||
compatible = "renesas,r8a774c0-pcie-ep",
|
||||
"renesas,rcar-gen3-pcie-ep";
|
||||
reg = <0xfe000000 0x80000>,
|
||||
<0xfe100000 0x100000>,
|
||||
<0xfe200000 0x200000>,
|
||||
<0x30000000 0x8000000>,
|
||||
<0x38000000 0x8000000>;
|
||||
reg-names = "apb-base", "memory0", "memory1", "memory2", "memory3";
|
||||
interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
|
||||
resets = <&cpg 319>;
|
||||
power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
|
||||
clocks = <&cpg CPG_MOD 319>;
|
||||
clock-names = "pcie";
|
||||
max-functions = /bits/ 8 <1>;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -113,27 +113,27 @@ examples:
|
|||
pcie: pcie@fe000000 {
|
||||
compatible = "renesas,pcie-r8a7791", "renesas,pcie-rcar-gen2";
|
||||
reg = <0 0xfe000000 0 0x80000>;
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
bus-range = <0x00 0xff>;
|
||||
device_type = "pci";
|
||||
ranges = <0x01000000 0 0x00000000 0 0xfe100000 0 0x00100000>,
|
||||
<0x02000000 0 0xfe200000 0 0xfe200000 0 0x00200000>,
|
||||
<0x02000000 0 0x30000000 0 0x30000000 0 0x08000000>,
|
||||
<0x42000000 0 0x38000000 0 0x38000000 0 0x08000000>;
|
||||
dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x40000000>,
|
||||
<0x42000000 2 0x00000000 2 0x00000000 0 0x40000000>;
|
||||
interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-map-mask = <0 0 0 0>;
|
||||
interrupt-map = <0 0 0 0 &gic GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&cpg CPG_MOD 319>, <&pcie_bus_clk>;
|
||||
clock-names = "pcie", "pcie_bus";
|
||||
power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
|
||||
resets = <&cpg 319>;
|
||||
vpcie3v3-supply = <&pcie_3v3>;
|
||||
vpcie12v-supply = <&pcie_12v>;
|
||||
};
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
bus-range = <0x00 0xff>;
|
||||
device_type = "pci";
|
||||
ranges = <0x01000000 0 0x00000000 0 0xfe100000 0 0x00100000>,
|
||||
<0x02000000 0 0xfe200000 0 0xfe200000 0 0x00200000>,
|
||||
<0x02000000 0 0x30000000 0 0x30000000 0 0x08000000>,
|
||||
<0x42000000 0 0x38000000 0 0x38000000 0 0x08000000>;
|
||||
dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x40000000>,
|
||||
<0x42000000 2 0x00000000 2 0x00000000 0 0x40000000>;
|
||||
interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-map-mask = <0 0 0 0>;
|
||||
interrupt-map = <0 0 0 0 &gic GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&cpg CPG_MOD 319>, <&pcie_bus_clk>;
|
||||
clock-names = "pcie", "pcie_bus";
|
||||
power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
|
||||
resets = <&cpg 319>;
|
||||
vpcie3v3-supply = <&pcie_3v3>;
|
||||
vpcie12v-supply = <&pcie_12v>;
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -65,7 +65,11 @@ properties:
|
|||
tx_cpl_timeout, cor_err_sent, nf_err_sent, f_err_sent, cor_err_rx,
|
||||
nf_err_rx, f_err_rx, radm_qoverflow
|
||||
- description:
|
||||
eDMA write channel 0 interrupt
|
||||
If the matching interrupt name is "msi", then this is the combined
|
||||
MSI line interrupt, which is to support MSI interrupts output to GIC
|
||||
controller via GIC SPI interrupt instead of GIC ITS interrupt.
|
||||
If the matching interrupt name is "dma0", then this is the eDMA write
|
||||
channel 0 interrupt.
|
||||
- description:
|
||||
eDMA write channel 1 interrupt
|
||||
- description:
|
||||
|
|
@ -81,7 +85,9 @@ properties:
|
|||
- const: msg
|
||||
- const: legacy
|
||||
- const: err
|
||||
- const: dma0
|
||||
- enum:
|
||||
- msi
|
||||
- dma0
|
||||
- const: dma1
|
||||
- const: dma2
|
||||
- const: dma3
|
||||
|
|
|
|||
|
|
@ -16,16 +16,14 @@ description: |+
|
|||
PCIe IP and thus inherits all the common properties defined in
|
||||
snps,dw-pcie.yaml.
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/pci/snps,dw-pcie.yaml#
|
||||
- $ref: /schemas/pci/rockchip-dw-pcie-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- const: rockchip,rk3568-pcie
|
||||
- items:
|
||||
- enum:
|
||||
- rockchip,rk3562-pcie
|
||||
- rockchip,rk3576-pcie
|
||||
- rockchip,rk3588-pcie
|
||||
- const: rockchip,rk3568-pcie
|
||||
|
||||
|
|
@ -71,8 +69,58 @@ properties:
|
|||
|
||||
vpcie3v3-supply: true
|
||||
|
||||
required:
|
||||
- msi-map
|
||||
allOf:
|
||||
- $ref: /schemas/pci/snps,dw-pcie.yaml#
|
||||
- $ref: /schemas/pci/rockchip-dw-pcie-common.yaml#
|
||||
- if:
|
||||
not:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- rockchip,rk3562-pcie
|
||||
- rockchip,rk3576-pcie
|
||||
then:
|
||||
required:
|
||||
- msi-map
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- rockchip,rk3562-pcie
|
||||
- rockchip,rk3576-pcie
|
||||
then:
|
||||
properties:
|
||||
interrupts:
|
||||
minItems: 6
|
||||
maxItems: 6
|
||||
interrupt-names:
|
||||
items:
|
||||
- const: sys
|
||||
- const: pmc
|
||||
- const: msg
|
||||
- const: legacy
|
||||
- const: err
|
||||
- const: msi
|
||||
else:
|
||||
properties:
|
||||
interrupts:
|
||||
minItems: 5
|
||||
interrupt-names:
|
||||
minItems: 5
|
||||
items:
|
||||
- const: sys
|
||||
- const: pmc
|
||||
- const: msg
|
||||
- const: legacy
|
||||
- const: err
|
||||
- const: dma0
|
||||
- const: dma1
|
||||
- const: dma2
|
||||
- const: dma3
|
||||
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
|
|
|
|||
|
|
@ -81,10 +81,10 @@ unevaluatedProperties: false
|
|||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/sifive-fu740-prci.h>
|
||||
bus {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
#include <dt-bindings/clock/sifive-fu740-prci.h>
|
||||
|
||||
pcie@e00000000 {
|
||||
compatible = "sifive,fu740-pcie";
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ properties:
|
|||
above for new bindings.
|
||||
oneOf:
|
||||
- description: See native 'dbi' clock for details
|
||||
enum: [ pcie, pcie_apb_sys, aclk_dbi ]
|
||||
enum: [ pcie, pcie_apb_sys, aclk_dbi, reg ]
|
||||
- description: See native 'mstr/slv' clock for details
|
||||
enum: [ pcie_bus, pcie_inbound_axi, pcie_aclk, aclk_mst, aclk_slv ]
|
||||
- description: See native 'pipe' clock for details
|
||||
|
|
@ -201,6 +201,7 @@ properties:
|
|||
oneOf:
|
||||
- pattern: '^pcie(-?phy[0-9]*)?$'
|
||||
- pattern: '^p2u-[0-7]$'
|
||||
- pattern: '^cp[01]-pcie[0-2]-x[124](-lane[0-3])?-phy$' # marvell,armada8k-pcie
|
||||
|
||||
reset-gpio:
|
||||
deprecated: true
|
||||
|
|
|
|||
|
|
@ -105,6 +105,8 @@ properties:
|
|||
Vendor-specific CSR names. Consider using the generic names above
|
||||
for new bindings.
|
||||
oneOf:
|
||||
- description: See native 'dbi' CSR region for details.
|
||||
enum: [ ctrl ]
|
||||
- description: See native 'elbi/app' CSR region for details.
|
||||
enum: [ apb, mgmt, link, ulreg, appl ]
|
||||
- description: See native 'atu' CSR region for details.
|
||||
|
|
@ -117,7 +119,7 @@ properties:
|
|||
const: slcr
|
||||
allOf:
|
||||
- contains:
|
||||
const: dbi
|
||||
enum: [ dbi, ctrl ]
|
||||
- contains:
|
||||
const: config
|
||||
|
||||
|
|
|
|||
100
Documentation/devicetree/bindings/pci/v3,v360epc-pci.yaml
Normal file
100
Documentation/devicetree/bindings/pci/v3,v360epc-pci.yaml
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/pci/v3,v360epc-pci.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: V3 Semiconductor V360 EPC PCI bridge
|
||||
|
||||
maintainers:
|
||||
- Linus Walleij <linus.walleij@linaro.org>
|
||||
|
||||
description:
|
||||
This bridge is found in the ARM Integrator/AP (Application Platform)
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/pci/pci-host-bridge.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: arm,integrator-ap-pci
|
||||
- const: v3,v360epc-pci
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: V3 host bridge controller
|
||||
- description: Configuration space
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
dma-ranges:
|
||||
maxItems: 2
|
||||
description:
|
||||
The inbound ranges must be aligned to a 1MB boundary, and may be 1MB, 2MB,
|
||||
4MB, 8MB, 16MB, 32MB, 64MB, 128MB, 256MB, 512MB, 1GB or 2GB in size. The
|
||||
memory should be marked as pre-fetchable.
|
||||
|
||||
interrupts:
|
||||
description: Bus Error IRQ
|
||||
maxItems: 1
|
||||
|
||||
ranges:
|
||||
description:
|
||||
The non-prefetchable and prefetchable memory windows must each be exactly
|
||||
256MB (0x10000000) in size. The prefetchable memory window must be
|
||||
immediately adjacent to the non-prefetchable memory window.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- dma-ranges
|
||||
- "#interrupt-cells"
|
||||
- interrupt-map
|
||||
- interrupt-map-mask
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
pci@62000000 {
|
||||
compatible = "arm,integrator-ap-pci", "v3,v360epc-pci";
|
||||
#interrupt-cells = <1>;
|
||||
#size-cells = <2>;
|
||||
#address-cells = <3>;
|
||||
reg = <0x62000000 0x10000>, <0x61000000 0x01000000>;
|
||||
device_type = "pci";
|
||||
interrupt-parent = <&pic>;
|
||||
interrupts = <17>; /* Bus error IRQ */
|
||||
clocks = <&pciclk>;
|
||||
ranges = <0x01000000 0 0x00000000 0x60000000 0 0x01000000>, /* 16 MiB @ LB 60000000 */
|
||||
<0x02000000 0 0x40000000 0x40000000 0 0x10000000>, /* 256 MiB @ LB 40000000 1:1 */
|
||||
<0x42000000 0 0x50000000 0x50000000 0 0x10000000>; /* 256 MiB @ LB 50000000 1:1 */
|
||||
dma-ranges = <0x02000000 0 0x20000000 0x20000000 0 0x20000000>, /* EBI: 512 MB @ LB 20000000 1:1 */
|
||||
<0x02000000 0 0x80000000 0x80000000 0 0x40000000>; /* CM alias: 1GB @ LB 80000000 */
|
||||
interrupt-map-mask = <0xf800 0 0 0x7>;
|
||||
interrupt-map =
|
||||
/* IDSEL 9 */
|
||||
<0x4800 0 0 1 &pic 13>, /* INT A on slot 9 is irq 13 */
|
||||
<0x4800 0 0 2 &pic 14>, /* INT B on slot 9 is irq 14 */
|
||||
<0x4800 0 0 3 &pic 15>, /* INT C on slot 9 is irq 15 */
|
||||
<0x4800 0 0 4 &pic 16>, /* INT D on slot 9 is irq 16 */
|
||||
/* IDSEL 10 */
|
||||
<0x5000 0 0 1 &pic 14>, /* INT A on slot 10 is irq 14 */
|
||||
<0x5000 0 0 2 &pic 15>, /* INT B on slot 10 is irq 15 */
|
||||
<0x5000 0 0 3 &pic 16>, /* INT C on slot 10 is irq 16 */
|
||||
<0x5000 0 0 4 &pic 13>, /* INT D on slot 10 is irq 13 */
|
||||
/* IDSEL 11 */
|
||||
<0x5800 0 0 1 &pic 15>, /* INT A on slot 11 is irq 15 */
|
||||
<0x5800 0 0 2 &pic 16>, /* INT B on slot 11 is irq 16 */
|
||||
<0x5800 0 0 3 &pic 13>, /* INT C on slot 11 is irq 13 */
|
||||
<0x5800 0 0 4 &pic 14>, /* INT D on slot 11 is irq 14 */
|
||||
/* IDSEL 12 */
|
||||
<0x6000 0 0 1 &pic 16>, /* INT A on slot 12 is irq 16 */
|
||||
<0x6000 0 0 2 &pic 13>, /* INT B on slot 12 is irq 13 */
|
||||
<0x6000 0 0 3 &pic 14>, /* INT C on slot 12 is irq 14 */
|
||||
<0x6000 0 0 4 &pic 15>; /* INT D on slot 12 is irq 15 */
|
||||
};
|
||||
...
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
V3 Semiconductor V360 EPC PCI bridge
|
||||
|
||||
This bridge is found in the ARM Integrator/AP (Application Platform)
|
||||
|
||||
Required properties:
|
||||
- compatible: should be one of:
|
||||
"v3,v360epc-pci"
|
||||
"arm,integrator-ap-pci", "v3,v360epc-pci"
|
||||
- reg: should contain two register areas:
|
||||
first the base address of the V3 host bridge controller, 64KB
|
||||
second the configuration area register space, 16MB
|
||||
- interrupts: should contain a reference to the V3 error interrupt
|
||||
as routed on the system.
|
||||
- bus-range: see pci.txt
|
||||
- ranges: this follows the standard PCI bindings in the IEEE Std
|
||||
1275-1994 (see pci.txt) with the following restriction:
|
||||
- The non-prefetchable and prefetchable memory windows must
|
||||
each be exactly 256MB (0x10000000) in size.
|
||||
- The prefetchable memory window must be immediately adjacent
|
||||
to the non-prefetcable memory window
|
||||
- dma-ranges: three ranges for the inbound memory region. The ranges must
|
||||
be aligned to a 1MB boundary, and may be 1MB, 2MB, 4MB, 8MB, 16MB, 32MB,
|
||||
64MB, 128MB, 256MB, 512MB, 1GB or 2GB in size. The memory should be marked
|
||||
as pre-fetchable. Two ranges are supported by the hardware.
|
||||
|
||||
Integrator-specific required properties:
|
||||
- syscon: should contain a link to the syscon device node, since
|
||||
on the Integrator, some registers in the syscon are required to
|
||||
operate the V3 host bridge.
|
||||
|
||||
Example:
|
||||
|
||||
pci: pciv3@62000000 {
|
||||
compatible = "arm,integrator-ap-pci", "v3,v360epc-pci";
|
||||
#interrupt-cells = <1>;
|
||||
#size-cells = <2>;
|
||||
#address-cells = <3>;
|
||||
reg = <0x62000000 0x10000>, <0x61000000 0x01000000>;
|
||||
interrupt-parent = <&pic>;
|
||||
interrupts = <17>; /* Bus error IRQ */
|
||||
clocks = <&pciclk>;
|
||||
bus-range = <0x00 0xff>;
|
||||
ranges = 0x01000000 0 0x00000000 /* I/O space @00000000 */
|
||||
0x60000000 0 0x01000000 /* 16 MiB @ LB 60000000 */
|
||||
0x02000000 0 0x40000000 /* non-prefectable memory @40000000 */
|
||||
0x40000000 0 0x10000000 /* 256 MiB @ LB 40000000 1:1 */
|
||||
0x42000000 0 0x50000000 /* prefetchable memory @50000000 */
|
||||
0x50000000 0 0x10000000>; /* 256 MiB @ LB 50000000 1:1 */
|
||||
dma-ranges = <0x02000000 0 0x20000000 /* EBI memory space */
|
||||
0x20000000 0 0x20000000 /* 512 MB @ LB 20000000 1:1 */
|
||||
0x02000000 0 0x80000000 /* Core module alias memory */
|
||||
0x80000000 0 0x40000000>; /* 1GB @ LB 80000000 */
|
||||
interrupt-map-mask = <0xf800 0 0 0x7>;
|
||||
interrupt-map = <
|
||||
/* IDSEL 9 */
|
||||
0x4800 0 0 1 &pic 13 /* INT A on slot 9 is irq 13 */
|
||||
0x4800 0 0 2 &pic 14 /* INT B on slot 9 is irq 14 */
|
||||
0x4800 0 0 3 &pic 15 /* INT C on slot 9 is irq 15 */
|
||||
0x4800 0 0 4 &pic 16 /* INT D on slot 9 is irq 16 */
|
||||
/* IDSEL 10 */
|
||||
0x5000 0 0 1 &pic 14 /* INT A on slot 10 is irq 14 */
|
||||
0x5000 0 0 2 &pic 15 /* INT B on slot 10 is irq 15 */
|
||||
0x5000 0 0 3 &pic 16 /* INT C on slot 10 is irq 16 */
|
||||
0x5000 0 0 4 &pic 13 /* INT D on slot 10 is irq 13 */
|
||||
/* IDSEL 11 */
|
||||
0x5800 0 0 1 &pic 15 /* INT A on slot 11 is irq 15 */
|
||||
0x5800 0 0 2 &pic 16 /* INT B on slot 11 is irq 16 */
|
||||
0x5800 0 0 3 &pic 13 /* INT C on slot 11 is irq 13 */
|
||||
0x5800 0 0 4 &pic 14 /* INT D on slot 11 is irq 14 */
|
||||
/* IDSEL 12 */
|
||||
0x6000 0 0 1 &pic 16 /* INT A on slot 12 is irq 16 */
|
||||
0x6000 0 0 2 &pic 13 /* INT B on slot 12 is irq 13 */
|
||||
0x6000 0 0 3 &pic 14 /* INT C on slot 12 is irq 14 */
|
||||
0x6000 0 0 4 &pic 15 /* INT D on slot 12 is irq 15 */
|
||||
>;
|
||||
};
|
||||
|
|
@ -76,64 +76,62 @@ unevaluatedProperties: false
|
|||
|
||||
examples:
|
||||
- |
|
||||
|
||||
versal {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
cpm_pcie: pcie@fca10000 {
|
||||
compatible = "xlnx,versal-cpm-host-1.00";
|
||||
device_type = "pci";
|
||||
#address-cells = <3>;
|
||||
#interrupt-cells = <1>;
|
||||
#size-cells = <2>;
|
||||
interrupts = <0 72 4>;
|
||||
interrupt-parent = <&gic>;
|
||||
interrupt-map-mask = <0 0 0 7>;
|
||||
interrupt-map = <0 0 0 1 &pcie_intc_0 0>,
|
||||
<0 0 0 2 &pcie_intc_0 1>,
|
||||
<0 0 0 3 &pcie_intc_0 2>,
|
||||
<0 0 0 4 &pcie_intc_0 3>;
|
||||
bus-range = <0x00 0xff>;
|
||||
ranges = <0x02000000 0x0 0xe0010000 0x0 0xe0010000 0x0 0x10000000>,
|
||||
<0x43000000 0x80 0x00000000 0x80 0x00000000 0x0 0x80000000>;
|
||||
msi-map = <0x0 &its_gic 0x0 0x10000>;
|
||||
reg = <0x0 0xfca10000 0x0 0x1000>,
|
||||
<0x6 0x00000000 0x0 0x10000000>;
|
||||
reg-names = "cpm_slcr", "cfg";
|
||||
pcie_intc_0: interrupt-controller {
|
||||
#address-cells = <0>;
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-controller;
|
||||
};
|
||||
};
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
pcie@fca10000 {
|
||||
compatible = "xlnx,versal-cpm-host-1.00";
|
||||
device_type = "pci";
|
||||
#address-cells = <3>;
|
||||
#interrupt-cells = <1>;
|
||||
#size-cells = <2>;
|
||||
interrupts = <0 72 4>;
|
||||
interrupt-parent = <&gic>;
|
||||
interrupt-map-mask = <0 0 0 7>;
|
||||
interrupt-map = <0 0 0 1 &pcie_intc_0 0>,
|
||||
<0 0 0 2 &pcie_intc_0 1>,
|
||||
<0 0 0 3 &pcie_intc_0 2>,
|
||||
<0 0 0 4 &pcie_intc_0 3>;
|
||||
bus-range = <0x00 0xff>;
|
||||
ranges = <0x02000000 0x0 0xe0010000 0x0 0xe0010000 0x0 0x10000000>,
|
||||
<0x43000000 0x80 0x00000000 0x80 0x00000000 0x0 0x80000000>;
|
||||
msi-map = <0x0 &its_gic 0x0 0x10000>;
|
||||
reg = <0x0 0xfca10000 0x0 0x1000>,
|
||||
<0x6 0x00000000 0x0 0x10000000>;
|
||||
reg-names = "cpm_slcr", "cfg";
|
||||
pcie_intc_0: interrupt-controller {
|
||||
#address-cells = <0>;
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-controller;
|
||||
};
|
||||
};
|
||||
|
||||
cpm5_pcie: pcie@fcdd0000 {
|
||||
compatible = "xlnx,versal-cpm5-host";
|
||||
device_type = "pci";
|
||||
#address-cells = <3>;
|
||||
#interrupt-cells = <1>;
|
||||
#size-cells = <2>;
|
||||
interrupts = <0 72 4>;
|
||||
interrupt-parent = <&gic>;
|
||||
interrupt-map-mask = <0 0 0 7>;
|
||||
interrupt-map = <0 0 0 1 &pcie_intc_1 0>,
|
||||
<0 0 0 2 &pcie_intc_1 1>,
|
||||
<0 0 0 3 &pcie_intc_1 2>,
|
||||
<0 0 0 4 &pcie_intc_1 3>;
|
||||
bus-range = <0x00 0xff>;
|
||||
ranges = <0x02000000 0x0 0xe0000000 0x0 0xe0000000 0x0 0x10000000>,
|
||||
<0x43000000 0x80 0x00000000 0x80 0x00000000 0x0 0x80000000>;
|
||||
msi-map = <0x0 &its_gic 0x0 0x10000>;
|
||||
reg = <0x00 0xfcdd0000 0x00 0x1000>,
|
||||
<0x06 0x00000000 0x00 0x1000000>,
|
||||
<0x00 0xfce20000 0x00 0x1000000>;
|
||||
reg-names = "cpm_slcr", "cfg", "cpm_csr";
|
||||
|
||||
pcie_intc_1: interrupt-controller {
|
||||
#address-cells = <0>;
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-controller;
|
||||
};
|
||||
};
|
||||
pcie@fcdd0000 {
|
||||
compatible = "xlnx,versal-cpm5-host";
|
||||
device_type = "pci";
|
||||
#address-cells = <3>;
|
||||
#interrupt-cells = <1>;
|
||||
#size-cells = <2>;
|
||||
interrupts = <0 72 4>;
|
||||
interrupt-parent = <&gic>;
|
||||
interrupt-map-mask = <0 0 0 7>;
|
||||
interrupt-map = <0 0 0 1 &pcie_intc_1 0>,
|
||||
<0 0 0 2 &pcie_intc_1 1>,
|
||||
<0 0 0 3 &pcie_intc_1 2>,
|
||||
<0 0 0 4 &pcie_intc_1 3>;
|
||||
bus-range = <0x00 0xff>;
|
||||
ranges = <0x02000000 0x0 0xe0000000 0x0 0xe0000000 0x0 0x10000000>,
|
||||
<0x43000000 0x80 0x00000000 0x80 0x00000000 0x0 0x80000000>;
|
||||
msi-map = <0x0 &its_gic 0x0 0x10000>;
|
||||
reg = <0x00 0xfcdd0000 0x00 0x1000>,
|
||||
<0x06 0x00000000 0x00 0x1000000>,
|
||||
<0x00 0xfce20000 0x00 0x1000000>;
|
||||
reg-names = "cpm_slcr", "cfg", "cpm_csr";
|
||||
|
||||
pcie_intc_1: interrupt-controller {
|
||||
#address-cells = <0>;
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-controller;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -391,12 +391,11 @@ PCI
|
|||
devm_pci_remap_cfgspace() : ioremap PCI configuration space
|
||||
devm_pci_remap_cfg_resource() : ioremap PCI configuration space resource
|
||||
|
||||
pcim_enable_device() : after success, some PCI ops become managed
|
||||
pcim_enable_device() : after success, the PCI device gets disabled automatically on driver detach
|
||||
pcim_iomap() : do iomap() on a single BAR
|
||||
pcim_iomap_regions() : do request_region() and iomap() on multiple BARs
|
||||
pcim_iomap_table() : array of mapped addresses indexed by BAR
|
||||
pcim_iounmap() : do iounmap() on a single BAR
|
||||
pcim_iounmap_regions() : do iounmap() and release_region() on multiple BARs
|
||||
pcim_pin_device() : keep PCI device enabled after release
|
||||
pcim_set_mwi() : enable Memory-Write-Invalidate PCI transaction
|
||||
|
||||
|
|
|
|||
50
MAINTAINERS
50
MAINTAINERS
|
|
@ -2147,7 +2147,7 @@ F: arch/arm/plat-*/
|
|||
|
||||
ARM/ACTIONS SEMI ARCHITECTURE
|
||||
M: Andreas Färber <afaerber@suse.de>
|
||||
M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
M: Manivannan Sadhasivam <mani@kernel.org>
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
L: linux-actions@lists.infradead.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
|
|
@ -2400,7 +2400,7 @@ F: arch/arm/boot/dts/intel/axm/
|
|||
F: arch/arm/mach-axxia/
|
||||
|
||||
ARM/BITMAIN ARCHITECTURE
|
||||
M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
M: Manivannan Sadhasivam <mani@kernel.org>
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/arm/bitmain.yaml
|
||||
|
|
@ -3069,7 +3069,7 @@ F: include/linux/soc/qcom/
|
|||
F: include/soc/qcom/
|
||||
|
||||
ARM/RDA MICRO ARCHITECTURE
|
||||
M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
M: Manivannan Sadhasivam <mani@kernel.org>
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
L: linux-unisoc@lists.infradead.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
|
|
@ -3776,7 +3776,7 @@ F: Documentation/admin-guide/aoe/
|
|||
F: drivers/block/aoe/
|
||||
|
||||
ATC260X PMIC MFD DRIVER
|
||||
M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
M: Manivannan Sadhasivam <mani@kernel.org>
|
||||
M: Cristian Ciocaltea <cristian.ciocaltea@gmail.com>
|
||||
L: linux-actions@lists.infradead.org
|
||||
S: Maintained
|
||||
|
|
@ -6806,7 +6806,7 @@ S: Orphan
|
|||
F: drivers/mtd/nand/raw/denali*
|
||||
|
||||
DESIGNWARE EDMA CORE IP DRIVER
|
||||
M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
M: Manivannan Sadhasivam <mani@kernel.org>
|
||||
L: dmaengine@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/dma/dw-edma/
|
||||
|
|
@ -8652,7 +8652,7 @@ S: Maintained
|
|||
F: drivers/edac/pnd2_edac.[ch]
|
||||
|
||||
EDAC-QCOM
|
||||
M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
M: Manivannan Sadhasivam <mani@kernel.org>
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
L: linux-edac@vger.kernel.org
|
||||
S: Maintained
|
||||
|
|
@ -12270,7 +12270,7 @@ M: Andy Shevchenko <andy@kernel.org>
|
|||
L: linux-kernel@vger.kernel.org
|
||||
S: Supported
|
||||
F: arch/x86/include/asm/intel-mid.h
|
||||
F: arch/x86/pci/intel_mid_pci.c
|
||||
F: arch/x86/pci/intel_mid.c
|
||||
F: arch/x86/platform/intel-mid/
|
||||
F: drivers/dma/hsu/
|
||||
F: drivers/extcon/extcon-intel-mrfld.c
|
||||
|
|
@ -14859,7 +14859,7 @@ F: drivers/hid/hid-mcp2221.c
|
|||
|
||||
MCP251XFD SPI-CAN NETWORK DRIVER
|
||||
M: Marc Kleine-Budde <mkl@pengutronix.de>
|
||||
M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
M: Manivannan Sadhasivam <mani@kernel.org>
|
||||
R: Thomas Kopp <thomas.kopp@microchip.com>
|
||||
L: linux-can@vger.kernel.org
|
||||
S: Maintained
|
||||
|
|
@ -16025,7 +16025,7 @@ F: arch/arm64/boot/dts/marvell/armada-3720-eDPU.dts
|
|||
F: arch/arm64/boot/dts/marvell/armada-3720-uDPU.*
|
||||
|
||||
MHI BUS
|
||||
M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
M: Manivannan Sadhasivam <mani@kernel.org>
|
||||
L: mhi@lists.linux.dev
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
S: Maintained
|
||||
|
|
@ -18837,7 +18837,7 @@ M: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
|
|||
L: linux-pci@vger.kernel.org
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/pci/pci-armada8k.txt
|
||||
F: Documentation/devicetree/bindings/pci/marvell,armada8k-pcie.yaml
|
||||
F: drivers/pci/controller/dwc/pcie-armada8k.c
|
||||
|
||||
PCI DRIVER FOR CADENCE PCIE IP
|
||||
|
|
@ -18957,6 +18957,7 @@ M: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
|
|||
L: linux-pci@vger.kernel.org
|
||||
L: linux-renesas-soc@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/PCI/controller/rcar-pcie-firmware.rst
|
||||
F: Documentation/devicetree/bindings/pci/*rcar*
|
||||
F: drivers/pci/controller/*rcar*
|
||||
F: drivers/pci/controller/dwc/*rcar*
|
||||
|
|
@ -18971,7 +18972,7 @@ F: drivers/pci/controller/dwc/pci-exynos.c
|
|||
|
||||
PCI DRIVER FOR SYNOPSYS DESIGNWARE
|
||||
M: Jingoo Han <jingoohan1@gmail.com>
|
||||
M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
M: Manivannan Sadhasivam <mani@kernel.org>
|
||||
L: linux-pci@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/pci/snps,dw-pcie-ep.yaml
|
||||
|
|
@ -18994,7 +18995,7 @@ PCI DRIVER FOR V3 SEMICONDUCTOR V360EPC
|
|||
M: Linus Walleij <linus.walleij@linaro.org>
|
||||
L: linux-pci@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/pci/v3-v360epc-pci.txt
|
||||
F: Documentation/devicetree/bindings/pci/v3,v360epc-pci.yaml
|
||||
F: drivers/pci/controller/pci-v3-semi.c
|
||||
|
||||
PCI DRIVER FOR XILINX VERSAL CPM
|
||||
|
|
@ -19006,8 +19007,8 @@ F: Documentation/devicetree/bindings/pci/xilinx-versal-cpm.yaml
|
|||
F: drivers/pci/controller/pcie-xilinx-cpm.c
|
||||
|
||||
PCI ENDPOINT SUBSYSTEM
|
||||
M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
M: Krzysztof Wilczyński <kw@linux.com>
|
||||
M: Manivannan Sadhasivam <mani@kernel.org>
|
||||
M: Krzysztof Wilczyński <kwilczynski@kernel.org>
|
||||
R: Kishon Vijay Abraham I <kishon@kernel.org>
|
||||
L: linux-pci@vger.kernel.org
|
||||
S: Supported
|
||||
|
|
@ -19058,8 +19059,8 @@ F: drivers/pci/controller/pci-xgene-msi.c
|
|||
|
||||
PCI NATIVE HOST BRIDGE AND ENDPOINT DRIVERS
|
||||
M: Lorenzo Pieralisi <lpieralisi@kernel.org>
|
||||
M: Krzysztof Wilczyński <kw@linux.com>
|
||||
M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
M: Krzysztof Wilczyński <kwilczynski@kernel.org>
|
||||
M: Manivannan Sadhasivam <mani@kernel.org>
|
||||
R: Rob Herring <robh@kernel.org>
|
||||
L: linux-pci@vger.kernel.org
|
||||
S: Supported
|
||||
|
|
@ -19067,6 +19068,7 @@ Q: https://patchwork.kernel.org/project/linux-pci/list/
|
|||
B: https://bugzilla.kernel.org
|
||||
C: irc://irc.oftc.net/linux-pci
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git
|
||||
F: Documentation/ABI/testing/debugfs-pcie-ptm
|
||||
F: Documentation/devicetree/bindings/pci/
|
||||
F: drivers/pci/controller/
|
||||
F: drivers/pci/pci-bridge-emul.c
|
||||
|
|
@ -19215,7 +19217,7 @@ F: Documentation/devicetree/bindings/pci/microchip*
|
|||
F: drivers/pci/controller/plda/*microchip*
|
||||
|
||||
PCIE DRIVER FOR QUALCOMM MSM
|
||||
M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
M: Manivannan Sadhasivam <mani@kernel.org>
|
||||
L: linux-pci@vger.kernel.org
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
S: Maintained
|
||||
|
|
@ -19251,7 +19253,7 @@ F: Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml
|
|||
F: drivers/pci/controller/plda/pcie-starfive.c
|
||||
|
||||
PCIE ENDPOINT DRIVER FOR QUALCOMM
|
||||
M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
M: Manivannan Sadhasivam <mani@kernel.org>
|
||||
L: linux-pci@vger.kernel.org
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
S: Maintained
|
||||
|
|
@ -20379,7 +20381,7 @@ F: drivers/iommu/arm/arm-smmu/arm-smmu-qcom*
|
|||
F: drivers/iommu/msm_iommu*
|
||||
|
||||
QUALCOMM IPC ROUTER (QRTR) DRIVER
|
||||
M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
M: Manivannan Sadhasivam <mani@kernel.org>
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
S: Maintained
|
||||
F: include/trace/events/qrtr.h
|
||||
|
|
@ -20387,7 +20389,7 @@ F: include/uapi/linux/qrtr.h
|
|||
F: net/qrtr/
|
||||
|
||||
QUALCOMM IPCC MAILBOX DRIVER
|
||||
M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
M: Manivannan Sadhasivam <mani@kernel.org>
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
S: Supported
|
||||
F: Documentation/devicetree/bindings/mailbox/qcom-ipcc.yaml
|
||||
|
|
@ -20422,7 +20424,7 @@ F: Documentation/devicetree/bindings/media/qcom,*-iris.yaml
|
|||
F: drivers/media/platform/qcom/iris/
|
||||
|
||||
QUALCOMM NAND CONTROLLER DRIVER
|
||||
M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
M: Manivannan Sadhasivam <mani@kernel.org>
|
||||
L: linux-mtd@lists.infradead.org
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
S: Maintained
|
||||
|
|
@ -22990,7 +22992,7 @@ F: Documentation/devicetree/bindings/media/i2c/sony,imx283.yaml
|
|||
F: drivers/media/i2c/imx283.c
|
||||
|
||||
SONY IMX290 SENSOR DRIVER
|
||||
M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
M: Manivannan Sadhasivam <mani@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://linuxtv.org/media.git
|
||||
|
|
@ -22999,7 +23001,7 @@ F: drivers/media/i2c/imx290.c
|
|||
|
||||
SONY IMX296 SENSOR DRIVER
|
||||
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
|
||||
M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
M: Manivannan Sadhasivam <mani@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://linuxtv.org/media.git
|
||||
|
|
@ -25374,7 +25376,7 @@ S: Maintained
|
|||
F: drivers/ufs/host/ufs-mediatek*
|
||||
|
||||
UNIVERSAL FLASH STORAGE HOST CONTROLLER DRIVER QUALCOMM HOOKS
|
||||
M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
M: Manivannan Sadhasivam <mani@kernel.org>
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
L: linux-scsi@vger.kernel.org
|
||||
S: Maintained
|
||||
|
|
|
|||
|
|
@ -269,7 +269,7 @@ config ARCH_QCOM
|
|||
bool "Qualcomm Platforms"
|
||||
select GPIOLIB
|
||||
select PINCTRL
|
||||
select HAVE_PWRCTL if PCI
|
||||
select HAVE_PWRCTRL if PCI
|
||||
help
|
||||
This enables support for the ARMv8 based Qualcomm chipsets.
|
||||
|
||||
|
|
|
|||
|
|
@ -8,13 +8,13 @@ obj-$(CONFIG_PCI_OLPC) += olpc.o
|
|||
obj-$(CONFIG_PCI_XEN) += xen.o
|
||||
|
||||
obj-y += fixup.o
|
||||
obj-$(CONFIG_X86_INTEL_CE) += ce4100.o
|
||||
obj-$(CONFIG_ACPI) += acpi.o
|
||||
obj-y += legacy.o irq.o
|
||||
|
||||
obj-$(CONFIG_X86_NUMACHIP) += numachip.o
|
||||
obj-$(CONFIG_X86_INTEL_CE) += ce4100.o
|
||||
obj-$(CONFIG_X86_INTEL_MID) += intel_mid.o
|
||||
|
||||
obj-$(CONFIG_X86_INTEL_MID) += intel_mid_pci.o
|
||||
obj-$(CONFIG_X86_NUMACHIP) += numachip.o
|
||||
|
||||
obj-y += common.o early.o
|
||||
obj-y += bus_numa.o
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ config DRM_ACCEL_QAIC
|
|||
depends on DRM_ACCEL
|
||||
depends on PCI && HAS_IOMEM
|
||||
depends on MHI_BUS
|
||||
depends on MMU
|
||||
select CRC32
|
||||
help
|
||||
Enables driver for Qualcomm's Cloud AI accelerator PCIe cards that are
|
||||
|
|
|
|||
|
|
@ -3717,7 +3717,7 @@ static int mtip_pci_probe(struct pci_dev *pdev,
|
|||
rv = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
|
||||
if (rv) {
|
||||
dev_warn(&pdev->dev, "64-bit DMA enable failed\n");
|
||||
goto setmask_err;
|
||||
goto iomap_err;
|
||||
}
|
||||
|
||||
/* Copy the info we may need later into the private data structure. */
|
||||
|
|
@ -3733,7 +3733,7 @@ static int mtip_pci_probe(struct pci_dev *pdev,
|
|||
if (!dd->isr_workq) {
|
||||
dev_warn(&pdev->dev, "Can't create wq %d\n", dd->instance);
|
||||
rv = -ENOMEM;
|
||||
goto setmask_err;
|
||||
goto iomap_err;
|
||||
}
|
||||
|
||||
memset(cpu_list, 0, sizeof(cpu_list));
|
||||
|
|
@ -3830,8 +3830,6 @@ static int mtip_pci_probe(struct pci_dev *pdev,
|
|||
drop_cpu(dd->work[1].cpu_binding);
|
||||
drop_cpu(dd->work[2].cpu_binding);
|
||||
}
|
||||
setmask_err:
|
||||
pcim_iounmap_regions(pdev, 1 << MTIP_ABAR);
|
||||
|
||||
iomap_err:
|
||||
kfree(dd);
|
||||
|
|
@ -3907,7 +3905,6 @@ static void mtip_pci_remove(struct pci_dev *pdev)
|
|||
|
||||
pci_disable_msi(pdev);
|
||||
|
||||
pcim_iounmap_regions(pdev, 1 << MTIP_ABAR);
|
||||
pci_set_drvdata(pdev, NULL);
|
||||
|
||||
put_disk(dd->disk);
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ config FIREWIRE_KUNIT_SELF_ID_SEQUENCE_HELPER_TEST
|
|||
|
||||
config FIREWIRE_OHCI
|
||||
tristate "OHCI-1394 controllers"
|
||||
depends on PCI && FIREWIRE && MMU
|
||||
depends on PCI && FIREWIRE
|
||||
help
|
||||
Enable this driver if you have a FireWire controller based
|
||||
on the OHCI specification. For all practical purposes, this
|
||||
|
|
|
|||
|
|
@ -398,7 +398,7 @@ source "drivers/gpu/drm/imagination/Kconfig"
|
|||
|
||||
config DRM_HYPERV
|
||||
tristate "DRM Support for Hyper-V synthetic video device"
|
||||
depends on DRM && PCI && MMU && HYPERV
|
||||
depends on DRM && PCI && HYPERV
|
||||
select DRM_CLIENT_SELECTION
|
||||
select DRM_KMS_HELPER
|
||||
select DRM_GEM_SHMEM_HELPER
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
config DRM_AMDGPU
|
||||
tristate "AMD GPU"
|
||||
depends on DRM && PCI && MMU
|
||||
depends on DRM && PCI
|
||||
depends on !UML
|
||||
select FW_LOADER
|
||||
select DRM_CLIENT
|
||||
|
|
@ -68,7 +68,6 @@ config DRM_AMDGPU_CIK
|
|||
config DRM_AMDGPU_USERPTR
|
||||
bool "Always enable userptr write support"
|
||||
depends on DRM_AMDGPU
|
||||
depends on MMU
|
||||
select HMM_MIRROR
|
||||
select MMU_NOTIFIER
|
||||
help
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
config DRM_AST
|
||||
tristate "AST server chips"
|
||||
depends on DRM && PCI && MMU
|
||||
depends on DRM && PCI
|
||||
select DRM_CLIENT_SELECTION
|
||||
select DRM_GEM_SHMEM_HELPER
|
||||
select DRM_KMS_HELPER
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
config DRM_GMA500
|
||||
tristate "Intel GMA500/600/3600/3650 KMS Framebuffer"
|
||||
depends on DRM && PCI && X86 && MMU && HAS_IOPORT
|
||||
depends on DRM && PCI && X86 && HAS_IOPORT
|
||||
select DRM_CLIENT_SELECTION
|
||||
select DRM_KMS_HELPER
|
||||
select FB_IOMEM_HELPERS if DRM_FBDEV_EMULATION
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
config DRM_HISI_HIBMC
|
||||
tristate "DRM Support for Hisilicon Hibmc"
|
||||
depends on DRM && PCI
|
||||
depends on MMU
|
||||
select DRM_CLIENT_SELECTION
|
||||
select DRM_DISPLAY_HELPER
|
||||
select DRM_DISPLAY_DP_HELPER
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
config DRM_LOONGSON
|
||||
tristate "DRM support for Loongson Graphics"
|
||||
depends on DRM && PCI && MMU
|
||||
depends on DRM && PCI
|
||||
depends on LOONGARCH || MIPS || COMPILE_TEST
|
||||
select DRM_CLIENT_SELECTION
|
||||
select DRM_KMS_HELPER
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
config DRM_MGAG200
|
||||
tristate "Matrox G200"
|
||||
depends on DRM && PCI && MMU
|
||||
depends on DRM && PCI
|
||||
select DRM_CLIENT_SELECTION
|
||||
select DRM_GEM_SHMEM_HELPER
|
||||
select DRM_KMS_HELPER
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
config DRM_NOUVEAU
|
||||
tristate "Nouveau (NVIDIA) cards"
|
||||
depends on DRM && PCI && MMU
|
||||
depends on DRM && PCI
|
||||
select IOMMU_API
|
||||
select FW_LOADER
|
||||
select FW_CACHE if PM_SLEEP
|
||||
|
|
@ -94,7 +94,6 @@ config DRM_NOUVEAU_SVM
|
|||
bool "(EXPERIMENTAL) Enable SVM (Shared Virtual Memory) support"
|
||||
depends on DEVICE_PRIVATE
|
||||
depends on DRM_NOUVEAU
|
||||
depends on MMU
|
||||
depends on STAGING
|
||||
select HMM_MIRROR
|
||||
select MMU_NOTIFIER
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
config DRM_QXL
|
||||
tristate "QXL virtual GPU"
|
||||
depends on DRM && PCI && MMU && HAS_IOPORT
|
||||
depends on DRM && PCI && HAS_IOPORT
|
||||
select DRM_CLIENT_SELECTION
|
||||
select DRM_KMS_HELPER
|
||||
select DRM_TTM
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
config DRM_RADEON
|
||||
tristate "ATI Radeon"
|
||||
depends on DRM && PCI && MMU
|
||||
depends on DRM && PCI
|
||||
depends on AGP || !AGP
|
||||
select FW_LOADER
|
||||
select DRM_CLIENT_SELECTION
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ config DRM_BOCHS
|
|||
|
||||
config DRM_CIRRUS_QEMU
|
||||
tristate "Cirrus driver for QEMU emulated device"
|
||||
depends on DRM && PCI && MMU
|
||||
depends on DRM && PCI
|
||||
select DRM_CLIENT_SELECTION
|
||||
select DRM_KMS_HELPER
|
||||
select DRM_GEM_SHMEM_HELPER
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
config DRM_VMWGFX
|
||||
tristate "DRM driver for VMware Virtual GPU"
|
||||
depends on DRM && PCI && MMU
|
||||
depends on DRM && PCI
|
||||
depends on (X86 && HYPERVISOR_GUEST) || ARM64
|
||||
select DRM_CLIENT_SELECTION
|
||||
select DRM_TTM
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
config DRM_XE
|
||||
tristate "Intel Xe Graphics"
|
||||
depends on DRM && PCI && MMU && (m || (y && KUNIT=y))
|
||||
depends on DRM && PCI && (m || (y && KUNIT=y))
|
||||
select INTERVAL_TREE
|
||||
# we need shmfs for the swappable backing store, and in particular
|
||||
# the shmem_readpage() which depends upon tmpfs
|
||||
|
|
|
|||
|
|
@ -2024,9 +2024,6 @@ static int __init iommu_init_pci(struct amd_iommu *iommu)
|
|||
if (!iommu->dev)
|
||||
return -ENODEV;
|
||||
|
||||
/* Prevent binding other PCI device drivers to IOMMU devices */
|
||||
iommu->dev->match_driver = false;
|
||||
|
||||
/* ACPI _PRT won't have an IRQ for IOMMU */
|
||||
iommu->dev->irq_managed = 1;
|
||||
|
||||
|
|
|
|||
|
|
@ -96,7 +96,6 @@ config BNX2
|
|||
config CNIC
|
||||
tristate "QLogic CNIC support"
|
||||
depends on PCI && (IPV6 || IPV6=n)
|
||||
depends on MMU
|
||||
select BNX2
|
||||
select UIO
|
||||
help
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ config ATH11K_PCI
|
|||
select MHI_BUS
|
||||
select QRTR
|
||||
select QRTR_MHI
|
||||
select PCI_PWRCTL_PWRSEQ if HAVE_PWRCTL
|
||||
select PCI_PWRCTRL_PWRSEQ if HAVE_PWRCTRL
|
||||
help
|
||||
This module adds support for PCIE bus
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ config ATH12K
|
|||
select MHI_BUS
|
||||
select QRTR
|
||||
select QRTR_MHI
|
||||
select PCI_PWRCTL_PWRSEQ if HAVE_PWRCTL
|
||||
select PCI_PWRCTRL_PWRSEQ if HAVE_PWRCTRL
|
||||
help
|
||||
Enable support for Qualcomm Technologies Wi-Fi 7 (IEEE
|
||||
802.11be) family of chipsets, for example WCN7850 and
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ config GENERIC_PCI_IOMAP
|
|||
menuconfig PCI
|
||||
bool "PCI support"
|
||||
depends on HAVE_PCI
|
||||
depends on MMU
|
||||
help
|
||||
This option enables support for the PCI local bus, including
|
||||
support for PCI-X and the foundations for PCI Express support.
|
||||
|
|
|
|||
|
|
@ -369,7 +369,9 @@ void pci_bus_add_device(struct pci_dev *dev)
|
|||
pdev->name);
|
||||
}
|
||||
|
||||
dev->match_driver = !dn || of_device_is_available(dn);
|
||||
if (!dn || of_device_is_available(dn))
|
||||
pci_dev_allow_binding(dev);
|
||||
|
||||
retval = device_attach(&dev->dev);
|
||||
if (retval < 0 && retval != -EPROBE_DEFER)
|
||||
pci_warn(dev, "device attach failed (%d)\n", retval);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,10 @@
|
|||
menu "PCI controller drivers"
|
||||
depends on PCI
|
||||
|
||||
config PCI_HOST_COMMON
|
||||
tristate
|
||||
select PCI_ECAM
|
||||
|
||||
config PCI_AARDVARK
|
||||
tristate "Aardvark PCIe controller"
|
||||
depends on (ARCH_MVEBU && ARM64) || COMPILE_TEST
|
||||
|
|
@ -120,10 +124,6 @@ config PCI_FTPCI100
|
|||
depends on OF
|
||||
default ARCH_GEMINI
|
||||
|
||||
config PCI_HOST_COMMON
|
||||
tristate
|
||||
select PCI_ECAM
|
||||
|
||||
config PCI_HOST_GENERIC
|
||||
tristate "Generic PCI host controller"
|
||||
depends on OF
|
||||
|
|
|
|||
|
|
@ -4,16 +4,16 @@ menu "Cadence-based PCIe controllers"
|
|||
depends on PCI
|
||||
|
||||
config PCIE_CADENCE
|
||||
bool
|
||||
tristate
|
||||
|
||||
config PCIE_CADENCE_HOST
|
||||
bool
|
||||
tristate
|
||||
depends on OF
|
||||
select IRQ_DOMAIN
|
||||
select PCIE_CADENCE
|
||||
|
||||
config PCIE_CADENCE_EP
|
||||
bool
|
||||
tristate
|
||||
depends on OF
|
||||
depends on PCI_ENDPOINT
|
||||
select PCIE_CADENCE
|
||||
|
|
@ -43,13 +43,14 @@ config PCIE_CADENCE_PLAT_EP
|
|||
different vendors SoCs.
|
||||
|
||||
config PCI_J721E
|
||||
bool
|
||||
tristate
|
||||
select PCIE_CADENCE_HOST if PCI_J721E_HOST != n
|
||||
select PCIE_CADENCE_EP if PCI_J721E_EP != n
|
||||
|
||||
config PCI_J721E_HOST
|
||||
bool "TI J721E PCIe controller (host mode)"
|
||||
tristate "TI J721E PCIe controller (host mode)"
|
||||
depends on ARCH_K3 || COMPILE_TEST
|
||||
depends on OF
|
||||
select PCIE_CADENCE_HOST
|
||||
select PCI_J721E
|
||||
help
|
||||
Say Y here if you want to support the TI J721E PCIe platform
|
||||
|
|
@ -57,11 +58,10 @@ config PCI_J721E_HOST
|
|||
core.
|
||||
|
||||
config PCI_J721E_EP
|
||||
bool "TI J721E PCIe controller (endpoint mode)"
|
||||
tristate "TI J721E PCIe controller (endpoint mode)"
|
||||
depends on ARCH_K3 || COMPILE_TEST
|
||||
depends on OF
|
||||
depends on PCI_ENDPOINT
|
||||
select PCIE_CADENCE_EP
|
||||
select PCI_J721E
|
||||
help
|
||||
Say Y here if you want to support the TI J721E PCIe platform
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#include <linux/irqchip/chained_irq.h>
|
||||
#include <linux/irqdomain.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
|
@ -27,6 +28,7 @@
|
|||
#define cdns_pcie_to_rc(p) container_of(p, struct cdns_pcie_rc, pcie)
|
||||
|
||||
#define ENABLE_REG_SYS_2 0x108
|
||||
#define ENABLE_CLR_REG_SYS_2 0x308
|
||||
#define STATUS_REG_SYS_2 0x508
|
||||
#define STATUS_CLR_REG_SYS_2 0x708
|
||||
#define LINK_DOWN BIT(1)
|
||||
|
|
@ -116,6 +118,15 @@ static irqreturn_t j721e_pcie_link_irq_handler(int irq, void *priv)
|
|||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void j721e_pcie_disable_link_irq(struct j721e_pcie *pcie)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
reg = j721e_pcie_intd_readl(pcie, ENABLE_CLR_REG_SYS_2);
|
||||
reg |= pcie->linkdown_irq_regfield;
|
||||
j721e_pcie_intd_writel(pcie, ENABLE_CLR_REG_SYS_2, reg);
|
||||
}
|
||||
|
||||
static void j721e_pcie_config_link_irq(struct j721e_pcie *pcie)
|
||||
{
|
||||
u32 reg;
|
||||
|
|
@ -153,11 +164,7 @@ static bool j721e_pcie_link_up(struct cdns_pcie *cdns_pcie)
|
|||
u32 reg;
|
||||
|
||||
reg = j721e_pcie_user_readl(pcie, J721E_PCIE_USER_LINKSTATUS);
|
||||
reg &= LINK_STATUS;
|
||||
if (reg == LINK_UP_DL_COMPLETED)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
return (reg & LINK_STATUS) == LINK_UP_DL_COMPLETED;
|
||||
}
|
||||
|
||||
static const struct cdns_pcie_ops j721e_pcie_ops = {
|
||||
|
|
@ -464,7 +471,7 @@ static int j721e_pcie_probe(struct platform_device *pdev)
|
|||
|
||||
switch (mode) {
|
||||
case PCI_MODE_RC:
|
||||
if (!IS_ENABLED(CONFIG_PCIE_CADENCE_HOST))
|
||||
if (!IS_ENABLED(CONFIG_PCI_J721E_HOST))
|
||||
return -ENODEV;
|
||||
|
||||
bridge = devm_pci_alloc_host_bridge(dev, sizeof(*rc));
|
||||
|
|
@ -483,7 +490,7 @@ static int j721e_pcie_probe(struct platform_device *pdev)
|
|||
pcie->cdns_pcie = cdns_pcie;
|
||||
break;
|
||||
case PCI_MODE_EP:
|
||||
if (!IS_ENABLED(CONFIG_PCIE_CADENCE_EP))
|
||||
if (!IS_ENABLED(CONFIG_PCI_J721E_EP))
|
||||
return -ENODEV;
|
||||
|
||||
ep = devm_kzalloc(dev, sizeof(*ep), GFP_KERNEL);
|
||||
|
|
@ -633,9 +640,22 @@ static void j721e_pcie_remove(struct platform_device *pdev)
|
|||
struct j721e_pcie *pcie = platform_get_drvdata(pdev);
|
||||
struct cdns_pcie *cdns_pcie = pcie->cdns_pcie;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct cdns_pcie_ep *ep;
|
||||
struct cdns_pcie_rc *rc;
|
||||
|
||||
if (pcie->mode == PCI_MODE_RC) {
|
||||
rc = container_of(cdns_pcie, struct cdns_pcie_rc, pcie);
|
||||
cdns_pcie_host_disable(rc);
|
||||
} else {
|
||||
ep = container_of(cdns_pcie, struct cdns_pcie_ep, pcie);
|
||||
cdns_pcie_ep_disable(ep);
|
||||
}
|
||||
|
||||
gpiod_set_value_cansleep(pcie->reset_gpio, 0);
|
||||
|
||||
clk_disable_unprepare(pcie->refclk);
|
||||
cdns_pcie_disable_phy(cdns_pcie);
|
||||
j721e_pcie_disable_link_irq(pcie);
|
||||
pm_runtime_put(dev);
|
||||
pm_runtime_disable(dev);
|
||||
}
|
||||
|
|
@ -730,4 +750,8 @@ static struct platform_driver j721e_pcie_driver = {
|
|||
.pm = pm_sleep_ptr(&j721e_pcie_pm_ops),
|
||||
},
|
||||
};
|
||||
builtin_platform_driver(j721e_pcie_driver);
|
||||
module_platform_driver(j721e_pcie_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("PCIe controller driver for TI's J721E and related SoCs");
|
||||
MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
|
||||
|
|
|
|||
|
|
@ -6,12 +6,14 @@
|
|||
#include <linux/bitfield.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/pci-epc.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/sizes.h>
|
||||
|
||||
#include "pcie-cadence.h"
|
||||
#include "../../pci.h"
|
||||
|
||||
#define CDNS_PCIE_EP_MIN_APERTURE 128 /* 128 bytes */
|
||||
#define CDNS_PCIE_EP_IRQ_PCI_ADDR_NONE 0x1
|
||||
|
|
@ -220,10 +222,11 @@ static void cdns_pcie_ep_unmap_addr(struct pci_epc *epc, u8 fn, u8 vfn,
|
|||
clear_bit(r, &ep->ob_region_map);
|
||||
}
|
||||
|
||||
static int cdns_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 vfn, u8 mmc)
|
||||
static int cdns_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 vfn, u8 nr_irqs)
|
||||
{
|
||||
struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
|
||||
struct cdns_pcie *pcie = &ep->pcie;
|
||||
u8 mmc = order_base_2(nr_irqs);
|
||||
u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET;
|
||||
u16 flags;
|
||||
|
||||
|
|
@ -262,7 +265,7 @@ static int cdns_pcie_ep_get_msi(struct pci_epc *epc, u8 fn, u8 vfn)
|
|||
*/
|
||||
mme = FIELD_GET(PCI_MSI_FLAGS_QSIZE, flags);
|
||||
|
||||
return mme;
|
||||
return 1 << mme;
|
||||
}
|
||||
|
||||
static int cdns_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
|
||||
|
|
@ -281,12 +284,11 @@ static int cdns_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
|
|||
|
||||
val &= PCI_MSIX_FLAGS_QSIZE;
|
||||
|
||||
return val;
|
||||
return val + 1;
|
||||
}
|
||||
|
||||
static int cdns_pcie_ep_set_msix(struct pci_epc *epc, u8 fn, u8 vfn,
|
||||
u16 interrupts, enum pci_barno bir,
|
||||
u32 offset)
|
||||
u16 nr_irqs, enum pci_barno bir, u32 offset)
|
||||
{
|
||||
struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
|
||||
struct cdns_pcie *pcie = &ep->pcie;
|
||||
|
|
@ -298,7 +300,7 @@ static int cdns_pcie_ep_set_msix(struct pci_epc *epc, u8 fn, u8 vfn,
|
|||
reg = cap + PCI_MSIX_FLAGS;
|
||||
val = cdns_pcie_ep_fn_readw(pcie, fn, reg);
|
||||
val &= ~PCI_MSIX_FLAGS_QSIZE;
|
||||
val |= interrupts;
|
||||
val |= nr_irqs - 1; /* encoded as N-1 */
|
||||
cdns_pcie_ep_fn_writew(pcie, fn, reg, val);
|
||||
|
||||
/* Set MSI-X BAR and offset */
|
||||
|
|
@ -308,7 +310,7 @@ static int cdns_pcie_ep_set_msix(struct pci_epc *epc, u8 fn, u8 vfn,
|
|||
|
||||
/* Set PBA BAR and offset. BAR must match MSI-X BAR */
|
||||
reg = cap + PCI_MSIX_PBA;
|
||||
val = (offset + (interrupts * PCI_MSIX_ENTRY_SIZE)) | bir;
|
||||
val = (offset + (nr_irqs * PCI_MSIX_ENTRY_SIZE)) | bir;
|
||||
cdns_pcie_ep_fn_writel(pcie, fn, reg, val);
|
||||
|
||||
return 0;
|
||||
|
|
@ -337,10 +339,10 @@ static void cdns_pcie_ep_assert_intx(struct cdns_pcie_ep *ep, u8 fn, u8 intx,
|
|||
|
||||
if (is_asserted) {
|
||||
ep->irq_pending |= BIT(intx);
|
||||
msg_code = MSG_CODE_ASSERT_INTA + intx;
|
||||
msg_code = PCIE_MSG_CODE_ASSERT_INTA + intx;
|
||||
} else {
|
||||
ep->irq_pending &= ~BIT(intx);
|
||||
msg_code = MSG_CODE_DEASSERT_INTA + intx;
|
||||
msg_code = PCIE_MSG_CODE_DEASSERT_INTA + intx;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&ep->lock, flags);
|
||||
|
|
@ -644,6 +646,17 @@ static const struct pci_epc_ops cdns_pcie_epc_ops = {
|
|||
.get_features = cdns_pcie_ep_get_features,
|
||||
};
|
||||
|
||||
void cdns_pcie_ep_disable(struct cdns_pcie_ep *ep)
|
||||
{
|
||||
struct device *dev = ep->pcie.dev;
|
||||
struct pci_epc *epc = to_pci_epc(dev);
|
||||
|
||||
pci_epc_deinit_notify(epc);
|
||||
pci_epc_mem_free_addr(epc, ep->irq_phys_addr, ep->irq_cpu_addr,
|
||||
SZ_128K);
|
||||
pci_epc_mem_exit(epc);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cdns_pcie_ep_disable);
|
||||
|
||||
int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)
|
||||
{
|
||||
|
|
@ -751,3 +764,8 @@ int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)
|
|||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cdns_pcie_ep_setup);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("Cadence PCIe endpoint controller driver");
|
||||
MODULE_AUTHOR("Cyrille Pitchen <cyrille.pitchen@free-electrons.com>");
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/list_sort.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_pci.h>
|
||||
|
|
@ -72,6 +73,7 @@ void __iomem *cdns_pci_map_bus(struct pci_bus *bus, unsigned int devfn,
|
|||
|
||||
return rc->cfg_base + (where & 0xfff);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cdns_pci_map_bus);
|
||||
|
||||
static struct pci_ops cdns_pcie_host_ops = {
|
||||
.map_bus = cdns_pci_map_bus,
|
||||
|
|
@ -150,6 +152,14 @@ static int cdns_pcie_retrain(struct cdns_pcie *pcie)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void cdns_pcie_host_disable_ptm_response(struct cdns_pcie *pcie)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = cdns_pcie_readl(pcie, CDNS_PCIE_LM_PTM_CTRL);
|
||||
cdns_pcie_writel(pcie, CDNS_PCIE_LM_PTM_CTRL, val & ~CDNS_PCIE_LM_TPM_CTRL_PTMRSEN);
|
||||
}
|
||||
|
||||
static void cdns_pcie_host_enable_ptm_response(struct cdns_pcie *pcie)
|
||||
{
|
||||
u32 val;
|
||||
|
|
@ -175,6 +185,26 @@ static int cdns_pcie_host_start_link(struct cdns_pcie_rc *rc)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void cdns_pcie_host_deinit_root_port(struct cdns_pcie_rc *rc)
|
||||
{
|
||||
struct cdns_pcie *pcie = &rc->pcie;
|
||||
u32 value, ctrl;
|
||||
|
||||
cdns_pcie_rp_writew(pcie, PCI_CLASS_DEVICE, 0xffff);
|
||||
cdns_pcie_rp_writeb(pcie, PCI_CLASS_PROG, 0xff);
|
||||
cdns_pcie_rp_writeb(pcie, PCI_CLASS_REVISION, 0xff);
|
||||
cdns_pcie_writel(pcie, CDNS_PCIE_LM_ID, 0xffffffff);
|
||||
cdns_pcie_rp_writew(pcie, PCI_DEVICE_ID, 0xffff);
|
||||
ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED;
|
||||
value = ~(CDNS_PCIE_LM_RC_BAR_CFG_BAR0_CTRL(ctrl) |
|
||||
CDNS_PCIE_LM_RC_BAR_CFG_BAR1_CTRL(ctrl) |
|
||||
CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_ENABLE |
|
||||
CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_64BITS |
|
||||
CDNS_PCIE_LM_RC_BAR_CFG_IO_ENABLE |
|
||||
CDNS_PCIE_LM_RC_BAR_CFG_IO_32BITS);
|
||||
cdns_pcie_writel(pcie, CDNS_PCIE_LM_RC_BAR_CFG, value);
|
||||
}
|
||||
|
||||
static int cdns_pcie_host_init_root_port(struct cdns_pcie_rc *rc)
|
||||
{
|
||||
struct cdns_pcie *pcie = &rc->pcie;
|
||||
|
|
@ -391,6 +421,32 @@ static int cdns_pcie_host_dma_ranges_cmp(void *priv, const struct list_head *a,
|
|||
return resource_size(entry2->res) - resource_size(entry1->res);
|
||||
}
|
||||
|
||||
static void cdns_pcie_host_unmap_dma_ranges(struct cdns_pcie_rc *rc)
|
||||
{
|
||||
struct cdns_pcie *pcie = &rc->pcie;
|
||||
enum cdns_pcie_rp_bar bar;
|
||||
u32 value;
|
||||
|
||||
/* Reset inbound configuration for all BARs which were being used */
|
||||
for (bar = RP_BAR0; bar <= RP_NO_BAR; bar++) {
|
||||
if (rc->avail_ib_bar[bar])
|
||||
continue;
|
||||
|
||||
cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_RP_BAR_ADDR0(bar), 0);
|
||||
cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_RP_BAR_ADDR1(bar), 0);
|
||||
|
||||
if (bar == RP_NO_BAR)
|
||||
continue;
|
||||
|
||||
value = ~(LM_RC_BAR_CFG_CTRL_MEM_64BITS(bar) |
|
||||
LM_RC_BAR_CFG_CTRL_PREF_MEM_64BITS(bar) |
|
||||
LM_RC_BAR_CFG_CTRL_MEM_32BITS(bar) |
|
||||
LM_RC_BAR_CFG_CTRL_PREF_MEM_32BITS(bar) |
|
||||
LM_RC_BAR_CFG_APERTURE(bar, bar_aperture_mask[bar] + 2));
|
||||
cdns_pcie_writel(pcie, CDNS_PCIE_LM_RC_BAR_CFG, value);
|
||||
}
|
||||
}
|
||||
|
||||
static int cdns_pcie_host_map_dma_ranges(struct cdns_pcie_rc *rc)
|
||||
{
|
||||
struct cdns_pcie *pcie = &rc->pcie;
|
||||
|
|
@ -428,6 +484,29 @@ static int cdns_pcie_host_map_dma_ranges(struct cdns_pcie_rc *rc)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void cdns_pcie_host_deinit_address_translation(struct cdns_pcie_rc *rc)
|
||||
{
|
||||
struct cdns_pcie *pcie = &rc->pcie;
|
||||
struct pci_host_bridge *bridge = pci_host_bridge_from_priv(rc);
|
||||
struct resource_entry *entry;
|
||||
int r;
|
||||
|
||||
cdns_pcie_host_unmap_dma_ranges(rc);
|
||||
|
||||
/*
|
||||
* Reset outbound region 0 which was reserved for configuration space
|
||||
* accesses.
|
||||
*/
|
||||
cdns_pcie_reset_outbound_region(pcie, 0);
|
||||
|
||||
/* Reset rest of the outbound regions */
|
||||
r = 1;
|
||||
resource_list_for_each_entry(entry, &bridge->windows) {
|
||||
cdns_pcie_reset_outbound_region(pcie, r);
|
||||
r++;
|
||||
}
|
||||
}
|
||||
|
||||
static int cdns_pcie_host_init_address_translation(struct cdns_pcie_rc *rc)
|
||||
{
|
||||
struct cdns_pcie *pcie = &rc->pcie;
|
||||
|
|
@ -485,6 +564,12 @@ static int cdns_pcie_host_init_address_translation(struct cdns_pcie_rc *rc)
|
|||
return cdns_pcie_host_map_dma_ranges(rc);
|
||||
}
|
||||
|
||||
static void cdns_pcie_host_deinit(struct cdns_pcie_rc *rc)
|
||||
{
|
||||
cdns_pcie_host_deinit_address_translation(rc);
|
||||
cdns_pcie_host_deinit_root_port(rc);
|
||||
}
|
||||
|
||||
int cdns_pcie_host_init(struct cdns_pcie_rc *rc)
|
||||
{
|
||||
int err;
|
||||
|
|
@ -495,6 +580,15 @@ int cdns_pcie_host_init(struct cdns_pcie_rc *rc)
|
|||
|
||||
return cdns_pcie_host_init_address_translation(rc);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cdns_pcie_host_init);
|
||||
|
||||
static void cdns_pcie_host_link_disable(struct cdns_pcie_rc *rc)
|
||||
{
|
||||
struct cdns_pcie *pcie = &rc->pcie;
|
||||
|
||||
cdns_pcie_stop_link(pcie);
|
||||
cdns_pcie_host_disable_ptm_response(pcie);
|
||||
}
|
||||
|
||||
int cdns_pcie_host_link_setup(struct cdns_pcie_rc *rc)
|
||||
{
|
||||
|
|
@ -519,6 +613,20 @@ int cdns_pcie_host_link_setup(struct cdns_pcie_rc *rc)
|
|||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cdns_pcie_host_link_setup);
|
||||
|
||||
void cdns_pcie_host_disable(struct cdns_pcie_rc *rc)
|
||||
{
|
||||
struct pci_host_bridge *bridge;
|
||||
|
||||
bridge = pci_host_bridge_from_priv(rc);
|
||||
pci_stop_root_bus(bridge->bus);
|
||||
pci_remove_root_bus(bridge->bus);
|
||||
|
||||
cdns_pcie_host_deinit(rc);
|
||||
cdns_pcie_host_link_disable(rc);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cdns_pcie_host_disable);
|
||||
|
||||
int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
|
||||
{
|
||||
|
|
@ -570,14 +678,10 @@ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
|
|||
if (!bridge->ops)
|
||||
bridge->ops = &cdns_pcie_host_ops;
|
||||
|
||||
ret = pci_host_probe(bridge);
|
||||
if (ret < 0)
|
||||
goto err_init;
|
||||
|
||||
return 0;
|
||||
|
||||
err_init:
|
||||
pm_runtime_put_sync(dev);
|
||||
|
||||
return ret;
|
||||
return pci_host_probe(bridge);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cdns_pcie_host_setup);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("Cadence PCIe host controller driver");
|
||||
MODULE_AUTHOR("Cyrille Pitchen <cyrille.pitchen@free-electrons.com>");
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
// Author: Cyrille Pitchen <cyrille.pitchen@free-electrons.com>
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#include "pcie-cadence.h"
|
||||
|
|
@ -23,6 +24,7 @@ void cdns_pcie_detect_quiet_min_delay_set(struct cdns_pcie *pcie)
|
|||
|
||||
cdns_pcie_writel(pcie, CDNS_PCIE_LTSSM_CONTROL_CAP, ltssm_control_cap);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cdns_pcie_detect_quiet_min_delay_set);
|
||||
|
||||
void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, u8 busnr, u8 fn,
|
||||
u32 r, bool is_io,
|
||||
|
|
@ -100,6 +102,7 @@ void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, u8 busnr, u8 fn,
|
|||
cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR0(r), addr0);
|
||||
cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR1(r), addr1);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cdns_pcie_set_outbound_region);
|
||||
|
||||
void cdns_pcie_set_outbound_region_for_normal_msg(struct cdns_pcie *pcie,
|
||||
u8 busnr, u8 fn,
|
||||
|
|
@ -134,6 +137,7 @@ void cdns_pcie_set_outbound_region_for_normal_msg(struct cdns_pcie *pcie,
|
|||
cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR0(r), addr0);
|
||||
cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR1(r), addr1);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cdns_pcie_set_outbound_region_for_normal_msg);
|
||||
|
||||
void cdns_pcie_reset_outbound_region(struct cdns_pcie *pcie, u32 r)
|
||||
{
|
||||
|
|
@ -146,6 +150,7 @@ void cdns_pcie_reset_outbound_region(struct cdns_pcie *pcie, u32 r)
|
|||
cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR0(r), 0);
|
||||
cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR1(r), 0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cdns_pcie_reset_outbound_region);
|
||||
|
||||
void cdns_pcie_disable_phy(struct cdns_pcie *pcie)
|
||||
{
|
||||
|
|
@ -156,6 +161,7 @@ void cdns_pcie_disable_phy(struct cdns_pcie *pcie)
|
|||
phy_exit(pcie->phy[i]);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cdns_pcie_disable_phy);
|
||||
|
||||
int cdns_pcie_enable_phy(struct cdns_pcie *pcie)
|
||||
{
|
||||
|
|
@ -184,6 +190,7 @@ int cdns_pcie_enable_phy(struct cdns_pcie *pcie)
|
|||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cdns_pcie_enable_phy);
|
||||
|
||||
int cdns_pcie_init_phy(struct device *dev, struct cdns_pcie *pcie)
|
||||
{
|
||||
|
|
@ -243,6 +250,7 @@ int cdns_pcie_init_phy(struct device *dev, struct cdns_pcie *pcie)
|
|||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cdns_pcie_init_phy);
|
||||
|
||||
static int cdns_pcie_suspend_noirq(struct device *dev)
|
||||
{
|
||||
|
|
@ -271,3 +279,7 @@ const struct dev_pm_ops cdns_pcie_pm_ops = {
|
|||
NOIRQ_SYSTEM_SLEEP_PM_OPS(cdns_pcie_suspend_noirq,
|
||||
cdns_pcie_resume_noirq)
|
||||
};
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("Cadence PCIe controller driver");
|
||||
MODULE_AUTHOR("Cyrille Pitchen <cyrille.pitchen@free-electrons.com>");
|
||||
|
|
|
|||
|
|
@ -250,17 +250,6 @@ struct cdns_pcie_rp_ib_bar {
|
|||
|
||||
struct cdns_pcie;
|
||||
|
||||
enum cdns_pcie_msg_code {
|
||||
MSG_CODE_ASSERT_INTA = 0x20,
|
||||
MSG_CODE_ASSERT_INTB = 0x21,
|
||||
MSG_CODE_ASSERT_INTC = 0x22,
|
||||
MSG_CODE_ASSERT_INTD = 0x23,
|
||||
MSG_CODE_DEASSERT_INTA = 0x24,
|
||||
MSG_CODE_DEASSERT_INTB = 0x25,
|
||||
MSG_CODE_DEASSERT_INTC = 0x26,
|
||||
MSG_CODE_DEASSERT_INTD = 0x27,
|
||||
};
|
||||
|
||||
enum cdns_pcie_msg_routing {
|
||||
/* Route to Root Complex */
|
||||
MSG_ROUTING_TO_RC,
|
||||
|
|
@ -519,10 +508,11 @@ static inline bool cdns_pcie_link_up(struct cdns_pcie *pcie)
|
|||
return true;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PCIE_CADENCE_HOST
|
||||
#if IS_ENABLED(CONFIG_PCIE_CADENCE_HOST)
|
||||
int cdns_pcie_host_link_setup(struct cdns_pcie_rc *rc);
|
||||
int cdns_pcie_host_init(struct cdns_pcie_rc *rc);
|
||||
int cdns_pcie_host_setup(struct cdns_pcie_rc *rc);
|
||||
void cdns_pcie_host_disable(struct cdns_pcie_rc *rc);
|
||||
void __iomem *cdns_pci_map_bus(struct pci_bus *bus, unsigned int devfn,
|
||||
int where);
|
||||
#else
|
||||
|
|
@ -541,6 +531,10 @@ static inline int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline void cdns_pcie_host_disable(struct cdns_pcie_rc *rc)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void __iomem *cdns_pci_map_bus(struct pci_bus *bus, unsigned int devfn,
|
||||
int where)
|
||||
{
|
||||
|
|
@ -548,13 +542,18 @@ static inline void __iomem *cdns_pci_map_bus(struct pci_bus *bus, unsigned int d
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PCIE_CADENCE_EP
|
||||
#if IS_ENABLED(CONFIG_PCIE_CADENCE_EP)
|
||||
int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep);
|
||||
void cdns_pcie_ep_disable(struct cdns_pcie_ep *ep);
|
||||
#else
|
||||
static inline int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void cdns_pcie_ep_disable(struct cdns_pcie_ep *ep)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
void cdns_pcie_detect_quiet_min_delay_set(struct cdns_pcie *pcie);
|
||||
|
|
|
|||
|
|
@ -118,12 +118,12 @@ static u64 dra7xx_pcie_cpu_addr_fixup(struct dw_pcie *pci, u64 cpu_addr)
|
|||
return cpu_addr & DRA7XX_CPU_TO_BUS_ADDR;
|
||||
}
|
||||
|
||||
static int dra7xx_pcie_link_up(struct dw_pcie *pci)
|
||||
static bool dra7xx_pcie_link_up(struct dw_pcie *pci)
|
||||
{
|
||||
struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci);
|
||||
u32 reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_PHY_CS);
|
||||
|
||||
return !!(reg & LINK_UP);
|
||||
return reg & LINK_UP;
|
||||
}
|
||||
|
||||
static void dra7xx_pcie_stop_link(struct dw_pcie *pci)
|
||||
|
|
|
|||
|
|
@ -209,12 +209,12 @@ static struct pci_ops exynos_pci_ops = {
|
|||
.write = exynos_pcie_wr_own_conf,
|
||||
};
|
||||
|
||||
static int exynos_pcie_link_up(struct dw_pcie *pci)
|
||||
static bool exynos_pcie_link_up(struct dw_pcie *pci)
|
||||
{
|
||||
struct exynos_pcie *ep = to_exynos_pcie(pci);
|
||||
u32 val = exynos_pcie_readl(ep->elbi_base, PCIE_ELBI_RDLH_LINKUP);
|
||||
|
||||
return (val & PCIE_ELBI_XMLH_LINKUP);
|
||||
return val & PCIE_ELBI_XMLH_LINKUP;
|
||||
}
|
||||
|
||||
static int exynos_pcie_host_init(struct dw_pcie_rp *pp)
|
||||
|
|
|
|||
|
|
@ -45,9 +45,14 @@
|
|||
#define IMX95_PCIE_PHY_GEN_CTRL 0x0
|
||||
#define IMX95_PCIE_REF_USE_PAD BIT(17)
|
||||
|
||||
#define IMX95_PCIE_PHY_MPLLA_CTRL 0x10
|
||||
#define IMX95_PCIE_PHY_MPLL_STATE BIT(30)
|
||||
|
||||
#define IMX95_PCIE_SS_RW_REG_0 0xf0
|
||||
#define IMX95_PCIE_REF_CLKEN BIT(23)
|
||||
#define IMX95_PCIE_PHY_CR_PARA_SEL BIT(9)
|
||||
#define IMX95_PCIE_SS_RW_REG_1 0xf4
|
||||
#define IMX95_PCIE_SYS_AUX_PWR_DET BIT(31)
|
||||
|
||||
#define IMX95_PE0_GEN_CTRL_1 0x1050
|
||||
#define IMX95_PCIE_DEVICE_TYPE GENMASK(3, 0)
|
||||
|
|
@ -71,6 +76,9 @@
|
|||
#define IMX95_SID_MASK GENMASK(5, 0)
|
||||
#define IMX95_MAX_LUT 32
|
||||
|
||||
#define IMX95_PCIE_RST_CTRL 0x3010
|
||||
#define IMX95_PCIE_COLD_RST BIT(0)
|
||||
|
||||
#define to_imx_pcie(x) dev_get_drvdata((x)->dev)
|
||||
|
||||
enum imx_pcie_variants {
|
||||
|
|
@ -91,7 +99,7 @@ enum imx_pcie_variants {
|
|||
};
|
||||
|
||||
#define IMX_PCIE_FLAG_IMX_PHY BIT(0)
|
||||
#define IMX_PCIE_FLAG_IMX_SPEED_CHANGE BIT(1)
|
||||
#define IMX_PCIE_FLAG_SPEED_CHANGE_WORKAROUND BIT(1)
|
||||
#define IMX_PCIE_FLAG_SUPPORTS_SUSPEND BIT(2)
|
||||
#define IMX_PCIE_FLAG_HAS_PHYDRV BIT(3)
|
||||
#define IMX_PCIE_FLAG_HAS_APP_RESET BIT(4)
|
||||
|
|
@ -105,6 +113,7 @@ enum imx_pcie_variants {
|
|||
*/
|
||||
#define IMX_PCIE_FLAG_BROKEN_SUSPEND BIT(9)
|
||||
#define IMX_PCIE_FLAG_HAS_LUT BIT(10)
|
||||
#define IMX_PCIE_FLAG_8GT_ECN_ERR051586 BIT(11)
|
||||
|
||||
#define imx_check_flag(pci, val) (pci->drvdata->flags & val)
|
||||
|
||||
|
|
@ -126,9 +135,15 @@ struct imx_pcie_drvdata {
|
|||
int (*init_phy)(struct imx_pcie *pcie);
|
||||
int (*enable_ref_clk)(struct imx_pcie *pcie, bool enable);
|
||||
int (*core_reset)(struct imx_pcie *pcie, bool assert);
|
||||
int (*wait_pll_lock)(struct imx_pcie *pcie);
|
||||
const struct dw_pcie_host_ops *ops;
|
||||
};
|
||||
|
||||
struct imx_lut_data {
|
||||
u32 data1;
|
||||
u32 data2;
|
||||
};
|
||||
|
||||
struct imx_pcie {
|
||||
struct dw_pcie *pci;
|
||||
struct gpio_desc *reset_gpiod;
|
||||
|
|
@ -148,6 +163,8 @@ struct imx_pcie {
|
|||
struct regulator *vph;
|
||||
void __iomem *phy_base;
|
||||
|
||||
/* LUT data for pcie */
|
||||
struct imx_lut_data luts[IMX95_MAX_LUT];
|
||||
/* power domain for pcie */
|
||||
struct device *pd_pcie;
|
||||
/* power domain for pcie phy */
|
||||
|
|
@ -224,6 +241,19 @@ static unsigned int imx_pcie_grp_offset(const struct imx_pcie *imx_pcie)
|
|||
|
||||
static int imx95_pcie_init_phy(struct imx_pcie *imx_pcie)
|
||||
{
|
||||
/*
|
||||
* ERR051624: The Controller Without Vaux Cannot Exit L23 Ready
|
||||
* Through Beacon or PERST# De-assertion
|
||||
*
|
||||
* When the auxiliary power is not available, the controller
|
||||
* cannot exit from L23 Ready with beacon or PERST# de-assertion
|
||||
* when main power is not removed.
|
||||
*
|
||||
* Workaround: Set SS_RW_REG_1[SYS_AUX_PWR_DET] to 1.
|
||||
*/
|
||||
regmap_set_bits(imx_pcie->iomuxc_gpr, IMX95_PCIE_SS_RW_REG_1,
|
||||
IMX95_PCIE_SYS_AUX_PWR_DET);
|
||||
|
||||
regmap_update_bits(imx_pcie->iomuxc_gpr,
|
||||
IMX95_PCIE_SS_RW_REG_0,
|
||||
IMX95_PCIE_PHY_CR_PARA_SEL,
|
||||
|
|
@ -460,6 +490,23 @@ static void imx7d_pcie_wait_for_phy_pll_lock(struct imx_pcie *imx_pcie)
|
|||
dev_err(dev, "PCIe PLL lock timeout\n");
|
||||
}
|
||||
|
||||
static int imx95_pcie_wait_for_phy_pll_lock(struct imx_pcie *imx_pcie)
|
||||
{
|
||||
u32 val;
|
||||
struct device *dev = imx_pcie->pci->dev;
|
||||
|
||||
if (regmap_read_poll_timeout(imx_pcie->iomuxc_gpr,
|
||||
IMX95_PCIE_PHY_MPLLA_CTRL, val,
|
||||
val & IMX95_PCIE_PHY_MPLL_STATE,
|
||||
PHY_PLL_LOCK_WAIT_USLEEP_MAX,
|
||||
PHY_PLL_LOCK_WAIT_TIMEOUT)) {
|
||||
dev_err(dev, "PCIe PLL lock timeout\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int imx_setup_phy_mpll(struct imx_pcie *imx_pcie)
|
||||
{
|
||||
unsigned long phy_rate = 0;
|
||||
|
|
@ -773,6 +820,43 @@ static int imx7d_pcie_core_reset(struct imx_pcie *imx_pcie, bool assert)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int imx95_pcie_core_reset(struct imx_pcie *imx_pcie, bool assert)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
if (assert) {
|
||||
/*
|
||||
* From i.MX95 PCIe PHY perspective, the COLD reset toggle
|
||||
* should be complete after power-up by the following sequence.
|
||||
* > 10us(at power-up)
|
||||
* > 10ns(warm reset)
|
||||
* |<------------>|
|
||||
* ______________
|
||||
* phy_reset ____/ \________________
|
||||
* ____________
|
||||
* ref_clk_en_______________________/
|
||||
* Toggle COLD reset aligned with this sequence for i.MX95 PCIe.
|
||||
*/
|
||||
regmap_set_bits(imx_pcie->iomuxc_gpr, IMX95_PCIE_RST_CTRL,
|
||||
IMX95_PCIE_COLD_RST);
|
||||
/*
|
||||
* Make sure the write to IMX95_PCIE_RST_CTRL is flushed to the
|
||||
* hardware by doing a read. Otherwise, there is no guarantee
|
||||
* that the write has reached the hardware before udelay().
|
||||
*/
|
||||
regmap_read_bypassed(imx_pcie->iomuxc_gpr, IMX95_PCIE_RST_CTRL,
|
||||
&val);
|
||||
udelay(15);
|
||||
regmap_clear_bits(imx_pcie->iomuxc_gpr, IMX95_PCIE_RST_CTRL,
|
||||
IMX95_PCIE_COLD_RST);
|
||||
regmap_read_bypassed(imx_pcie->iomuxc_gpr, IMX95_PCIE_RST_CTRL,
|
||||
&val);
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void imx_pcie_assert_core_reset(struct imx_pcie *imx_pcie)
|
||||
{
|
||||
reset_control_assert(imx_pcie->pciephy_reset);
|
||||
|
|
@ -860,6 +944,12 @@ static int imx_pcie_start_link(struct dw_pcie *pci)
|
|||
u32 tmp;
|
||||
int ret;
|
||||
|
||||
if (!(imx_pcie->drvdata->flags &
|
||||
IMX_PCIE_FLAG_SPEED_CHANGE_WORKAROUND)) {
|
||||
imx_pcie_ltssm_enable(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Force Gen1 operation when starting the link. In case the link is
|
||||
* started in Gen2 mode, there is a possibility the devices on the
|
||||
|
|
@ -875,11 +965,11 @@ static int imx_pcie_start_link(struct dw_pcie *pci)
|
|||
/* Start LTSSM. */
|
||||
imx_pcie_ltssm_enable(dev);
|
||||
|
||||
ret = dw_pcie_wait_for_link(pci);
|
||||
if (ret)
|
||||
goto err_reset_phy;
|
||||
|
||||
if (pci->max_link_speed > 1) {
|
||||
ret = dw_pcie_wait_for_link(pci);
|
||||
if (ret)
|
||||
goto err_reset_phy;
|
||||
|
||||
/* Allow faster modes after the link is up */
|
||||
dw_pcie_dbi_ro_wr_en(pci);
|
||||
tmp = dw_pcie_readl_dbi(pci, offset + PCI_EXP_LNKCAP);
|
||||
|
|
@ -896,34 +986,15 @@ static int imx_pcie_start_link(struct dw_pcie *pci)
|
|||
dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, tmp);
|
||||
dw_pcie_dbi_ro_wr_dis(pci);
|
||||
|
||||
if (imx_pcie->drvdata->flags &
|
||||
IMX_PCIE_FLAG_IMX_SPEED_CHANGE) {
|
||||
|
||||
/*
|
||||
* On i.MX7, DIRECT_SPEED_CHANGE behaves differently
|
||||
* from i.MX6 family when no link speed transition
|
||||
* occurs and we go Gen1 -> yep, Gen1. The difference
|
||||
* is that, in such case, it will not be cleared by HW
|
||||
* which will cause the following code to report false
|
||||
* failure.
|
||||
*/
|
||||
ret = imx_pcie_wait_for_speed_change(imx_pcie);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to bring link up!\n");
|
||||
goto err_reset_phy;
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure link training is finished as well! */
|
||||
ret = dw_pcie_wait_for_link(pci);
|
||||
if (ret)
|
||||
ret = imx_pcie_wait_for_speed_change(imx_pcie);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to bring link up!\n");
|
||||
goto err_reset_phy;
|
||||
}
|
||||
} else {
|
||||
dev_info(dev, "Link: Only Gen1 is enabled\n");
|
||||
}
|
||||
|
||||
tmp = dw_pcie_readw_dbi(pci, offset + PCI_EXP_LNKSTA);
|
||||
dev_info(dev, "Link up, Gen%i\n", tmp & PCI_EXP_LNKSTA_CLS);
|
||||
return 0;
|
||||
|
||||
err_reset_phy:
|
||||
|
|
@ -1182,6 +1253,12 @@ static int imx_pcie_host_init(struct dw_pcie_rp *pp)
|
|||
goto err_phy_off;
|
||||
}
|
||||
|
||||
if (imx_pcie->drvdata->wait_pll_lock) {
|
||||
ret = imx_pcie->drvdata->wait_pll_lock(imx_pcie);
|
||||
if (ret < 0)
|
||||
goto err_phy_off;
|
||||
}
|
||||
|
||||
imx_setup_phy_mpll(imx_pcie);
|
||||
|
||||
return 0;
|
||||
|
|
@ -1214,6 +1291,32 @@ static void imx_pcie_host_exit(struct dw_pcie_rp *pp)
|
|||
regulator_disable(imx_pcie->vpcie);
|
||||
}
|
||||
|
||||
static void imx_pcie_host_post_init(struct dw_pcie_rp *pp)
|
||||
{
|
||||
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
|
||||
struct imx_pcie *imx_pcie = to_imx_pcie(pci);
|
||||
u32 val;
|
||||
|
||||
if (imx_pcie->drvdata->flags & IMX_PCIE_FLAG_8GT_ECN_ERR051586) {
|
||||
/*
|
||||
* ERR051586: Compliance with 8GT/s Receiver Impedance ECN
|
||||
*
|
||||
* The default value of GEN3_RELATED_OFF[GEN3_ZRXDC_NONCOMPL]
|
||||
* is 1 which makes receiver non-compliant with the ZRX-DC
|
||||
* parameter for 2.5 GT/s when operating at 8 GT/s or higher.
|
||||
* It causes unnecessary timeout in L1.
|
||||
*
|
||||
* Workaround: Program GEN3_RELATED_OFF[GEN3_ZRXDC_NONCOMPL]
|
||||
* to 0.
|
||||
*/
|
||||
dw_pcie_dbi_ro_wr_en(pci);
|
||||
val = dw_pcie_readl_dbi(pci, GEN3_RELATED_OFF);
|
||||
val &= ~GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL;
|
||||
dw_pcie_writel_dbi(pci, GEN3_RELATED_OFF, val);
|
||||
dw_pcie_dbi_ro_wr_dis(pci);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* In old DWC implementations, PCIE_ATU_INHIBIT_PAYLOAD in iATU Ctrl2
|
||||
* register is reserved, so the generic DWC implementation of sending the
|
||||
|
|
@ -1239,6 +1342,7 @@ static const struct dw_pcie_host_ops imx_pcie_host_ops = {
|
|||
static const struct dw_pcie_host_ops imx_pcie_host_dw_pme_ops = {
|
||||
.init = imx_pcie_host_init,
|
||||
.deinit = imx_pcie_host_exit,
|
||||
.post_init = imx_pcie_host_post_init,
|
||||
};
|
||||
|
||||
static const struct dw_pcie_ops dw_pcie_ops = {
|
||||
|
|
@ -1350,6 +1454,7 @@ static int imx_add_pcie_ep(struct imx_pcie *imx_pcie,
|
|||
dev_err(dev, "failed to initialize endpoint\n");
|
||||
return ret;
|
||||
}
|
||||
imx_pcie_host_post_init(pp);
|
||||
|
||||
ret = dw_pcie_ep_init_registers(ep);
|
||||
if (ret) {
|
||||
|
|
@ -1386,6 +1491,42 @@ static void imx_pcie_msi_save_restore(struct imx_pcie *imx_pcie, bool save)
|
|||
}
|
||||
}
|
||||
|
||||
static void imx_pcie_lut_save(struct imx_pcie *imx_pcie)
|
||||
{
|
||||
u32 data1, data2;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < IMX95_MAX_LUT; i++) {
|
||||
regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_ACSCTRL,
|
||||
IMX95_PEO_LUT_RWA | i);
|
||||
regmap_read(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA1, &data1);
|
||||
regmap_read(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA2, &data2);
|
||||
if (data1 & IMX95_PE0_LUT_VLD) {
|
||||
imx_pcie->luts[i].data1 = data1;
|
||||
imx_pcie->luts[i].data2 = data2;
|
||||
} else {
|
||||
imx_pcie->luts[i].data1 = 0;
|
||||
imx_pcie->luts[i].data2 = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void imx_pcie_lut_restore(struct imx_pcie *imx_pcie)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < IMX95_MAX_LUT; i++) {
|
||||
if ((imx_pcie->luts[i].data1 & IMX95_PE0_LUT_VLD) == 0)
|
||||
continue;
|
||||
|
||||
regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA1,
|
||||
imx_pcie->luts[i].data1);
|
||||
regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA2,
|
||||
imx_pcie->luts[i].data2);
|
||||
regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_ACSCTRL, i);
|
||||
}
|
||||
}
|
||||
|
||||
static int imx_pcie_suspend_noirq(struct device *dev)
|
||||
{
|
||||
struct imx_pcie *imx_pcie = dev_get_drvdata(dev);
|
||||
|
|
@ -1394,6 +1535,8 @@ static int imx_pcie_suspend_noirq(struct device *dev)
|
|||
return 0;
|
||||
|
||||
imx_pcie_msi_save_restore(imx_pcie, true);
|
||||
if (imx_check_flag(imx_pcie, IMX_PCIE_FLAG_HAS_LUT))
|
||||
imx_pcie_lut_save(imx_pcie);
|
||||
if (imx_check_flag(imx_pcie, IMX_PCIE_FLAG_BROKEN_SUSPEND)) {
|
||||
/*
|
||||
* The minimum for a workaround would be to set PERST# and to
|
||||
|
|
@ -1438,6 +1581,8 @@ static int imx_pcie_resume_noirq(struct device *dev)
|
|||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
if (imx_check_flag(imx_pcie, IMX_PCIE_FLAG_HAS_LUT))
|
||||
imx_pcie_lut_restore(imx_pcie);
|
||||
imx_pcie_msi_save_restore(imx_pcie, false);
|
||||
|
||||
return 0;
|
||||
|
|
@ -1649,7 +1794,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
|
|||
[IMX6Q] = {
|
||||
.variant = IMX6Q,
|
||||
.flags = IMX_PCIE_FLAG_IMX_PHY |
|
||||
IMX_PCIE_FLAG_IMX_SPEED_CHANGE |
|
||||
IMX_PCIE_FLAG_SPEED_CHANGE_WORKAROUND |
|
||||
IMX_PCIE_FLAG_BROKEN_SUSPEND |
|
||||
IMX_PCIE_FLAG_SUPPORTS_SUSPEND,
|
||||
.dbi_length = 0x200,
|
||||
|
|
@ -1665,7 +1810,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
|
|||
[IMX6SX] = {
|
||||
.variant = IMX6SX,
|
||||
.flags = IMX_PCIE_FLAG_IMX_PHY |
|
||||
IMX_PCIE_FLAG_IMX_SPEED_CHANGE |
|
||||
IMX_PCIE_FLAG_SPEED_CHANGE_WORKAROUND |
|
||||
IMX_PCIE_FLAG_SUPPORTS_SUSPEND,
|
||||
.gpr = "fsl,imx6q-iomuxc-gpr",
|
||||
.ltssm_off = IOMUXC_GPR12,
|
||||
|
|
@ -1680,7 +1825,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
|
|||
[IMX6QP] = {
|
||||
.variant = IMX6QP,
|
||||
.flags = IMX_PCIE_FLAG_IMX_PHY |
|
||||
IMX_PCIE_FLAG_IMX_SPEED_CHANGE |
|
||||
IMX_PCIE_FLAG_SPEED_CHANGE_WORKAROUND |
|
||||
IMX_PCIE_FLAG_SUPPORTS_SUSPEND,
|
||||
.dbi_length = 0x200,
|
||||
.gpr = "fsl,imx6q-iomuxc-gpr",
|
||||
|
|
@ -1747,12 +1892,15 @@ static const struct imx_pcie_drvdata drvdata[] = {
|
|||
.variant = IMX95,
|
||||
.flags = IMX_PCIE_FLAG_HAS_SERDES |
|
||||
IMX_PCIE_FLAG_HAS_LUT |
|
||||
IMX_PCIE_FLAG_8GT_ECN_ERR051586 |
|
||||
IMX_PCIE_FLAG_SUPPORTS_SUSPEND,
|
||||
.ltssm_off = IMX95_PE0_GEN_CTRL_3,
|
||||
.ltssm_mask = IMX95_PCIE_LTSSM_EN,
|
||||
.mode_off[0] = IMX95_PE0_GEN_CTRL_1,
|
||||
.mode_mask[0] = IMX95_PCIE_DEVICE_TYPE,
|
||||
.core_reset = imx95_pcie_core_reset,
|
||||
.init_phy = imx95_pcie_init_phy,
|
||||
.wait_pll_lock = imx95_pcie_wait_for_phy_pll_lock,
|
||||
},
|
||||
[IMX8MQ_EP] = {
|
||||
.variant = IMX8MQ_EP,
|
||||
|
|
@ -1799,12 +1947,15 @@ static const struct imx_pcie_drvdata drvdata[] = {
|
|||
[IMX95_EP] = {
|
||||
.variant = IMX95_EP,
|
||||
.flags = IMX_PCIE_FLAG_HAS_SERDES |
|
||||
IMX_PCIE_FLAG_8GT_ECN_ERR051586 |
|
||||
IMX_PCIE_FLAG_SUPPORT_64BIT,
|
||||
.ltssm_off = IMX95_PE0_GEN_CTRL_3,
|
||||
.ltssm_mask = IMX95_PCIE_LTSSM_EN,
|
||||
.mode_off[0] = IMX95_PE0_GEN_CTRL_1,
|
||||
.mode_mask[0] = IMX95_PCIE_DEVICE_TYPE,
|
||||
.init_phy = imx95_pcie_init_phy,
|
||||
.core_reset = imx95_pcie_core_reset,
|
||||
.wait_pll_lock = imx95_pcie_wait_for_phy_pll_lock,
|
||||
.epc_features = &imx95_pcie_epc_features,
|
||||
.mode = DW_PCIE_EP_TYPE,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -492,13 +492,12 @@ static struct pci_ops ks_pcie_ops = {
|
|||
* @pci: A pointer to the dw_pcie structure which holds the DesignWare PCIe host
|
||||
* controller driver information.
|
||||
*/
|
||||
static int ks_pcie_link_up(struct dw_pcie *pci)
|
||||
static bool ks_pcie_link_up(struct dw_pcie *pci)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = dw_pcie_readl_dbi(pci, PCIE_PORT_DEBUG0);
|
||||
val &= PORT_LOGIC_LTSSM_STATE_MASK;
|
||||
return (val == PORT_LOGIC_LTSSM_STATE_L0);
|
||||
return (val & PORT_LOGIC_LTSSM_STATE_MASK) == PORT_LOGIC_LTSSM_STATE_L0;
|
||||
}
|
||||
|
||||
static void ks_pcie_stop_link(struct dw_pcie *pci)
|
||||
|
|
|
|||
|
|
@ -335,7 +335,7 @@ static struct pci_ops meson_pci_ops = {
|
|||
.write = pci_generic_config_write,
|
||||
};
|
||||
|
||||
static int meson_pcie_link_up(struct dw_pcie *pci)
|
||||
static bool meson_pcie_link_up(struct dw_pcie *pci)
|
||||
{
|
||||
struct meson_pcie *mp = to_meson_pcie(pci);
|
||||
struct device *dev = pci->dev;
|
||||
|
|
@ -363,7 +363,7 @@ static int meson_pcie_link_up(struct dw_pcie *pci)
|
|||
dev_dbg(dev, "speed_okay\n");
|
||||
|
||||
if (smlh_up && rdlh_up && ltssm_up && speed_okay)
|
||||
return 1;
|
||||
return true;
|
||||
|
||||
cnt++;
|
||||
|
||||
|
|
@ -371,7 +371,7 @@ static int meson_pcie_link_up(struct dw_pcie *pci)
|
|||
} while (cnt < WAIT_LINKUP_TIMEOUT);
|
||||
|
||||
dev_err(dev, "error: wait linkup timeout\n");
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
static int meson_pcie_host_init(struct dw_pcie_rp *pp)
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ static int armada8k_pcie_setup_phys(struct armada8k_pcie *pcie)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int armada8k_pcie_link_up(struct dw_pcie *pci)
|
||||
static bool armada8k_pcie_link_up(struct dw_pcie *pci)
|
||||
{
|
||||
u32 reg;
|
||||
u32 mask = PCIE_GLB_STS_RDLH_LINK_UP | PCIE_GLB_STS_PHY_LINK_UP;
|
||||
|
|
@ -147,10 +147,10 @@ static int armada8k_pcie_link_up(struct dw_pcie *pci)
|
|||
reg = dw_pcie_readl_dbi(pci, PCIE_GLOBAL_STATUS_REG);
|
||||
|
||||
if ((reg & mask) == mask)
|
||||
return 1;
|
||||
return true;
|
||||
|
||||
dev_dbg(pci->dev, "No link detected (Global-Status: 0x%08x).\n", reg);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
static int armada8k_pcie_start_link(struct dw_pcie *pci)
|
||||
|
|
|
|||
|
|
@ -642,16 +642,262 @@ static void dwc_pcie_ltssm_debugfs_init(struct dw_pcie *pci, struct dentry *dir)
|
|||
&dwc_pcie_ltssm_status_ops);
|
||||
}
|
||||
|
||||
static int dw_pcie_ptm_check_capability(void *drvdata)
|
||||
{
|
||||
struct dw_pcie *pci = drvdata;
|
||||
|
||||
pci->ptm_vsec_offset = dw_pcie_find_ptm_capability(pci);
|
||||
|
||||
return pci->ptm_vsec_offset;
|
||||
}
|
||||
|
||||
static int dw_pcie_ptm_context_update_write(void *drvdata, u8 mode)
|
||||
{
|
||||
struct dw_pcie *pci = drvdata;
|
||||
u32 val;
|
||||
|
||||
if (mode == PCIE_PTM_CONTEXT_UPDATE_AUTO) {
|
||||
val = dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_RES_REQ_CTRL);
|
||||
val |= PTM_REQ_AUTO_UPDATE_ENABLED;
|
||||
dw_pcie_writel_dbi(pci, pci->ptm_vsec_offset + PTM_RES_REQ_CTRL, val);
|
||||
} else if (mode == PCIE_PTM_CONTEXT_UPDATE_MANUAL) {
|
||||
val = dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_RES_REQ_CTRL);
|
||||
val &= ~PTM_REQ_AUTO_UPDATE_ENABLED;
|
||||
val |= PTM_REQ_START_UPDATE;
|
||||
dw_pcie_writel_dbi(pci, pci->ptm_vsec_offset + PTM_RES_REQ_CTRL, val);
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dw_pcie_ptm_context_update_read(void *drvdata, u8 *mode)
|
||||
{
|
||||
struct dw_pcie *pci = drvdata;
|
||||
u32 val;
|
||||
|
||||
val = dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_RES_REQ_CTRL);
|
||||
if (FIELD_GET(PTM_REQ_AUTO_UPDATE_ENABLED, val))
|
||||
*mode = PCIE_PTM_CONTEXT_UPDATE_AUTO;
|
||||
else
|
||||
/*
|
||||
* PTM_REQ_START_UPDATE is a self clearing register bit. So if
|
||||
* PTM_REQ_AUTO_UPDATE_ENABLED is not set, then it implies that
|
||||
* manual update is used.
|
||||
*/
|
||||
*mode = PCIE_PTM_CONTEXT_UPDATE_MANUAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dw_pcie_ptm_context_valid_write(void *drvdata, bool valid)
|
||||
{
|
||||
struct dw_pcie *pci = drvdata;
|
||||
u32 val;
|
||||
|
||||
if (valid) {
|
||||
val = dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_RES_REQ_CTRL);
|
||||
val |= PTM_RES_CCONTEXT_VALID;
|
||||
dw_pcie_writel_dbi(pci, pci->ptm_vsec_offset + PTM_RES_REQ_CTRL, val);
|
||||
} else {
|
||||
val = dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_RES_REQ_CTRL);
|
||||
val &= ~PTM_RES_CCONTEXT_VALID;
|
||||
dw_pcie_writel_dbi(pci, pci->ptm_vsec_offset + PTM_RES_REQ_CTRL, val);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dw_pcie_ptm_context_valid_read(void *drvdata, bool *valid)
|
||||
{
|
||||
struct dw_pcie *pci = drvdata;
|
||||
u32 val;
|
||||
|
||||
val = dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_RES_REQ_CTRL);
|
||||
*valid = !!FIELD_GET(PTM_RES_CCONTEXT_VALID, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dw_pcie_ptm_local_clock_read(void *drvdata, u64 *clock)
|
||||
{
|
||||
struct dw_pcie *pci = drvdata;
|
||||
u32 msb, lsb;
|
||||
|
||||
do {
|
||||
msb = dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_LOCAL_MSB);
|
||||
lsb = dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_LOCAL_LSB);
|
||||
} while (msb != dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_LOCAL_MSB));
|
||||
|
||||
*clock = ((u64) msb) << 32 | lsb;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dw_pcie_ptm_master_clock_read(void *drvdata, u64 *clock)
|
||||
{
|
||||
struct dw_pcie *pci = drvdata;
|
||||
u32 msb, lsb;
|
||||
|
||||
do {
|
||||
msb = dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_MASTER_MSB);
|
||||
lsb = dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_MASTER_LSB);
|
||||
} while (msb != dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_MASTER_MSB));
|
||||
|
||||
*clock = ((u64) msb) << 32 | lsb;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dw_pcie_ptm_t1_read(void *drvdata, u64 *clock)
|
||||
{
|
||||
struct dw_pcie *pci = drvdata;
|
||||
u32 msb, lsb;
|
||||
|
||||
do {
|
||||
msb = dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_T1_T2_MSB);
|
||||
lsb = dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_T1_T2_LSB);
|
||||
} while (msb != dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_T1_T2_MSB));
|
||||
|
||||
*clock = ((u64) msb) << 32 | lsb;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dw_pcie_ptm_t2_read(void *drvdata, u64 *clock)
|
||||
{
|
||||
struct dw_pcie *pci = drvdata;
|
||||
u32 msb, lsb;
|
||||
|
||||
do {
|
||||
msb = dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_T1_T2_MSB);
|
||||
lsb = dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_T1_T2_LSB);
|
||||
} while (msb != dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_T1_T2_MSB));
|
||||
|
||||
*clock = ((u64) msb) << 32 | lsb;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dw_pcie_ptm_t3_read(void *drvdata, u64 *clock)
|
||||
{
|
||||
struct dw_pcie *pci = drvdata;
|
||||
u32 msb, lsb;
|
||||
|
||||
do {
|
||||
msb = dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_T3_T4_MSB);
|
||||
lsb = dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_T3_T4_LSB);
|
||||
} while (msb != dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_T3_T4_MSB));
|
||||
|
||||
*clock = ((u64) msb) << 32 | lsb;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dw_pcie_ptm_t4_read(void *drvdata, u64 *clock)
|
||||
{
|
||||
struct dw_pcie *pci = drvdata;
|
||||
u32 msb, lsb;
|
||||
|
||||
do {
|
||||
msb = dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_T3_T4_MSB);
|
||||
lsb = dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_T3_T4_LSB);
|
||||
} while (msb != dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_T3_T4_MSB));
|
||||
|
||||
*clock = ((u64) msb) << 32 | lsb;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool dw_pcie_ptm_context_update_visible(void *drvdata)
|
||||
{
|
||||
struct dw_pcie *pci = drvdata;
|
||||
|
||||
return (pci->mode == DW_PCIE_EP_TYPE) ? true : false;
|
||||
}
|
||||
|
||||
static bool dw_pcie_ptm_context_valid_visible(void *drvdata)
|
||||
{
|
||||
struct dw_pcie *pci = drvdata;
|
||||
|
||||
return (pci->mode == DW_PCIE_RC_TYPE) ? true : false;
|
||||
}
|
||||
|
||||
static bool dw_pcie_ptm_local_clock_visible(void *drvdata)
|
||||
{
|
||||
/* PTM local clock is always visible */
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool dw_pcie_ptm_master_clock_visible(void *drvdata)
|
||||
{
|
||||
struct dw_pcie *pci = drvdata;
|
||||
|
||||
return (pci->mode == DW_PCIE_EP_TYPE) ? true : false;
|
||||
}
|
||||
|
||||
static bool dw_pcie_ptm_t1_visible(void *drvdata)
|
||||
{
|
||||
struct dw_pcie *pci = drvdata;
|
||||
|
||||
return (pci->mode == DW_PCIE_EP_TYPE) ? true : false;
|
||||
}
|
||||
|
||||
static bool dw_pcie_ptm_t2_visible(void *drvdata)
|
||||
{
|
||||
struct dw_pcie *pci = drvdata;
|
||||
|
||||
return (pci->mode == DW_PCIE_RC_TYPE) ? true : false;
|
||||
}
|
||||
|
||||
static bool dw_pcie_ptm_t3_visible(void *drvdata)
|
||||
{
|
||||
struct dw_pcie *pci = drvdata;
|
||||
|
||||
return (pci->mode == DW_PCIE_RC_TYPE) ? true : false;
|
||||
}
|
||||
|
||||
static bool dw_pcie_ptm_t4_visible(void *drvdata)
|
||||
{
|
||||
struct dw_pcie *pci = drvdata;
|
||||
|
||||
return (pci->mode == DW_PCIE_EP_TYPE) ? true : false;
|
||||
}
|
||||
|
||||
const struct pcie_ptm_ops dw_pcie_ptm_ops = {
|
||||
.check_capability = dw_pcie_ptm_check_capability,
|
||||
.context_update_write = dw_pcie_ptm_context_update_write,
|
||||
.context_update_read = dw_pcie_ptm_context_update_read,
|
||||
.context_valid_write = dw_pcie_ptm_context_valid_write,
|
||||
.context_valid_read = dw_pcie_ptm_context_valid_read,
|
||||
.local_clock_read = dw_pcie_ptm_local_clock_read,
|
||||
.master_clock_read = dw_pcie_ptm_master_clock_read,
|
||||
.t1_read = dw_pcie_ptm_t1_read,
|
||||
.t2_read = dw_pcie_ptm_t2_read,
|
||||
.t3_read = dw_pcie_ptm_t3_read,
|
||||
.t4_read = dw_pcie_ptm_t4_read,
|
||||
.context_update_visible = dw_pcie_ptm_context_update_visible,
|
||||
.context_valid_visible = dw_pcie_ptm_context_valid_visible,
|
||||
.local_clock_visible = dw_pcie_ptm_local_clock_visible,
|
||||
.master_clock_visible = dw_pcie_ptm_master_clock_visible,
|
||||
.t1_visible = dw_pcie_ptm_t1_visible,
|
||||
.t2_visible = dw_pcie_ptm_t2_visible,
|
||||
.t3_visible = dw_pcie_ptm_t3_visible,
|
||||
.t4_visible = dw_pcie_ptm_t4_visible,
|
||||
};
|
||||
|
||||
void dwc_pcie_debugfs_deinit(struct dw_pcie *pci)
|
||||
{
|
||||
if (!pci->debugfs)
|
||||
return;
|
||||
|
||||
pcie_ptm_destroy_debugfs(pci->ptm_debugfs);
|
||||
dwc_pcie_rasdes_debugfs_deinit(pci);
|
||||
debugfs_remove_recursive(pci->debugfs->debug_dir);
|
||||
}
|
||||
|
||||
void dwc_pcie_debugfs_init(struct dw_pcie *pci)
|
||||
void dwc_pcie_debugfs_init(struct dw_pcie *pci, enum dw_pcie_device_mode mode)
|
||||
{
|
||||
char dirname[DWC_DEBUGFS_BUF_MAX];
|
||||
struct device *dev = pci->dev;
|
||||
|
|
@ -674,4 +920,8 @@ void dwc_pcie_debugfs_init(struct dw_pcie *pci)
|
|||
err);
|
||||
|
||||
dwc_pcie_ltssm_debugfs_init(pci, dir);
|
||||
|
||||
pci->mode = mode;
|
||||
pci->ptm_debugfs = pcie_ptm_create_debugfs(pci->dev, pci,
|
||||
&dw_pcie_ptm_ops);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -256,11 +256,11 @@ static unsigned int dw_pcie_ep_get_rebar_offset(struct dw_pcie *pci,
|
|||
return offset;
|
||||
|
||||
reg = dw_pcie_readl_dbi(pci, offset + PCI_REBAR_CTRL);
|
||||
nbars = (reg & PCI_REBAR_CTRL_NBAR_MASK) >> PCI_REBAR_CTRL_NBAR_SHIFT;
|
||||
nbars = FIELD_GET(PCI_REBAR_CTRL_NBAR_MASK, reg);
|
||||
|
||||
for (i = 0; i < nbars; i++, offset += PCI_REBAR_CTRL) {
|
||||
reg = dw_pcie_readl_dbi(pci, offset + PCI_REBAR_CTRL);
|
||||
bar_index = reg & PCI_REBAR_CTRL_BAR_IDX;
|
||||
bar_index = FIELD_GET(PCI_REBAR_CTRL_BAR_IDX, reg);
|
||||
if (bar_index == bar)
|
||||
return offset;
|
||||
}
|
||||
|
|
@ -532,15 +532,16 @@ static int dw_pcie_ep_get_msi(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
|
|||
|
||||
val = FIELD_GET(PCI_MSI_FLAGS_QSIZE, val);
|
||||
|
||||
return val;
|
||||
return 1 << val;
|
||||
}
|
||||
|
||||
static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
|
||||
u8 interrupts)
|
||||
u8 nr_irqs)
|
||||
{
|
||||
struct dw_pcie_ep *ep = epc_get_drvdata(epc);
|
||||
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
|
||||
struct dw_pcie_ep_func *ep_func;
|
||||
u8 mmc = order_base_2(nr_irqs);
|
||||
u32 val, reg;
|
||||
|
||||
ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no);
|
||||
|
|
@ -550,7 +551,7 @@ static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
|
|||
reg = ep_func->msi_cap + PCI_MSI_FLAGS;
|
||||
val = dw_pcie_ep_readw_dbi(ep, func_no, reg);
|
||||
val &= ~PCI_MSI_FLAGS_QMASK;
|
||||
val |= FIELD_PREP(PCI_MSI_FLAGS_QMASK, interrupts);
|
||||
val |= FIELD_PREP(PCI_MSI_FLAGS_QMASK, mmc);
|
||||
dw_pcie_dbi_ro_wr_en(pci);
|
||||
dw_pcie_ep_writew_dbi(ep, func_no, reg, val);
|
||||
dw_pcie_dbi_ro_wr_dis(pci);
|
||||
|
|
@ -575,11 +576,11 @@ static int dw_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
|
|||
|
||||
val &= PCI_MSIX_FLAGS_QSIZE;
|
||||
|
||||
return val;
|
||||
return val + 1;
|
||||
}
|
||||
|
||||
static int dw_pcie_ep_set_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
|
||||
u16 interrupts, enum pci_barno bir, u32 offset)
|
||||
u16 nr_irqs, enum pci_barno bir, u32 offset)
|
||||
{
|
||||
struct dw_pcie_ep *ep = epc_get_drvdata(epc);
|
||||
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
|
||||
|
|
@ -595,7 +596,7 @@ static int dw_pcie_ep_set_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
|
|||
reg = ep_func->msix_cap + PCI_MSIX_FLAGS;
|
||||
val = dw_pcie_ep_readw_dbi(ep, func_no, reg);
|
||||
val &= ~PCI_MSIX_FLAGS_QSIZE;
|
||||
val |= interrupts;
|
||||
val |= nr_irqs - 1; /* encoded as N-1 */
|
||||
dw_pcie_writew_dbi(pci, reg, val);
|
||||
|
||||
reg = ep_func->msix_cap + PCI_MSIX_TABLE;
|
||||
|
|
@ -603,7 +604,7 @@ static int dw_pcie_ep_set_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
|
|||
dw_pcie_ep_writel_dbi(ep, func_no, reg, val);
|
||||
|
||||
reg = ep_func->msix_cap + PCI_MSIX_PBA;
|
||||
val = (offset + (interrupts * PCI_MSIX_ENTRY_SIZE)) | bir;
|
||||
val = (offset + (nr_irqs * PCI_MSIX_ENTRY_SIZE)) | bir;
|
||||
dw_pcie_ep_writel_dbi(ep, func_no, reg, val);
|
||||
|
||||
dw_pcie_dbi_ro_wr_dis(pci);
|
||||
|
|
@ -671,7 +672,7 @@ static const struct pci_epc_ops epc_ops = {
|
|||
* @ep: DWC EP device
|
||||
* @func_no: Function number of the endpoint
|
||||
*
|
||||
* Return: 0 if success, errono otherwise.
|
||||
* Return: 0 if success, errno otherwise.
|
||||
*/
|
||||
int dw_pcie_ep_raise_intx_irq(struct dw_pcie_ep *ep, u8 func_no)
|
||||
{
|
||||
|
|
@ -690,7 +691,7 @@ EXPORT_SYMBOL_GPL(dw_pcie_ep_raise_intx_irq);
|
|||
* @func_no: Function number of the endpoint
|
||||
* @interrupt_num: Interrupt number to be raised
|
||||
*
|
||||
* Return: 0 if success, errono otherwise.
|
||||
* Return: 0 if success, errno otherwise.
|
||||
*/
|
||||
int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
|
||||
u8 interrupt_num)
|
||||
|
|
@ -875,8 +876,7 @@ static void dw_pcie_ep_init_non_sticky_registers(struct dw_pcie *pci)
|
|||
|
||||
if (offset) {
|
||||
reg = dw_pcie_readl_dbi(pci, offset + PCI_REBAR_CTRL);
|
||||
nbars = (reg & PCI_REBAR_CTRL_NBAR_MASK) >>
|
||||
PCI_REBAR_CTRL_NBAR_SHIFT;
|
||||
nbars = FIELD_GET(PCI_REBAR_CTRL_NBAR_MASK, reg);
|
||||
|
||||
/*
|
||||
* PCIe r6.0, sec 7.8.6.2 require us to support at least one
|
||||
|
|
@ -897,7 +897,7 @@ static void dw_pcie_ep_init_non_sticky_registers(struct dw_pcie *pci)
|
|||
* is why RESBAR_CAP_REG is written here.
|
||||
*/
|
||||
val = dw_pcie_readl_dbi(pci, offset + PCI_REBAR_CTRL);
|
||||
bar = val & PCI_REBAR_CTRL_BAR_IDX;
|
||||
bar = FIELD_GET(PCI_REBAR_CTRL_BAR_IDX, val);
|
||||
if (ep->epf_bar[bar])
|
||||
pci_epc_bar_size_to_rebar_cap(ep->epf_bar[bar]->size, &val);
|
||||
else
|
||||
|
|
@ -1013,7 +1013,7 @@ int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep)
|
|||
|
||||
dw_pcie_ep_init_non_sticky_registers(pci);
|
||||
|
||||
dwc_pcie_debugfs_init(pci);
|
||||
dwc_pcie_debugfs_init(pci, DW_PCIE_EP_TYPE);
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -523,6 +523,13 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
|
|||
|
||||
dw_pcie_iatu_detect(pci);
|
||||
|
||||
if (pci->num_lanes < 1)
|
||||
pci->num_lanes = dw_pcie_link_get_max_link_width(pci);
|
||||
|
||||
ret = of_pci_get_equalization_presets(dev, &pp->presets, pci->num_lanes);
|
||||
if (ret)
|
||||
goto err_free_msi;
|
||||
|
||||
/*
|
||||
* Allocate the resource for MSG TLP before programming the iATU
|
||||
* outbound window in dw_pcie_setup_rc(). Since the allocation depends
|
||||
|
|
@ -567,7 +574,7 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
|
|||
if (pp->ops->post_init)
|
||||
pp->ops->post_init(pp);
|
||||
|
||||
dwc_pcie_debugfs_init(pci);
|
||||
dwc_pcie_debugfs_init(pci, DW_PCIE_RC_TYPE);
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
@ -828,6 +835,77 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void dw_pcie_program_presets(struct dw_pcie_rp *pp, enum pci_bus_speed speed)
|
||||
{
|
||||
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
|
||||
u8 lane_eq_offset, lane_reg_size, cap_id;
|
||||
u8 *presets;
|
||||
u32 cap;
|
||||
int i;
|
||||
|
||||
if (speed == PCIE_SPEED_8_0GT) {
|
||||
presets = (u8 *)pp->presets.eq_presets_8gts;
|
||||
lane_eq_offset = PCI_SECPCI_LE_CTRL;
|
||||
cap_id = PCI_EXT_CAP_ID_SECPCI;
|
||||
/* For data rate of 8 GT/S each lane equalization control is 16bits wide*/
|
||||
lane_reg_size = 0x2;
|
||||
} else if (speed == PCIE_SPEED_16_0GT) {
|
||||
presets = pp->presets.eq_presets_Ngts[EQ_PRESET_TYPE_16GTS - 1];
|
||||
lane_eq_offset = PCI_PL_16GT_LE_CTRL;
|
||||
cap_id = PCI_EXT_CAP_ID_PL_16GT;
|
||||
lane_reg_size = 0x1;
|
||||
} else if (speed == PCIE_SPEED_32_0GT) {
|
||||
presets = pp->presets.eq_presets_Ngts[EQ_PRESET_TYPE_32GTS - 1];
|
||||
lane_eq_offset = PCI_PL_32GT_LE_CTRL;
|
||||
cap_id = PCI_EXT_CAP_ID_PL_32GT;
|
||||
lane_reg_size = 0x1;
|
||||
} else if (speed == PCIE_SPEED_64_0GT) {
|
||||
presets = pp->presets.eq_presets_Ngts[EQ_PRESET_TYPE_64GTS - 1];
|
||||
lane_eq_offset = PCI_PL_64GT_LE_CTRL;
|
||||
cap_id = PCI_EXT_CAP_ID_PL_64GT;
|
||||
lane_reg_size = 0x1;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if (presets[0] == PCI_EQ_RESV)
|
||||
return;
|
||||
|
||||
cap = dw_pcie_find_ext_capability(pci, cap_id);
|
||||
if (!cap)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Write preset values to the registers byte-by-byte for the given
|
||||
* number of lanes and register size.
|
||||
*/
|
||||
for (i = 0; i < pci->num_lanes * lane_reg_size; i++)
|
||||
dw_pcie_writeb_dbi(pci, cap + lane_eq_offset + i, presets[i]);
|
||||
}
|
||||
|
||||
static void dw_pcie_config_presets(struct dw_pcie_rp *pp)
|
||||
{
|
||||
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
|
||||
enum pci_bus_speed speed = pcie_link_speed[pci->max_link_speed];
|
||||
|
||||
/*
|
||||
* Lane equalization settings need to be applied for all data rates the
|
||||
* controller supports and for all supported lanes.
|
||||
*/
|
||||
|
||||
if (speed >= PCIE_SPEED_8_0GT)
|
||||
dw_pcie_program_presets(pp, PCIE_SPEED_8_0GT);
|
||||
|
||||
if (speed >= PCIE_SPEED_16_0GT)
|
||||
dw_pcie_program_presets(pp, PCIE_SPEED_16_0GT);
|
||||
|
||||
if (speed >= PCIE_SPEED_32_0GT)
|
||||
dw_pcie_program_presets(pp, PCIE_SPEED_32_0GT);
|
||||
|
||||
if (speed >= PCIE_SPEED_64_0GT)
|
||||
dw_pcie_program_presets(pp, PCIE_SPEED_64_0GT);
|
||||
}
|
||||
|
||||
int dw_pcie_setup_rc(struct dw_pcie_rp *pp)
|
||||
{
|
||||
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
|
||||
|
|
@ -881,6 +959,7 @@ int dw_pcie_setup_rc(struct dw_pcie_rp *pp)
|
|||
PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
|
||||
dw_pcie_writel_dbi(pci, PCI_COMMAND, val);
|
||||
|
||||
dw_pcie_config_presets(pp);
|
||||
/*
|
||||
* If the platform provides its own child bus config accesses, it means
|
||||
* the platform uses its own address translation component rather than
|
||||
|
|
|
|||
|
|
@ -54,6 +54,14 @@ static const char * const dw_pcie_core_rsts[DW_PCIE_NUM_CORE_RSTS] = {
|
|||
[DW_PCIE_PWR_RST] = "pwr",
|
||||
};
|
||||
|
||||
static const struct dwc_pcie_vsec_id dwc_pcie_ptm_vsec_ids[] = {
|
||||
{ .vendor_id = PCI_VENDOR_ID_QCOM, /* EP */
|
||||
.vsec_id = 0x03, .vsec_rev = 0x1 },
|
||||
{ .vendor_id = PCI_VENDOR_ID_QCOM, /* RC */
|
||||
.vsec_id = 0x04, .vsec_rev = 0x1 },
|
||||
{ }
|
||||
};
|
||||
|
||||
static int dw_pcie_get_clocks(struct dw_pcie *pci)
|
||||
{
|
||||
int i, ret;
|
||||
|
|
@ -330,6 +338,12 @@ u16 dw_pcie_find_rasdes_capability(struct dw_pcie *pci)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(dw_pcie_find_rasdes_capability);
|
||||
|
||||
u16 dw_pcie_find_ptm_capability(struct dw_pcie *pci)
|
||||
{
|
||||
return dw_pcie_find_vsec_capability(pci, dwc_pcie_ptm_vsec_ids);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dw_pcie_find_ptm_capability);
|
||||
|
||||
int dw_pcie_read(void __iomem *addr, int size, u32 *val)
|
||||
{
|
||||
if (!IS_ALIGNED((uintptr_t)addr, size)) {
|
||||
|
|
@ -711,7 +725,7 @@ int dw_pcie_wait_for_link(struct dw_pcie *pci)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(dw_pcie_wait_for_link);
|
||||
|
||||
int dw_pcie_link_up(struct dw_pcie *pci)
|
||||
bool dw_pcie_link_up(struct dw_pcie *pci)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
|
|
@ -781,6 +795,14 @@ static void dw_pcie_link_set_max_speed(struct dw_pcie *pci)
|
|||
|
||||
}
|
||||
|
||||
int dw_pcie_link_get_max_link_width(struct dw_pcie *pci)
|
||||
{
|
||||
u8 cap = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
|
||||
u32 lnkcap = dw_pcie_readl_dbi(pci, cap + PCI_EXP_LNKCAP);
|
||||
|
||||
return FIELD_GET(PCI_EXP_LNKCAP_MLW, lnkcap);
|
||||
}
|
||||
|
||||
static void dw_pcie_link_set_max_link_width(struct dw_pcie *pci, u32 num_lanes)
|
||||
{
|
||||
u32 lnkcap, lwsc, plc;
|
||||
|
|
@ -797,22 +819,19 @@ static void dw_pcie_link_set_max_link_width(struct dw_pcie *pci, u32 num_lanes)
|
|||
/* Set link width speed control register */
|
||||
lwsc = dw_pcie_readl_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL);
|
||||
lwsc &= ~PORT_LOGIC_LINK_WIDTH_MASK;
|
||||
lwsc |= PORT_LOGIC_LINK_WIDTH_1_LANES;
|
||||
switch (num_lanes) {
|
||||
case 1:
|
||||
plc |= PORT_LINK_MODE_1_LANES;
|
||||
lwsc |= PORT_LOGIC_LINK_WIDTH_1_LANES;
|
||||
break;
|
||||
case 2:
|
||||
plc |= PORT_LINK_MODE_2_LANES;
|
||||
lwsc |= PORT_LOGIC_LINK_WIDTH_2_LANES;
|
||||
break;
|
||||
case 4:
|
||||
plc |= PORT_LINK_MODE_4_LANES;
|
||||
lwsc |= PORT_LOGIC_LINK_WIDTH_4_LANES;
|
||||
break;
|
||||
case 8:
|
||||
plc |= PORT_LINK_MODE_8_LANES;
|
||||
lwsc |= PORT_LOGIC_LINK_WIDTH_8_LANES;
|
||||
break;
|
||||
default:
|
||||
dev_err(pci->dev, "num-lanes %u: invalid value\n", num_lanes);
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@
|
|||
#include <linux/pci-epc.h>
|
||||
#include <linux/pci-epf.h>
|
||||
|
||||
#include "../../pci.h"
|
||||
|
||||
/* DWC PCIe IP-core versions (native support since v4.70a) */
|
||||
#define DW_PCIE_VER_365A 0x3336352a
|
||||
#define DW_PCIE_VER_460A 0x3436302a
|
||||
|
|
@ -260,6 +262,21 @@
|
|||
|
||||
#define PCIE_RAS_DES_EVENT_COUNTER_DATA 0xc
|
||||
|
||||
/* PTM register definitions */
|
||||
#define PTM_RES_REQ_CTRL 0x8
|
||||
#define PTM_RES_CCONTEXT_VALID BIT(0)
|
||||
#define PTM_REQ_AUTO_UPDATE_ENABLED BIT(0)
|
||||
#define PTM_REQ_START_UPDATE BIT(1)
|
||||
|
||||
#define PTM_LOCAL_LSB 0x10
|
||||
#define PTM_LOCAL_MSB 0x14
|
||||
#define PTM_T1_T2_LSB 0x18
|
||||
#define PTM_T1_T2_MSB 0x1c
|
||||
#define PTM_T3_T4_LSB 0x28
|
||||
#define PTM_T3_T4_MSB 0x2c
|
||||
#define PTM_MASTER_LSB 0x38
|
||||
#define PTM_MASTER_MSB 0x3c
|
||||
|
||||
/*
|
||||
* The default address offset between dbi_base and atu_base. Root controller
|
||||
* drivers are not required to initialize atu_base if the offset matches this
|
||||
|
|
@ -412,6 +429,7 @@ struct dw_pcie_rp {
|
|||
int msg_atu_index;
|
||||
struct resource *msg_res;
|
||||
bool use_linkup_irq;
|
||||
struct pci_eq_presets presets;
|
||||
};
|
||||
|
||||
struct dw_pcie_ep_ops {
|
||||
|
|
@ -462,7 +480,7 @@ struct dw_pcie_ops {
|
|||
size_t size, u32 val);
|
||||
void (*write_dbi2)(struct dw_pcie *pcie, void __iomem *base, u32 reg,
|
||||
size_t size, u32 val);
|
||||
int (*link_up)(struct dw_pcie *pcie);
|
||||
bool (*link_up)(struct dw_pcie *pcie);
|
||||
enum dw_pcie_ltssm (*get_ltssm)(struct dw_pcie *pcie);
|
||||
int (*start_link)(struct dw_pcie *pcie);
|
||||
void (*stop_link)(struct dw_pcie *pcie);
|
||||
|
|
@ -503,6 +521,9 @@ struct dw_pcie {
|
|||
struct gpio_desc *pe_rst;
|
||||
bool suspended;
|
||||
struct debugfs_info *debugfs;
|
||||
enum dw_pcie_device_mode mode;
|
||||
u16 ptm_vsec_offset;
|
||||
struct pci_ptm_debugfs *ptm_debugfs;
|
||||
|
||||
/*
|
||||
* If iATU input addresses are offset from CPU physical addresses,
|
||||
|
|
@ -530,6 +551,7 @@ void dw_pcie_version_detect(struct dw_pcie *pci);
|
|||
u8 dw_pcie_find_capability(struct dw_pcie *pci, u8 cap);
|
||||
u16 dw_pcie_find_ext_capability(struct dw_pcie *pci, u8 cap);
|
||||
u16 dw_pcie_find_rasdes_capability(struct dw_pcie *pci);
|
||||
u16 dw_pcie_find_ptm_capability(struct dw_pcie *pci);
|
||||
|
||||
int dw_pcie_read(void __iomem *addr, int size, u32 *val);
|
||||
int dw_pcie_write(void __iomem *addr, int size, u32 val);
|
||||
|
|
@ -537,9 +559,10 @@ int dw_pcie_write(void __iomem *addr, int size, u32 val);
|
|||
u32 dw_pcie_read_dbi(struct dw_pcie *pci, u32 reg, size_t size);
|
||||
void dw_pcie_write_dbi(struct dw_pcie *pci, u32 reg, size_t size, u32 val);
|
||||
void dw_pcie_write_dbi2(struct dw_pcie *pci, u32 reg, size_t size, u32 val);
|
||||
int dw_pcie_link_up(struct dw_pcie *pci);
|
||||
bool dw_pcie_link_up(struct dw_pcie *pci);
|
||||
void dw_pcie_upconfig_setup(struct dw_pcie *pci);
|
||||
int dw_pcie_wait_for_link(struct dw_pcie *pci);
|
||||
int dw_pcie_link_get_max_link_width(struct dw_pcie *pci);
|
||||
int dw_pcie_prog_outbound_atu(struct dw_pcie *pci,
|
||||
const struct dw_pcie_ob_atu_cfg *atu);
|
||||
int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, int index, int type,
|
||||
|
|
@ -871,10 +894,11 @@ dw_pcie_ep_get_func_from_ep(struct dw_pcie_ep *ep, u8 func_no)
|
|||
#endif
|
||||
|
||||
#ifdef CONFIG_PCIE_DW_DEBUGFS
|
||||
void dwc_pcie_debugfs_init(struct dw_pcie *pci);
|
||||
void dwc_pcie_debugfs_init(struct dw_pcie *pci, enum dw_pcie_device_mode mode);
|
||||
void dwc_pcie_debugfs_deinit(struct dw_pcie *pci);
|
||||
#else
|
||||
static inline void dwc_pcie_debugfs_init(struct dw_pcie *pci)
|
||||
static inline void dwc_pcie_debugfs_init(struct dw_pcie *pci,
|
||||
enum dw_pcie_device_mode mode)
|
||||
{
|
||||
}
|
||||
static inline void dwc_pcie_debugfs_deinit(struct dw_pcie *pci)
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
* Author: Simon Xue <xxm@rock-chips.com>
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/irqchip/chained_irq.h>
|
||||
|
|
@ -21,6 +22,7 @@
|
|||
#include <linux/regmap.h>
|
||||
#include <linux/reset.h>
|
||||
|
||||
#include "../../pci.h"
|
||||
#include "pcie-designware.h"
|
||||
|
||||
/*
|
||||
|
|
@ -33,26 +35,36 @@
|
|||
|
||||
#define to_rockchip_pcie(x) dev_get_drvdata((x)->dev)
|
||||
|
||||
#define PCIE_CLIENT_RC_MODE HIWORD_UPDATE_BIT(0x40)
|
||||
#define PCIE_CLIENT_EP_MODE HIWORD_UPDATE(0xf0, 0x0)
|
||||
#define PCIE_CLIENT_ENABLE_LTSSM HIWORD_UPDATE_BIT(0xc)
|
||||
#define PCIE_CLIENT_DISABLE_LTSSM HIWORD_UPDATE(0x0c, 0x8)
|
||||
#define PCIE_CLIENT_INTR_STATUS_MISC 0x10
|
||||
#define PCIE_CLIENT_INTR_MASK_MISC 0x24
|
||||
#define PCIE_SMLH_LINKUP BIT(16)
|
||||
#define PCIE_RDLH_LINKUP BIT(17)
|
||||
#define PCIE_LINKUP (PCIE_SMLH_LINKUP | PCIE_RDLH_LINKUP)
|
||||
#define PCIE_RDLH_LINK_UP_CHGED BIT(1)
|
||||
#define PCIE_LINK_REQ_RST_NOT_INT BIT(2)
|
||||
#define PCIE_L0S_ENTRY 0x11
|
||||
#define PCIE_CLIENT_GENERAL_CONTROL 0x0
|
||||
/* General Control Register */
|
||||
#define PCIE_CLIENT_GENERAL_CON 0x0
|
||||
#define PCIE_CLIENT_RC_MODE HIWORD_UPDATE_BIT(0x40)
|
||||
#define PCIE_CLIENT_EP_MODE HIWORD_UPDATE(0xf0, 0x0)
|
||||
#define PCIE_CLIENT_ENABLE_LTSSM HIWORD_UPDATE_BIT(0xc)
|
||||
#define PCIE_CLIENT_DISABLE_LTSSM HIWORD_UPDATE(0x0c, 0x8)
|
||||
|
||||
/* Interrupt Status Register Related to Legacy Interrupt */
|
||||
#define PCIE_CLIENT_INTR_STATUS_LEGACY 0x8
|
||||
|
||||
/* Interrupt Status Register Related to Miscellaneous Operation */
|
||||
#define PCIE_CLIENT_INTR_STATUS_MISC 0x10
|
||||
#define PCIE_RDLH_LINK_UP_CHGED BIT(1)
|
||||
#define PCIE_LINK_REQ_RST_NOT_INT BIT(2)
|
||||
|
||||
/* Interrupt Mask Register Related to Legacy Interrupt */
|
||||
#define PCIE_CLIENT_INTR_MASK_LEGACY 0x1c
|
||||
#define PCIE_CLIENT_GENERAL_DEBUG 0x104
|
||||
|
||||
/* Interrupt Mask Register Related to Miscellaneous Operation */
|
||||
#define PCIE_CLIENT_INTR_MASK_MISC 0x24
|
||||
|
||||
/* Hot Reset Control Register */
|
||||
#define PCIE_CLIENT_HOT_RESET_CTRL 0x180
|
||||
#define PCIE_LTSSM_ENABLE_ENHANCE BIT(4)
|
||||
|
||||
/* LTSSM Status Register */
|
||||
#define PCIE_CLIENT_LTSSM_STATUS 0x300
|
||||
#define PCIE_LTSSM_ENABLE_ENHANCE BIT(4)
|
||||
#define PCIE_LTSSM_STATUS_MASK GENMASK(5, 0)
|
||||
#define PCIE_LINKUP 0x3
|
||||
#define PCIE_LINKUP_MASK GENMASK(17, 16)
|
||||
#define PCIE_LTSSM_STATUS_MASK GENMASK(5, 0)
|
||||
|
||||
struct rockchip_pcie {
|
||||
struct dw_pcie pci;
|
||||
|
|
@ -163,25 +175,36 @@ static u32 rockchip_pcie_get_ltssm(struct rockchip_pcie *rockchip)
|
|||
static void rockchip_pcie_enable_ltssm(struct rockchip_pcie *rockchip)
|
||||
{
|
||||
rockchip_pcie_writel_apb(rockchip, PCIE_CLIENT_ENABLE_LTSSM,
|
||||
PCIE_CLIENT_GENERAL_CONTROL);
|
||||
PCIE_CLIENT_GENERAL_CON);
|
||||
}
|
||||
|
||||
static void rockchip_pcie_disable_ltssm(struct rockchip_pcie *rockchip)
|
||||
{
|
||||
rockchip_pcie_writel_apb(rockchip, PCIE_CLIENT_DISABLE_LTSSM,
|
||||
PCIE_CLIENT_GENERAL_CONTROL);
|
||||
PCIE_CLIENT_GENERAL_CON);
|
||||
}
|
||||
|
||||
static int rockchip_pcie_link_up(struct dw_pcie *pci)
|
||||
static bool rockchip_pcie_link_up(struct dw_pcie *pci)
|
||||
{
|
||||
struct rockchip_pcie *rockchip = to_rockchip_pcie(pci);
|
||||
u32 val = rockchip_pcie_get_ltssm(rockchip);
|
||||
|
||||
if ((val & PCIE_LINKUP) == PCIE_LINKUP &&
|
||||
(val & PCIE_LTSSM_STATUS_MASK) == PCIE_L0S_ENTRY)
|
||||
return 1;
|
||||
return FIELD_GET(PCIE_LINKUP_MASK, val) == PCIE_LINKUP;
|
||||
}
|
||||
|
||||
return 0;
|
||||
static void rockchip_pcie_enable_l0s(struct dw_pcie *pci)
|
||||
{
|
||||
u32 cap, lnkcap;
|
||||
|
||||
/* Enable L0S capability for all SoCs */
|
||||
cap = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
|
||||
if (cap) {
|
||||
lnkcap = dw_pcie_readl_dbi(pci, cap + PCI_EXP_LNKCAP);
|
||||
lnkcap |= PCI_EXP_LNKCAP_ASPM_L0S;
|
||||
dw_pcie_dbi_ro_wr_en(pci);
|
||||
dw_pcie_writel_dbi(pci, cap + PCI_EXP_LNKCAP, lnkcap);
|
||||
dw_pcie_dbi_ro_wr_dis(pci);
|
||||
}
|
||||
}
|
||||
|
||||
static int rockchip_pcie_start_link(struct dw_pcie *pci)
|
||||
|
|
@ -202,7 +225,7 @@ static int rockchip_pcie_start_link(struct dw_pcie *pci)
|
|||
* We need more extra time as before, rather than setting just
|
||||
* 100us as we don't know how long should the device need to reset.
|
||||
*/
|
||||
msleep(100);
|
||||
msleep(PCIE_T_PVPERL_MS);
|
||||
gpiod_set_value_cansleep(rockchip->rst_gpio, 1);
|
||||
|
||||
return 0;
|
||||
|
|
@ -233,6 +256,8 @@ static int rockchip_pcie_host_init(struct dw_pcie_rp *pp)
|
|||
irq_set_chained_handler_and_data(irq, rockchip_pcie_intx_handler,
|
||||
rockchip);
|
||||
|
||||
rockchip_pcie_enable_l0s(pci);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -263,16 +288,14 @@ static void rockchip_pcie_ep_hide_broken_ats_cap_rk3588(struct dw_pcie_ep *ep)
|
|||
dev_err(dev, "failed to hide ATS capability\n");
|
||||
}
|
||||
|
||||
static void rockchip_pcie_ep_pre_init(struct dw_pcie_ep *ep)
|
||||
{
|
||||
rockchip_pcie_ep_hide_broken_ats_cap_rk3588(ep);
|
||||
}
|
||||
|
||||
static void rockchip_pcie_ep_init(struct dw_pcie_ep *ep)
|
||||
{
|
||||
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
|
||||
enum pci_barno bar;
|
||||
|
||||
rockchip_pcie_enable_l0s(pci);
|
||||
rockchip_pcie_ep_hide_broken_ats_cap_rk3588(ep);
|
||||
|
||||
for (bar = 0; bar < PCI_STD_NUM_BARS; bar++)
|
||||
dw_pcie_ep_reset_bar(pci, bar);
|
||||
};
|
||||
|
|
@ -342,7 +365,6 @@ rockchip_pcie_get_features(struct dw_pcie_ep *ep)
|
|||
|
||||
static const struct dw_pcie_ep_ops rockchip_pcie_ep_ops = {
|
||||
.init = rockchip_pcie_ep_init,
|
||||
.pre_init = rockchip_pcie_ep_pre_init,
|
||||
.raise_irq = rockchip_pcie_raise_irq,
|
||||
.get_features = rockchip_pcie_get_features,
|
||||
};
|
||||
|
|
@ -410,8 +432,8 @@ static int rockchip_pcie_phy_init(struct rockchip_pcie *rockchip)
|
|||
|
||||
static void rockchip_pcie_phy_deinit(struct rockchip_pcie *rockchip)
|
||||
{
|
||||
phy_exit(rockchip->phy);
|
||||
phy_power_off(rockchip->phy);
|
||||
phy_exit(rockchip->phy);
|
||||
}
|
||||
|
||||
static const struct dw_pcie_ops dw_pcie_ops = {
|
||||
|
|
@ -426,7 +448,7 @@ static irqreturn_t rockchip_pcie_rc_sys_irq_thread(int irq, void *arg)
|
|||
struct dw_pcie *pci = &rockchip->pci;
|
||||
struct dw_pcie_rp *pp = &pci->pp;
|
||||
struct device *dev = pci->dev;
|
||||
u32 reg, val;
|
||||
u32 reg;
|
||||
|
||||
reg = rockchip_pcie_readl_apb(rockchip, PCIE_CLIENT_INTR_STATUS_MISC);
|
||||
rockchip_pcie_writel_apb(rockchip, reg, PCIE_CLIENT_INTR_STATUS_MISC);
|
||||
|
|
@ -435,8 +457,7 @@ static irqreturn_t rockchip_pcie_rc_sys_irq_thread(int irq, void *arg)
|
|||
dev_dbg(dev, "LTSSM_STATUS: %#x\n", rockchip_pcie_get_ltssm(rockchip));
|
||||
|
||||
if (reg & PCIE_RDLH_LINK_UP_CHGED) {
|
||||
val = rockchip_pcie_get_ltssm(rockchip);
|
||||
if ((val & PCIE_LINKUP) == PCIE_LINKUP) {
|
||||
if (rockchip_pcie_link_up(pci)) {
|
||||
dev_dbg(dev, "Received Link up event. Starting enumeration!\n");
|
||||
/* Rescan the bus to enumerate endpoint devices */
|
||||
pci_lock_rescan_remove();
|
||||
|
|
@ -453,7 +474,7 @@ static irqreturn_t rockchip_pcie_ep_sys_irq_thread(int irq, void *arg)
|
|||
struct rockchip_pcie *rockchip = arg;
|
||||
struct dw_pcie *pci = &rockchip->pci;
|
||||
struct device *dev = pci->dev;
|
||||
u32 reg, val;
|
||||
u32 reg;
|
||||
|
||||
reg = rockchip_pcie_readl_apb(rockchip, PCIE_CLIENT_INTR_STATUS_MISC);
|
||||
rockchip_pcie_writel_apb(rockchip, reg, PCIE_CLIENT_INTR_STATUS_MISC);
|
||||
|
|
@ -467,8 +488,7 @@ static irqreturn_t rockchip_pcie_ep_sys_irq_thread(int irq, void *arg)
|
|||
}
|
||||
|
||||
if (reg & PCIE_RDLH_LINK_UP_CHGED) {
|
||||
val = rockchip_pcie_get_ltssm(rockchip);
|
||||
if ((val & PCIE_LINKUP) == PCIE_LINKUP) {
|
||||
if (rockchip_pcie_link_up(pci)) {
|
||||
dev_dbg(dev, "link up\n");
|
||||
dw_pcie_ep_linkup(&pci->ep);
|
||||
}
|
||||
|
|
@ -505,7 +525,7 @@ static int rockchip_pcie_configure_rc(struct platform_device *pdev,
|
|||
rockchip_pcie_writel_apb(rockchip, val, PCIE_CLIENT_HOT_RESET_CTRL);
|
||||
|
||||
rockchip_pcie_writel_apb(rockchip, PCIE_CLIENT_RC_MODE,
|
||||
PCIE_CLIENT_GENERAL_CONTROL);
|
||||
PCIE_CLIENT_GENERAL_CON);
|
||||
|
||||
pp = &rockchip->pci.pp;
|
||||
pp->ops = &rockchip_pcie_host_ops;
|
||||
|
|
@ -551,7 +571,7 @@ static int rockchip_pcie_configure_ep(struct platform_device *pdev,
|
|||
rockchip_pcie_writel_apb(rockchip, val, PCIE_CLIENT_HOT_RESET_CTRL);
|
||||
|
||||
rockchip_pcie_writel_apb(rockchip, PCIE_CLIENT_EP_MODE,
|
||||
PCIE_CLIENT_GENERAL_CONTROL);
|
||||
PCIE_CLIENT_GENERAL_CON);
|
||||
|
||||
rockchip->pci.ep.ops = &rockchip_pcie_ep_ops;
|
||||
rockchip->pci.ep.page_size = SZ_64K;
|
||||
|
|
@ -601,6 +621,10 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
|
|||
rockchip->pci.ops = &dw_pcie_ops;
|
||||
rockchip->data = data;
|
||||
|
||||
/* Default N_FTS value (210) is broken, override it to 255 */
|
||||
rockchip->pci.n_fts[0] = 255; /* Gen1 */
|
||||
rockchip->pci.n_fts[1] = 255; /* Gen2+ */
|
||||
|
||||
ret = rockchip_pcie_resource_get(pdev, rockchip);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#include <linux/pci-acpi.h>
|
||||
#include <linux/pci-ecam.h>
|
||||
#include "../../pci.h"
|
||||
#include "../pci-host-common.h"
|
||||
|
||||
#if defined(CONFIG_PCI_HISI) || (defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS))
|
||||
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ static struct pci_ops histb_pci_ops = {
|
|||
.write = histb_pcie_wr_own_conf,
|
||||
};
|
||||
|
||||
static int histb_pcie_link_up(struct dw_pcie *pci)
|
||||
static bool histb_pcie_link_up(struct dw_pcie *pci)
|
||||
{
|
||||
struct histb_pcie *hipcie = to_histb_pcie(pci);
|
||||
u32 regval;
|
||||
|
|
@ -160,11 +160,8 @@ static int histb_pcie_link_up(struct dw_pcie *pci)
|
|||
regval = histb_pcie_readl(hipcie, PCIE_SYS_STAT0);
|
||||
status = histb_pcie_readl(hipcie, PCIE_SYS_STAT4);
|
||||
status &= PCIE_LTSSM_STATE_MASK;
|
||||
if ((regval & PCIE_XMLH_LINK_UP) && (regval & PCIE_RDLH_LINK_UP) &&
|
||||
(status == PCIE_LTSSM_STATE_ACTIVE))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
return ((regval & PCIE_XMLH_LINK_UP) && (regval & PCIE_RDLH_LINK_UP) &&
|
||||
(status == PCIE_LTSSM_STATE_ACTIVE));
|
||||
}
|
||||
|
||||
static int histb_pcie_start_link(struct dw_pcie *pci)
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ static void keembay_pcie_ltssm_set(struct keembay_pcie *pcie, bool enable)
|
|||
writel(val, pcie->apb_base + PCIE_REGS_PCIE_APP_CNTRL);
|
||||
}
|
||||
|
||||
static int keembay_pcie_link_up(struct dw_pcie *pci)
|
||||
static bool keembay_pcie_link_up(struct dw_pcie *pci)
|
||||
{
|
||||
struct keembay_pcie *pcie = dev_get_drvdata(pci->dev);
|
||||
u32 val;
|
||||
|
|
|
|||
|
|
@ -586,16 +586,13 @@ static void kirin_pcie_write_dbi(struct dw_pcie *pci, void __iomem *base,
|
|||
kirin_pcie_sideband_dbi_w_mode(kirin_pcie, false);
|
||||
}
|
||||
|
||||
static int kirin_pcie_link_up(struct dw_pcie *pci)
|
||||
static bool kirin_pcie_link_up(struct dw_pcie *pci)
|
||||
{
|
||||
struct kirin_pcie *kirin_pcie = to_kirin_pcie(pci);
|
||||
u32 val;
|
||||
|
||||
regmap_read(kirin_pcie->apb, PCIE_APB_PHY_STATUS0, &val);
|
||||
if ((val & PCIE_LINKUP_ENABLE) == PCIE_LINKUP_ENABLE)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
return (val & PCIE_LINKUP_ENABLE) == PCIE_LINKUP_ENABLE;
|
||||
}
|
||||
|
||||
static int kirin_pcie_start_link(struct dw_pcie *pci)
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@
|
|||
#define PARF_DEVICE_TYPE 0x1000
|
||||
#define PARF_BDF_TO_SID_CFG 0x2c00
|
||||
#define PARF_INT_ALL_5_MASK 0x2dcc
|
||||
#define PARF_INT_ALL_3_MASK 0x2e18
|
||||
|
||||
/* PARF_INT_ALL_{STATUS/CLEAR/MASK} register fields */
|
||||
#define PARF_INT_ALL_LINK_DOWN BIT(1)
|
||||
|
|
@ -132,6 +133,9 @@
|
|||
/* PARF_INT_ALL_5_MASK fields */
|
||||
#define PARF_INT_ALL_5_MHI_RAM_DATA_PARITY_ERR BIT(0)
|
||||
|
||||
/* PARF_INT_ALL_3_MASK fields */
|
||||
#define PARF_INT_ALL_3_PTM_UPDATING BIT(4)
|
||||
|
||||
/* ELBI registers */
|
||||
#define ELBI_SYS_STTS 0x08
|
||||
#define ELBI_CS2_ENABLE 0xa4
|
||||
|
|
@ -261,7 +265,7 @@ static void qcom_pcie_ep_configure_tcsr(struct qcom_pcie_ep *pcie_ep)
|
|||
}
|
||||
}
|
||||
|
||||
static int qcom_pcie_dw_link_up(struct dw_pcie *pci)
|
||||
static bool qcom_pcie_dw_link_up(struct dw_pcie *pci)
|
||||
{
|
||||
struct qcom_pcie_ep *pcie_ep = to_pcie_ep(pci);
|
||||
u32 reg;
|
||||
|
|
@ -497,6 +501,10 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci)
|
|||
writel_relaxed(val, pcie_ep->parf + PARF_INT_ALL_5_MASK);
|
||||
}
|
||||
|
||||
val = readl_relaxed(pcie_ep->parf + PARF_INT_ALL_3_MASK);
|
||||
val &= ~PARF_INT_ALL_3_PTM_UPDATING;
|
||||
writel_relaxed(val, pcie_ep->parf + PARF_INT_ALL_3_MASK);
|
||||
|
||||
ret = dw_pcie_ep_init_registers(&pcie_ep->pci.ep);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to complete initialization: %d\n", ret);
|
||||
|
|
|
|||
|
|
@ -289,7 +289,7 @@ static void qcom_ep_reset_assert(struct qcom_pcie *pcie)
|
|||
static void qcom_ep_reset_deassert(struct qcom_pcie *pcie)
|
||||
{
|
||||
/* Ensure that PERST has been asserted for at least 100 ms */
|
||||
msleep(100);
|
||||
msleep(PCIE_T_PVPERL_MS);
|
||||
gpiod_set_value_cansleep(pcie->reset, 0);
|
||||
usleep_range(PERST_DELAY_US, PERST_DELAY_US + 500);
|
||||
}
|
||||
|
|
@ -1221,12 +1221,12 @@ static int qcom_pcie_post_init_2_9_0(struct qcom_pcie *pcie)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int qcom_pcie_link_up(struct dw_pcie *pci)
|
||||
static bool qcom_pcie_link_up(struct dw_pcie *pci)
|
||||
{
|
||||
u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
|
||||
u16 val = readw(pci->dbi_base + offset + PCI_EXP_LNKSTA);
|
||||
|
||||
return !!(val & PCI_EXP_LNKSTA_DLLLA);
|
||||
return val & PCI_EXP_LNKSTA_DLLLA;
|
||||
}
|
||||
|
||||
static int qcom_pcie_host_init(struct dw_pcie_rp *pp)
|
||||
|
|
@ -1840,6 +1840,7 @@ static const struct of_device_id qcom_pcie_match[] = {
|
|||
{ .compatible = "qcom,pcie-apq8064", .data = &cfg_2_1_0 },
|
||||
{ .compatible = "qcom,pcie-apq8084", .data = &cfg_1_0_0 },
|
||||
{ .compatible = "qcom,pcie-ipq4019", .data = &cfg_2_4_0 },
|
||||
{ .compatible = "qcom,pcie-ipq5018", .data = &cfg_2_9_0 },
|
||||
{ .compatible = "qcom,pcie-ipq6018", .data = &cfg_2_9_0 },
|
||||
{ .compatible = "qcom,pcie-ipq8064", .data = &cfg_2_1_0 },
|
||||
{ .compatible = "qcom,pcie-ipq8064-v2", .data = &cfg_2_1_0 },
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ struct rcar_gen4_pcie {
|
|||
#define to_rcar_gen4_pcie(_dw) container_of(_dw, struct rcar_gen4_pcie, dw)
|
||||
|
||||
/* Common */
|
||||
static int rcar_gen4_pcie_link_up(struct dw_pcie *dw)
|
||||
static bool rcar_gen4_pcie_link_up(struct dw_pcie *dw)
|
||||
{
|
||||
struct rcar_gen4_pcie *rcar = to_rcar_gen4_pcie(dw);
|
||||
u32 val, mask;
|
||||
|
|
@ -403,6 +403,7 @@ static const struct pci_epc_features rcar_gen4_pcie_epc_features = {
|
|||
.msix_capable = false,
|
||||
.bar[BAR_1] = { .type = BAR_RESERVED, },
|
||||
.bar[BAR_3] = { .type = BAR_RESERVED, },
|
||||
.bar[BAR_4] = { .type = BAR_FIXED, .fixed_size = 256 },
|
||||
.bar[BAR_5] = { .type = BAR_RESERVED, },
|
||||
.align = SZ_1M,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -110,15 +110,12 @@ static void spear13xx_pcie_enable_interrupts(struct spear13xx_pcie *spear13xx_pc
|
|||
MSI_CTRL_INT, &app_reg->int_mask);
|
||||
}
|
||||
|
||||
static int spear13xx_pcie_link_up(struct dw_pcie *pci)
|
||||
static bool spear13xx_pcie_link_up(struct dw_pcie *pci)
|
||||
{
|
||||
struct spear13xx_pcie *spear13xx_pcie = to_spear13xx_pcie(pci);
|
||||
struct pcie_app_reg __iomem *app_reg = spear13xx_pcie->app_base;
|
||||
|
||||
if (readl(&app_reg->app_status_1) & XMLH_LINK_UP)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
return readl(&app_reg->app_status_1) & XMLH_LINK_UP;
|
||||
}
|
||||
|
||||
static int spear13xx_pcie_host_init(struct dw_pcie_rp *pp)
|
||||
|
|
|
|||
|
|
@ -713,7 +713,16 @@ static void init_host_aspm(struct tegra_pcie_dw *pcie)
|
|||
|
||||
static void init_debugfs(struct tegra_pcie_dw *pcie)
|
||||
{
|
||||
debugfs_create_devm_seqfile(pcie->dev, "aspm_state_cnt", pcie->debugfs,
|
||||
struct device *dev = pcie->dev;
|
||||
char *name;
|
||||
|
||||
name = devm_kasprintf(dev, GFP_KERNEL, "%pOFP", dev->of_node);
|
||||
if (!name)
|
||||
return;
|
||||
|
||||
pcie->debugfs = debugfs_create_dir(name, NULL);
|
||||
|
||||
debugfs_create_devm_seqfile(dev, "aspm_state_cnt", pcie->debugfs,
|
||||
aspm_state_cnt);
|
||||
}
|
||||
#else
|
||||
|
|
@ -1027,12 +1036,12 @@ static int tegra_pcie_dw_start_link(struct dw_pcie *pci)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int tegra_pcie_dw_link_up(struct dw_pcie *pci)
|
||||
static bool tegra_pcie_dw_link_up(struct dw_pcie *pci)
|
||||
{
|
||||
struct tegra_pcie_dw *pcie = to_tegra_pcie(pci);
|
||||
u32 val = dw_pcie_readw_dbi(pci, pcie->pcie_cap_base + PCI_EXP_LNKSTA);
|
||||
|
||||
return !!(val & PCI_EXP_LNKSTA_DLLLA);
|
||||
return val & PCI_EXP_LNKSTA_DLLLA;
|
||||
}
|
||||
|
||||
static void tegra_pcie_dw_stop_link(struct dw_pcie *pci)
|
||||
|
|
@ -1634,7 +1643,6 @@ static void tegra_pcie_deinit_controller(struct tegra_pcie_dw *pcie)
|
|||
static int tegra_pcie_config_rp(struct tegra_pcie_dw *pcie)
|
||||
{
|
||||
struct device *dev = pcie->dev;
|
||||
char *name;
|
||||
int ret;
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
|
|
@ -1664,13 +1672,6 @@ static int tegra_pcie_config_rp(struct tegra_pcie_dw *pcie)
|
|||
goto fail_host_init;
|
||||
}
|
||||
|
||||
name = devm_kasprintf(dev, GFP_KERNEL, "%pOFP", dev->of_node);
|
||||
if (!name) {
|
||||
ret = -ENOMEM;
|
||||
goto fail_host_init;
|
||||
}
|
||||
|
||||
pcie->debugfs = debugfs_create_dir(name, NULL);
|
||||
init_debugfs(pcie);
|
||||
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ static int uniphier_pcie_wait_rc(struct uniphier_pcie *pcie)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int uniphier_pcie_link_up(struct dw_pcie *pci)
|
||||
static bool uniphier_pcie_link_up(struct dw_pcie *pci)
|
||||
{
|
||||
struct uniphier_pcie *pcie = to_uniphier_pcie(pci);
|
||||
u32 val, mask;
|
||||
|
|
|
|||
|
|
@ -121,13 +121,13 @@ static u32 visconti_mpu_readl(struct visconti_pcie *pcie, u32 reg)
|
|||
return readl_relaxed(pcie->mpu_base + reg);
|
||||
}
|
||||
|
||||
static int visconti_pcie_link_up(struct dw_pcie *pci)
|
||||
static bool visconti_pcie_link_up(struct dw_pcie *pci)
|
||||
{
|
||||
struct visconti_pcie *pcie = dev_get_drvdata(pci->dev);
|
||||
void __iomem *addr = pcie->ulreg_base;
|
||||
u32 val = readl_relaxed(addr + PCIE_UL_REG_V_PHY_ST_02);
|
||||
|
||||
return !!(val & PCIE_UL_S_L0);
|
||||
return val & PCIE_UL_S_L0;
|
||||
}
|
||||
|
||||
static int visconti_pcie_start_link(struct dw_pcie *pci)
|
||||
|
|
|
|||
|
|
@ -53,18 +53,13 @@ static inline void ls_g4_pcie_pf_writel(struct ls_g4_pcie *pcie,
|
|||
iowrite32(val, pcie->pci.csr_axi_slave_base + PCIE_PF_OFF + off);
|
||||
}
|
||||
|
||||
static int ls_g4_pcie_link_up(struct mobiveil_pcie *pci)
|
||||
static bool ls_g4_pcie_link_up(struct mobiveil_pcie *pci)
|
||||
{
|
||||
struct ls_g4_pcie *pcie = to_ls_g4_pcie(pci);
|
||||
u32 state;
|
||||
|
||||
state = ls_g4_pcie_pf_readl(pcie, PCIE_PF_DBG);
|
||||
state = state & PF_DBG_LTSSM_MASK;
|
||||
|
||||
if (state == PF_DBG_LTSSM_L0)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
return (state & PF_DBG_LTSSM_MASK) == PF_DBG_LTSSM_L0;
|
||||
}
|
||||
|
||||
static void ls_g4_pcie_disable_interrupt(struct ls_g4_pcie *pcie)
|
||||
|
|
@ -174,8 +169,7 @@ static int ls_g4_pcie_interrupt_init(struct mobiveil_pcie *mv_pci)
|
|||
|
||||
static void ls_g4_pcie_reset(struct work_struct *work)
|
||||
{
|
||||
struct delayed_work *dwork = container_of(work, struct delayed_work,
|
||||
work);
|
||||
struct delayed_work *dwork = to_delayed_work(work);
|
||||
struct ls_g4_pcie *pcie = container_of(dwork, struct ls_g4_pcie, dwork);
|
||||
struct mobiveil_pcie *mv_pci = &pcie->pci;
|
||||
u16 ctrl;
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ struct mobiveil_root_port {
|
|||
};
|
||||
|
||||
struct mobiveil_pab_ops {
|
||||
int (*link_up)(struct mobiveil_pcie *pcie);
|
||||
bool (*link_up)(struct mobiveil_pcie *pcie);
|
||||
};
|
||||
|
||||
struct mobiveil_pcie {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Generic PCI host driver common code
|
||||
* Common library for PCI host controller drivers
|
||||
*
|
||||
* Copyright (C) 2014 ARM Limited
|
||||
*
|
||||
|
|
@ -15,6 +15,8 @@
|
|||
#include <linux/pci-ecam.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "pci-host-common.h"
|
||||
|
||||
static void gen_pci_unmap_cfg(void *ptr)
|
||||
{
|
||||
pci_ecam_free((struct pci_config_window *)ptr);
|
||||
|
|
@ -49,23 +51,17 @@ static struct pci_config_window *gen_pci_init(struct device *dev,
|
|||
return cfg;
|
||||
}
|
||||
|
||||
int pci_host_common_probe(struct platform_device *pdev)
|
||||
int pci_host_common_init(struct platform_device *pdev,
|
||||
const struct pci_ecam_ops *ops)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct pci_host_bridge *bridge;
|
||||
struct pci_config_window *cfg;
|
||||
const struct pci_ecam_ops *ops;
|
||||
|
||||
ops = of_device_get_match_data(&pdev->dev);
|
||||
if (!ops)
|
||||
return -ENODEV;
|
||||
|
||||
bridge = devm_pci_alloc_host_bridge(dev, 0);
|
||||
if (!bridge)
|
||||
return -ENOMEM;
|
||||
|
||||
platform_set_drvdata(pdev, bridge);
|
||||
|
||||
of_pci_check_probe_only();
|
||||
|
||||
/* Parse and map our Configuration Space windows */
|
||||
|
|
@ -73,6 +69,8 @@ int pci_host_common_probe(struct platform_device *pdev)
|
|||
if (IS_ERR(cfg))
|
||||
return PTR_ERR(cfg);
|
||||
|
||||
platform_set_drvdata(pdev, bridge);
|
||||
|
||||
bridge->sysdata = cfg;
|
||||
bridge->ops = (struct pci_ops *)&ops->pci_ops;
|
||||
bridge->enable_device = ops->enable_device;
|
||||
|
|
@ -81,6 +79,18 @@ int pci_host_common_probe(struct platform_device *pdev)
|
|||
|
||||
return pci_host_probe(bridge);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_host_common_init);
|
||||
|
||||
int pci_host_common_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct pci_ecam_ops *ops;
|
||||
|
||||
ops = of_device_get_match_data(&pdev->dev);
|
||||
if (!ops)
|
||||
return -ENODEV;
|
||||
|
||||
return pci_host_common_init(pdev, ops);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_host_common_probe);
|
||||
|
||||
void pci_host_common_remove(struct platform_device *pdev)
|
||||
|
|
@ -94,5 +104,5 @@ void pci_host_common_remove(struct platform_device *pdev)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(pci_host_common_remove);
|
||||
|
||||
MODULE_DESCRIPTION("Generic PCI host common driver");
|
||||
MODULE_DESCRIPTION("Common library for PCI host controller drivers");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
|
|
|||
20
drivers/pci/controller/pci-host-common.h
Normal file
20
drivers/pci/controller/pci-host-common.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Common library for PCI host controller drivers
|
||||
*
|
||||
* Copyright (C) 2014 ARM Limited
|
||||
*
|
||||
* Author: Will Deacon <will.deacon@arm.com>
|
||||
*/
|
||||
|
||||
#ifndef _PCI_HOST_COMMON_H
|
||||
#define _PCI_HOST_COMMON_H
|
||||
|
||||
struct pci_ecam_ops;
|
||||
|
||||
int pci_host_common_probe(struct platform_device *pdev);
|
||||
int pci_host_common_init(struct platform_device *pdev,
|
||||
const struct pci_ecam_ops *ops);
|
||||
void pci_host_common_remove(struct platform_device *pdev);
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue