# PCIe
Source: [https://docs.qualcomm.com/doc/80-70014-8/topic/pcie.html](https://docs.qualcomm.com/doc/80-70014-8/topic/pcie.html)
PCIe uses a bidirectional connection and is capable of sending and receiving
information at the same time as shown in the following figure.
Figure : PCIe device connection link
The path between the devices is called a Link. It is made up of one or more transmit
and receive pairs. One pair of the Link is called a Lane. The PCIe device connection
supports two lanes. The number of lanes or the Link width is x2.
The following table lists the types of PCIe connections for devices.
Table : PCIe connections
| PCIe type | Description |
| --- | --- |
| Root complex (RC) | Connects the CPU to the PCIe topology. |
| Switch | Connects more than two ports and acts as a packet router. |
| Bridge | Connects different buses, for example, PCIe to PCIe, or PCIe to peripheral component interconnect (PCI). |
| Endpoint (EP) | Resides at the bottom of the PCIe topology tree structure and has only an upstream port. |
| Legacy endpoint | Uses older PCI bus operations to support backward compatibility. |
### PCIe topology entities
PCIe topology contains the following entities.
- Domain: single PCIe tree with one RC and one or more EPs.
- Bus: a point-to-point (external) or point-to-multipoint (internal)
connection.
- A PCIe domain can contain up to 256 buses.
- The internal bus in the RC is always hardwired as Bus 0.
- An external bus always connects to a downstream port and upstream
port.
- Device: component on either end of a PCIe link. A single PCIe bus can have
up to 32 devices connected to it.
- Function: addressable entity in the configuration space associated with a
single function number. Each device can contain up to eight functions.
The following figure illustrates the topological representation.
Figure : PCIe topology

## PCIe host mode enumeration feature
Source: [https://docs.qualcomm.com/doc/80-70014-8/topic/pcie.html](https://docs.qualcomm.com/doc/80-70014-8/topic/pcie.html)
When a system first powers up, the configuration software running on the system host
processor is only aware of the existence of Bus 0 (if PCIe is supported). The software
is not aware of the bus topology or any device connected to the bus. The enumeration
process discovers the various buses, devices, and functions present in the system.
Enumeration is a lengthy process. The configuration software discovers the presence of
buses, devices, and functions by reading the vendor ID register from all possible
combinations of the bus device function (BDF) number. If a physical device is present
with a specified BDF ID, the device returns a valid vendor ID value (non-0xFFFF). The
configuration software performs a depth-first search (as opposed to a width-first
search).
The enumeration process discovers the presence of all BDFs and numbers each one, as shown
in the following figure.
Figure : Example of PCIe enumeration results

When enumeration is complete, each bus in the system is numbered:
- The primary bus number is the number of the bus that directly connects to the
primary interface of the bridge (towards the RC).
- The secondary bus number is the number of the bus that directly connects to the
secondary interface of the bridge (away from the RC).
- The subordinate bus number is the number of the highest numbered bus that exists
on the downstream side of the bridge.
Each device can be uniquely identified by its BDF number. The ID-based routing method of
the transaction layer packet (TLP) uses this number. The PCIe host mode enumeration
process involves the following:
1. Link training
2. Scanning for devices on the bus
3. Registration
For more information on the PCIe device initialization, enumeration process, seeĀ [https://www.kernel.org/doc/html/latest/PCI/index.html](https://www.kernel.org/doc/html/latest/PCI/index.html).
## PCIe layered architecture
Source: [https://docs.qualcomm.com/doc/80-70014-8/topic/pcie.html](https://docs.qualcomm.com/doc/80-70014-8/topic/pcie.html)
The following figure shows the layered architecture model of PCIe.
Figure : PCIe layered architecture

The transmission units exchanged are as follows.
- Ordered set between the physical layer entities.
- Data link layer packet (DLLP) between data link layer entities.
- Transaction layer packet (TLP) between transaction layer entities.
The following table lists the three layers, with the respective functions, in the PCIe
architecture.
| Layer | Features |
| --- | --- |
| Physical layer | Logical sub-block: Link training, initialization, and maintenance. |
| Physical layer | Physical sub-block: 8b/10b encoding and decoding, and parallel-to-serial and serial-to-parallel conversion. |
| Data link layer | Assembly and disassembly of the DLLP packet. |
| Data link layer | Generation and validation of the link layer CRC (LCRC). |
| Data link layer | Acknowledgment and no acknowledgment protocol (replay of TLPs in error). |
| Transaction layer | Assembly and disassembly of the TLP packet. |
| Transaction layer | Generation and validation of end-to-end CRC (ECRC). |
| Transaction layer | Flow control receives entity advertises for the available to receive buffer size information using DLLPs. |
| Transaction layer | Quality of service (QoS): traffic class (TC)-to-virtual channel (VC) mapping. |
| Transaction layer | Transaction ordering: implements the transaction ordering rule within a VC. |
| | |
| | |
| | |
| | |
### PCIe TLP requests
The PCIe TLP request types address the following four spaces:
- Memory
- Transfers data to or from a location in the system memory map.
- Supports a locked memory read transaction (the Qualcomm implementation
does not support the locked memory read transaction).
- I/O
- Transfers data to or from a location in the system I/O map.
- Supports only legacy devices.
- Configuration
- Transfers data to or from a location in the configuration space of a
PCIe device.
- Discovers device capabilities.
- Programs the plug-and-play feature.
- Checks the status (done by the host).
- Message: Provides an in-band messaging and event reporting mechanism without
consuming either memory or I/O address resources.
Each request type has either one of these characteristics:
- Posted: The targeted device does not return a completion TLP to the requester.
The posted transaction improves performance but provides no feedback on
transaction success or failure.
- Nonposted: The requester sends a packet for which the targeted device generates
a response in the form of a completion TLP.
The posting statuses for the request types are listed in the following table.
Table : PCIe TLP request categories
| Request category | Nonposted or posted |
| --- | :---: |
| Memory read | Nonposted |
| Memory write | Posted |
| Memory read lock | Nonposted |
| I/O read | Nonposted |
| I/O write | Nonposted |
| Configuration read (Type 0 and Type 1) | Nonposted |
| Configuration write (Type 0 and Type 1) | Nonposted |
| Message | Posted |
### PCIe TLP routing and addressing rules
There are three principal mechanisms for TLP routing:
- Address routing
- Used with memory and I/O requests.
- Uses only the 64ābit and 32ābit address formats (I/O requests use only
the 32ābit format).
- ID routing
- Used with configuration requests, ID routed messages, and
completions.
- Uses the bus, device, and function (BDF) numbers to specify the
destination for the TLP.
- Implicit routing ā Special messages are defined to convey related information
(power management, interrupt handling, error handling, and so on) between the RC
and EPs.
### PCIe configuration address space
PCI defines a dedicated block of configuration address space for each function. The
software determines the presence of a function, configures it, and checks and
controls its status.
A PCIe configuration space contains the following zones:
- The first 16 DWORDs, 0x0000 to 0x003F, contain the PCI configuration
header.
- The next 48 DWORDs, 0x0040 to 0x00FF, contain the PCI device-specific and new
capability register sets.
- The next 960 DWORDs, 0x0100 to 0x0FFF, contain the PCIe extended configuration
space.
The first two zones are identical to the PCI configuration space, which makes the
PCIe software configuration process compatible with the PCI configuration
process.
Figure : PCIe-compatible configuration address space

The following types of PCI configuration space header are defined as:
- Type 0 header: Used by nonbridge devices, such as EP devices.
- Type 1 header: Used by switch and bridge devices.
The configuration header format information (Type 0 or Type 1) is encoded in the
header type register.
## PCIe software
Source: [https://docs.qualcomm.com/doc/80-70014-8/topic/pcie.html](https://docs.qualcomm.com/doc/80-70014-8/topic/pcie.html)
The PCIe controller driver initializes the PCIe resources and performs link training.
After successful training, the controller driver calls the PCIe framework for link
enumeration, such as endpoint discovery, identifying the client driver, and probing
those drivers. For more details on the PCIe framework and client driver PCIe
registrations, seeĀ [https://www.kernel.org/doc/html/latest/PCI/index.html](https://www.kernel.org/doc/html/latest/PCI/index.html).
### Link training
Following are the steps to perform link training.
1. The PCIe platform driver `pcie-qcom.c` file atĀ [https://github.com/torvalds/linux/blob/master/drivers/pci/controller/dwc/pcie-qcom.c](https://github.com/torvalds/linux/blob/master/drivers/pci/controller/dwc/pcie-qcom.c) obtains the required resources like
regulators, clocks, from the device tree.
2. The PCIe driver calls Synopsys DesignWareĀ® Core host driverĀ pcie-designware-host.c file atĀ [https://github.com/torvalds/linux/blob/master/drivers/pci/controller/dwc/pcie-designware-host.c](https://github.com/torvalds/linux/blob/master/drivers/pci/controller/dwc/pcie-designware-host.c) to initialize the root complex.
3. The Synopsys DesignWare Core driver performs all necessary
initializations.
4. The Synopsys DesignWare Core driver calls a function pointer to perform host
initialization.
5. The Qualcomm PCIe driver performs PHY power-on, enables all regulators,
clocks, and so on.
6. The Synopsys DesignWare Core driver starts the link training by calling the
function pointer to start the link.
### Hardware initialization
The driver initializes and configures the PCIe hardware block and performs link
training. The initialization occurs only once after the `platform
_probe()` driver function is
called.
static int qcom_pcie_probe(struct platform_device *pdev)
{
// get PCIe resources
ret = dw_pcie_host_init(pp); // call DWC framework to host intialisation like MSI, MSIx and controller init
if (ret) {
dev_err(dev, "cannot initialize host\n");
goto err_phy_exit;
}
};
static const struct of_device_id qcom_pcie_match[] = {
{ .compatible = "qcom,pcie-sc7280", .data = &cfg_1_9_0 },
{}
};
static struct platform_driver qcom_pcie_driver = {
.probe = qcom_pcie_probe,
.driver = {
.name = "qcom-pcie",
.suppress_bind_attrs = true,
.of_match_table = qcom_pcie_match,
},
};Copy to clipboard
When the Synopsys DesignWare Core driver is initialized, it also initializes MSI,
MSIx, and controllers. The driver calls a Qualcomm function pointer to start the
link training.
static int qcom_pcie_start_link(struct dw_pcie *pci)
{
struct qcom_pcie *pcie = to_qcom_pcie(pci);
/* Enable Link Training state machine */
if (pcie->cfg->ops->ltssm_enable)
pcie->cfg->ops->ltssm_enable(pcie);
return 0;
}
static int 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); // checks the link is up or not
}
static const struct dw_pcie_ops dw_pcie_ops = {
.link_up = qcom_pcie_link_up,
.start_link = qcom_pcie_start_link,
};Copy to clipboard
The Synopsys DesignWare Core driver waits for the link to be up. If the link is up,
then Synopsys DesignWare Core driver calls the PCI framework to do enumeration. The
Qualcomm PCIe driver enables only the link training.
Note: The PCIE\_0 root complex instance is enabled by default for
the WLAN EP connection.
## PCIe software support for QPS615 switch
Source: [https://docs.qualcomm.com/doc/80-70014-8/topic/pcie.html](https://docs.qualcomm.com/doc/80-70014-8/topic/pcie.html)
This section describes how to enable a QPS615 PCIe switch in the Qualcomm Linux chip
products. The QPS615 switch endpoint is supported on the `PCIe1`
instance. The following figure illustrates the QPS615 endpoint and connections in the
Qualcomm Linux chip products.
Figure : QPS615 PCIe switch connection diagram

The Qualcomm PCIe driver documentation can be accessed at the following locationĀ [https://github.com/torvalds/linux/blob/master/Documentation/devicetree/bindings/phy/qcom%2Csc8280xp-qmp-pcie-phy.yaml](https://github.com/torvalds/linux/blob/master/Documentation/devicetree/bindings/phy/qcom%2Csc8280xp-qmp-pcie-phy.yaml).
### PCIe-related configurations
The following configurations are enabled by default to support the QPS615 switch.
Disable the QPS615 switch default support, by reverting the code changes, to use it
for a different PCIe endpoint.
To enable PCIe-related `configs`, apply the following patch to theĀ /arch/arm64/configs/qcom\_addons.config
file.
QCLINUX: arm64: defconfig: qcom:
diff --git a/arch/arm64/configs/qcom_addons.config b/arch/arm64/configs/qcom_addons.config
index 46555f9..a83f417 100644
--- a/arch/arm64/configs/qcom_addons.config
+++ b/arch/arm64/configs/qcom_addons.config
@@ -25,3 +25,4 @@
CONFIG_VIRT_DRIVERS=y
CONFIG_QCOM_SMP2P_SLEEPSTATE=m
CONFIG_QCOM_SOC_DEBUG=y
+CONFIG_QCOM_QPS615_PCIE_SWITCH=y
diff --git a/arch/arm64/configs/qcom_defconfig b/arch/arm64/configs/qcom_defconfig
index 7293680..730122c 100644
--- a/arch/arm64/configs/qcom_defconfig
+++ b/arch/arm64/configs/qcom_defconfig
@@ -173,6 +173,7 @@
CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_ACPI=y
CONFIG_PCI_HOST_GENERIC=y
+CONFIG_PCIE_DW_PLAT_HOST=y
CONFIG_PCIE_QCOM=y
CONFIG_PCI_ENDPOINT=y
CONFIG_PCI_ENDPOINT_CONFIGFS=y
@@ -793,3 +794,5 @@
CONFIG_CORESIGHT_TPDM=m
CONFIG_CORESIGHT_DUMMY=m
CONFIG_MEMTEST=y
+CONFIG_PCIEASPM=y
+CONFIG_PCIEASPM_POWER_SUPERSAVE=y
Copy to clipboard
### Always-on refclk signal to endpoint
In PCIe low-power states such as L1.1 or L1.2, the PHY stops supplying
`refclk` to the endpoint. If the endpoint asserts
`clkreq` to bring back the link to L0, then root complex must
provide `refclk` to the endpoint. Some platforms with PCIe QPS615
switches fail to drive the `clkreq` signal to the host from the
endpoints due to the switch board design. The `refclk` signal must be
supplied to the endpoint. Therefore, add a flag to keep `refclk`
always supplied to the endpoint.
To retain `refclk` in always-on status, apply the following patch to
theĀ phy-qcom-qmp-pcie.c file atĀ [https://github.com/torvalds/linux/blob/master/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c](https://github.com/torvalds/linux/blob/master/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c).
phy: qcom-qmp-pcie:
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -43,6 +43,8 @@
/* QPHY_PCS_STATUS bit */
#define PHYSTATUS BIT(6)
#define PHYSTATUS_4_20 BIT(7)
+/* PCS_PCIE_ENDPOINT_REFCLK_CNTRL */
+#define EPCLK_ALWAYS_ON_EN BIT(6)
#define PHY_INIT_COMPLETE_TIMEOUT 10000
@@ -2293,6 +2295,8 @@
struct phy *phy;
int mode;
+ bool refclk_always_on;
+
struct clk_fixed_rate pipe_clk_fixed;
};
@@ -3238,6 +3242,10 @@
qmp_pcie_configure(pcs, tbls->pcs, tbls->pcs_num);
qmp_pcie_configure(pcs_misc, tbls->pcs_misc, tbls->pcs_misc_num);
+ if (qmp->refclk_always_on && cfg->regs[QPHY_PCS_ENDPOINT_REFCLK_CNTRL])
+ qphy_setbits(pcs_misc, cfg->regs[QPHY_PCS_ENDPOINT_REFCLK_CNTRL],
+ EPCLK_ALWAYS_ON_EN);
+
if (cfg->lanes >= 4 && qmp->tcsr_4ln_config) {
qmp_pcie_configure(serdes, cfg->serdes_4ln_tbl, cfg->serdes_4ln_num);
qmp_pcie_init_port_b(qmp, tbls);
@@ -3760,6 +3768,12 @@
if (ret)
goto err_node_put;
+ qmp->refclk_always_on = of_property_read_bool(dev->of_node, "qcom,refclk-always-on");
+ if (qmp->refclk_always_on && !qmp->cfg->regs[QPHY_PCS_ENDPOINT_REFCLK_CNTRL]) {
+ dev_err(dev, "refclk is always on is present but refclk cntrl offset is not present\n");
+ goto err_node_put;
+ }
+
ret = phy_pipe_clk_register(qmp, np);
if (ret)
goto err_node_put;
Copy to clipboard
### Additional MSI interrupts
The current MSI mapping does not have all the vectors. The Qualcomm Linux chip
products support eight vectors. Each vector in turn supports 32 MSIs. Therefore, the
total MSIs supported are 256.
For information about adding all the MSI groups supported for this PCIe instance,
seeĀ [https://lore.kernel.org/linux-arm-msm/f1168212-bc6e-4570-869c-2870d6f248ad@linaro.org/T/](https://lore.kernel.org/linux-arm-msm/f1168212-bc6e-4570-869c-2870d6f248ad@linaro.org/T/).
### QPS615 switch support
When all the GPIOs that control power to the QPS615 PCIe switch are added as fixed
regulators, the QPS615 driver enables the power through the regulator framework. It
also performs I2C writes to configure the QPS615 switch. The PCIe node is added as a
dependency to the QPS615 node so that the PCIe driver probes after the QPS615 driver
probe, which ensures that the switch is powered and ready for enumeration. When
QPS615 cannot toggle, the CLKREQ pin causes a device crash. This is a known
limitation. Hence, the `refclk` is set to always-on.
### QPS615 switch device tree bindings
To add QPS615 switch device tree binding, apply the following patch to theĀ /arch/arm64/boot/dts/qcom/<chipset>-addons-rb3.dts
file.
QCLINUX: dt-bindings: pci: qps615:
diff --git a/arch/arm64/boot/dts/qcom/-addons-rb3.dts b/arch/arm64/boot/dts/qcom/-addons-rb3.dts
index 109ad08..7baf505 100644
--- a/arch/arm64/boot/dts/qcom/-addons-rb3.dts
+++ b/arch/arm64/boot/dts/qcom/-addons-rb3.dts
@@ -14,6 +14,82 @@
/ {
model = "Qualcomm Technologies, Inc. -addons RB3 platform";
compatible = "qcom,-addons-rb3","qcom,sc7280";
+
+ qps615_0p9_vreg: qps615-0p9-vreg {
+ compatible = "regulator-fixed";
+ regulator-name = "qps615_0p9_vreg";
+ gpio = <&pm8350c_gpios 2 0>;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ enable-active-high;
+ regulator-enable-ramp-delay = <4300>;
+ };
+
+ qps615_1p8_vreg: qps615-1p8-vreg {
+ compatible = "regulator-fixed";
+ regulator-name = "qps615_1p8_vreg";
+ gpio = <&pm8350c_gpios 3 0>;
+ vin-supply = <&qps615_0p9_vreg>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ enable-active-high;
+ regulator-enable-ramp-delay = <10000>;
+ };
+
+ qps615_rsex_vreg: qps615-rsex-vreg {
+ compatible = "regulator-fixed";
+ regulator-name = "qps615_rsex_vreg";
+ gpio = <&pm8350c_gpios 1 0>;
+ vin-supply = <&qps615_1p8_vreg>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ enable-active-high;
+ regulator-enable-ramp-delay = <10000>;
+ };
+
+ usb_hub_1p05_vreg: usb-hub-1p05-vreg {
+ compatible = "regulator-fixed";
+ regulator-name = "usb_hub_1p05_vreg";
+ gpio = <&pm7250b_gpios 4 0>;
+ vin-supply = <&qps615_rsex_vreg>;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ enable-active-high;
+ regulator-enable-ramp-delay = <5000>;
+ };
+
+ usb_hub_3p3_vreg: usb-hub-3p3-vreg {
+ compatible = "regulator-fixed";
+ regulator-name = "usb_hub_3p3_vreg";
+ gpio = <&pm7250b_gpios 1 0>;
+ vin-supply = <&usb_hub_1p05_vreg>;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ regulator-enable-ramp-delay = <10000>;
+ };
+
+ usb_hub_rest_vreg: usb-hub-rest-vreg {
+ compatible = "regulator-fixed";
+ regulator-name = "usb_hub_rest_vreg";
+ gpio = <&pm8350c_gpios 4 0>;
+ vin-supply = <&usb_hub_3p3_vreg>;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ };
+};
+
+&i2c0 {
+ clock-frequency = <100000>;
+ status = "okay";
+
+ qps615_switch: pcie-switch@77 {
+ compatible = "qcom,switch-i2c";
+ reg = <0x77>;
+ vdda-supply = <&usb_hub_rest_vreg>;
+ status = "okay";
+ };
};
&i2c1 {
@@ -216,6 +292,14 @@
};
};
+&pcie1 {
+ dummy-supply = <&qps615_switch>;
+};
+
+&pcie1_phy {
+ qcom,refclk-always-on;
+};
+
&pm8350c_gpios {
pm8008i-reset-state {
pm8008i_active: pm8008i-active-pins {
Documentation/devicetree/bindings/pci/qps615-switch.yaml Documentation/devicetree/bindings/pci/qps615-switch.yaml
new file mode 100644
index 0000000..f59e068
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/qps615-switch.yaml
@@ -0,0 +1,41 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/qps615-switch.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Technologies, Inc. (QTI) PCIe switch
+
+maintainers:
+ - Chundru Krishna chaitanya
+
+properties:
+ compatible:
+ enum:
+ - qcom,switch-i2c
+
+ reg:
+ maxItems: 1
+
+ vdda-supply:
+ description: A phandle to the core analog power supply
+
+required:
+ - compatible
+ - reg
+ - vdda-supply
+
+additionalProperties: false
+
+examples:
+ - |
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ qps615: pcie-switch@77 {
+ compatible = "qcom,switch-i2c";
+ reg = <0x077>;
+ vdda-supply = <&foo>;
+ };
Copy to clipboard
### QPS615 switch driver
A driver is added for powering on QPS615 PCIe switch. It performs the basic
initialization through I2C. The initialization sequence is present in the firmware
image that the driver requested through the request\_firmware
API.
To add the QPS615 switch driver, apply the following patch to theĀ /drivers/pci/controller/Kconfig
file.
QCLINUX: pci: controller: misc:
diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index c0c3f28..d68e701 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -345,4 +345,5 @@
source "drivers/pci/controller/cadence/Kconfig"
source "drivers/pci/controller/dwc/Kconfig"
source "drivers/pci/controller/mobiveil/Kconfig"
+source "drivers/pci/controller/misc/Kconfig"
endmenu
diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
index 37c8663..015f711b 100644
--- a/drivers/pci/controller/Makefile
+++ b/drivers/pci/controller/Makefile
@@ -43,6 +43,7 @@
# pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW
obj-y += dwc/
obj-y += mobiveil/
+obj-y += misc/
# The following drivers are for devices that use the generic ACPI
diff --git a/drivers/pci/controller/misc/Kconfig b/drivers/pci/controller/misc/Kconfig
new file mode 100644
index 0000000..0acea3f
--- /dev/null
+++ b/drivers/pci/controller/misc/Kconfig
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0
+config QCOM_QPS615_PCIE_SWITCH
+ bool "QCOM QPS615 PCIe Switch Driver"
+ depends on PCuart
+ help
+ This adds support to enable QPS615 PCIe switch power. And after powering on the switch do
+ switch initialization through I2C writes. The I2C data is parsed from the requested
+ firmware.
+
+ Say Y to compile this driver.
diff --git a/drivers/pci/controller/misc/Makefile b/drivers/pci/controller/misc/Makefile
new file mode 100644
index 0000000..1c2b99e
--- /dev/null
+++ b/drivers/pci/controller/misc/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_QCOM_QPS615_PCIE_SWITCH) += qps615.o
Change in arm64: dts: qcom: -rb3g2: Add PCIe nodes.
Enable PCIe1 controller and its corresponding PHY nodes on
-rb3g2 platform. As there are multiple endpoints connected through PCIe switch add smmu id for each BDF.
diff --git a/arch/arm64/boot/dts/qcom/-rb3.dts b/arch/arm64/boot/dts/qcom/-rb3.dts
index 5adce1f..f995a53 100644
--- a/arch/arm64/boot/dts/qcom/-rb3.dts
+++ b/arch/arm64/boot/dts/qcom/-rb3.dts
@@ -512,6 +512,32 @@
bias-bus-hold;
};
+&pcie1 {
+ perst-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>;
+
+ pinctrl-0 = <&pcie1_reset_n>, <&pcie1_wake_n>;
+ pinctrl-names = "default";
+
+ iommu-map = <0x0 &apps_smmu 0x1c80 0x1>,
+ <0x100 &apps_smmu 0x1c81 0x1>,
+ <0x208 &apps_smmu 0x1c84 0x1>,
+ <0x210 &apps_smmu 0x1c85 0x1>,
+ <0x218 &apps_smmu 0x1c86 0x1>,
+ <0x300 &apps_smmu 0x1c87 0x1>,
+ <0x400 &apps_smmu 0x1c88 0x1>,
+ <0x500 &apps_smmu 0x1c89 0x1>,
+ <0x501 &apps_smmu 0x1c90 0x1>;
+
+ status = "okay";
+};
+
+&pcie1_phy {
+ vdda-phy-supply = <&vreg_l10c_0p88>;
+ vdda-pll-supply = <&vreg_l6b_1p2>;
+
+ status = "okay";
+};
+
&qup_uart5_rx {
drive-strength = <2>;
bias-pull-up;
@@ -604,6 +630,21 @@
bias-disable;
};
+ pcie1_reset_n: pcie1-reset-n-state {
+ pins = "gpio2";
+ function = "gpio";
+ drive-strength = <16>;
+ output-low;
+ bias-disable;
+ };
+
+ pcie1_wake_n: pcie1-wake-n-state {
+ pins = "gpio3";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
qup_uart7_sleep_cts: qup-uart7-sleep-cts-state {
pins = "gpio28";
function = "gpio";
Copy to clipboard
PCIe kernel driver logs for QPS615 device enumeration
reference:
[ 7.254674] qcom-pcie 1c08000.pci: supply vdda not found, using dummy regulator
[ 7.285224] qcom-pcie 1c08000.pci: supply vddpe-3v3 not found, using dummy regulator
[ 7.299688] qcom-pcie 1c08000.pci: host bridge /soc@0/pci@1c08000 ranges:
[ 7.313713] qcom-pcie 1c08000.pci: IO 0x0040200000..0x00402fffff -> 0x0000000000
[ 7.329778] qcom-pcie 1c08000.pci: MEM 0x0040300000..0x005fffffff -> 0x0040300000
[ 7.479174] qcom-pcie 1c08000.pci: iATU: unroll T, 8 ob, 8 ib, align 4K, limit 1024G
[ 7.577792] qcom-pcie 1c08000.pci: PCIe Gen.3 x2 link up
[ 7.648353] qcom-pcie 1c08000.pci: PCI host bridge to bus 0001:00
[ 7.654618] pci_bus 0001:00: root bus resource [bus 00-ff]
[ 7.654620] pci_bus 0001:00: root bus resource [io 0x0000-0xfffff]
[ 7.654622] pci_bus 0001:00: root bus resource [mem 0x40300000-0x5fffffff]
[ 7.654633] pci 0001:00:00.0: [17cb:010b] type 01 class 0x060400
[ 7.665893] pci 0001:00:00.0: reg 0x10: [mem 0x00000000-0x00000fff]
[ 7.684913] pci 0001:00:00.0: PME# supported from D0 D3hot D3cold
[ 7.700502] pci 0001:01:00.0: [1179:0623] type 01 class 0x060400
[ 7.710817] pci 0001:01:00.0: PME# supported from D0 D3hot D3cold
[ 7.733698] pci 0001:01:00.0: bridge configuration invalid ([bus 00-00]), reconfiguring
[ 7.738818] pci 0001:02:01.0: [1179:0623] type 01 class 0x060400
[ 7.751157] pci 0001:02:01.0: PME# supported from D0 D3hot D3cold
[ 7.763174] pci 0001:02:02.0: [1179:0623] type 01 class 0x060400
[ 7.777084] pci 0001:02:02.0: PME# supported from D0 D3hot D3cold
[ 7.792832] pci 0001:02:03.0: [1179:0623] type 01 class 0x060400
[ 7.815659] pci 0001:02:03.0: PME# supported from D0 D3hot D3cold
Copy to clipboard
## PCIe software support for USB
Source: [https://docs.qualcomm.com/doc/80-70014-8/topic/pcie.html](https://docs.qualcomm.com/doc/80-70014-8/topic/pcie.html)
This section provides instructions on how to activate a USB interface via a PCIe switch
in the Qualcomm Linux chip products. The PCIE1 instance is linked to the endpoint of the
QPS615 switch, and the downstream port of the QPS615 is connected to the PCIe to USB
endpoint. The following figure illustrates the PCIe to USB endpoint connections using
the QPS615 in the Qualcomm Linux chip products.
Figure : Qualcomm Robotics RB3 Gen 2 functional block diagram

### Enable power for the PCIe to USB controller
Enable the power for the PCIe to USB controller that is linked via the QPS615 switch,
and reset the external USB hub connected through GPIO162. This is necessary for the
correct detection and functioning of the USB peripherals.
diff --git a/arch/arm64/boot/dts/qcom/qcs6490-addons-rb3gen2.dtsi b/arch/arm64/boot/dts/qcom/qcs6490-addons-rb3gen2.dtsi
index bf95b66..4a76a36 100644
--- a/arch/arm64/boot/dts/qcom/qcs6490-addons-rb3gen2.dtsi
+++ b/arch/arm64/boot/dts/qcom/qcs6490-addons-rb3gen2.dtsi
@@ -40,6 +40,37 @@
regulator-enable-ramp-delay = <10000>;
};
+ upd_3p3_vreg: upd_3p3_vreg {
+ compatible = "regulator-fixed";
+ regulator-name = "upd_3p3_vreg";
+ gpio = <&pm7250b_gpios 1 0>;
+ vin-supply = <&qps615_rsex_vreg>;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ regulator-enable-ramp-delay = <10000>;
+ regulator-always-on;
+ };
+
+ upd_rest_vreg: upd_rest_vreg {
+ compatible = "regulator-fixed";
+ regulator-name = "upd_rest_vreg";
+ gpio = <&pm8350c_gpios 4 0>;
+ vin-supply = <&upd_3p3_vreg>;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ regulator-always-on;
+ };
+
+ usbhub_rest_vreg: usbhub_rest_vreg {
+ compatible = "regulator-fixed";
+ regulator-name = "usbhub_rest_vreg";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie1_usb_hub_reset_default>;
+ gpio = <&tlmm 162 GPIO_ACTIVE_LOW>;
+ enable-active-high;
+ };
};
&i2c0 {
@@ -165,6 +196,14 @@
bias-pull-down;
input-enable;
};
+
+ pcie1_usb_hub_reset_default: pcie1_usb_hub_reset_default {
+ pins = "gpio162";
+ function = "gpio";
+ drive-strength = <2>;
+ output-high;
+ bias-pull-down;
+ };
};
Copy to clipboard
### Avoid early handoff in PCIe to USB controller
Ensure that `usb_early-handoff` is skipped for the PCIe to USB
controller since the firmware is not loaded. This is necessary to prevent any
adverse impact on the bootup duration.
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index 2665832..c3d488f 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -1260,6 +1260,11 @@
return;
}
+ /* Skip handoff for Renesas PCI USB controller on QCOM SOC */
+ if ((pdev->vendor == PCI_VENDOR_ID_RENESAS) &&
+ (pcie_find_root_port(pdev)->vendor == PCI_VENDOR_ID_QCOM))
+ return;
+
if (pdev->class != PCI_CLASS_SERIAL_USB_UHCI &&
pdev->class != PCI_CLASS_SERIAL_USB_OHCI &&
pdev->class != PCI_CLASS_SERIAL_USB_EHCI &&
Copy to clipboard
### Save and restore configuration space QPS615 switch
Preserve the configuration space of the PCIe bridge device during power management
suspend state. Resume the PCIe bridge configuration space during power management
resume state. This is essential for the proper operation of PCIe endpoints connected
via the QPS615 PCIe switch.
diff --git a/drivers/pci/controller/misc/qps615.c b/drivers/pci/controller/misc/qps615.c
index 7d63efb..10048cd 100644
--- a/drivers/pci/controller/misc/qps615.c
+++ b/drivers/pci/controller/misc/qps615.c
@@ -5,6 +5,7 @@
#include
#include
#include
+#include
#define DRV_NAME "qps615-switch-i2c"
@@ -235,6 +236,24 @@
}
module_init(qps615_i2c_init);
+static void qcom_pcie_resume_early(struct pci_dev *pdev)
+{
+ pci_restore_state(pdev);
+}
+
+DECLARE_PCI_FIXUP_CLASS_RESUME_EARLY(PCI_ANY_ID,
+ PCI_ANY_ID, PCI_CLASS_BRIDGE_PCI_NORMAL, 0,
+ qcom_pcie_resume_early);
+
+static void qcom_pcie_suspend_late(struct pci_dev *pdev)
+{
+ pci_save_state(pdev);
+}
+
+DECLARE_PCI_FIXUP_CLASS_SUSPEND_LATE(PCI_ANY_ID,
+ PCI_ANY_ID, PCI_CLASS_BRIDGE_PCI_NORMAL, 0,
+ qcom_pcie_suspend_late);
+
MODULE_AUTHOR("Krishna Chaitanya Chundru ");
MODULE_DESCRIPTION("QPS615 PCIE Switch driver");
MODULE_LICENSE("GPL");
Copy to clipboard
### Download PCIe to USB controller firmware
To download the firmware fromĀ [https://www.renesas.com/us/en/products/interface/usb-switches-hubs/upd720201-usb-30-host-controller#design_development](https://www.renesas.com/us/en/products/interface/usb-switches-hubs/upd720201-usb-30-host-controller#design_development), register and log in toĀ [https://www.renesas.com/](https://www.renesas.com/).
Note: Ensure that the updated firmware at
`/lib/firmware` is named `renesas_usb_fw.mem`. The
driver will only read the firmware based on this specific filename.
Transfer files using SCP or similar tools insideĀ /lib/firmware.
Example:
scp renesas_usb.mem root@: /lib/firmware Copy to clipboard
Note: Restart the device after the firmware has been flashed.
During the subsequent boot up, the driver reads this firmware and activates the
PCI to USB controller.
### PCIe kernel driver logs for PCIe to USB device enumeration reference
[ 6.589462] usbcore: registered new device driver onboard-usb-hub
[ 6.653277] usb 2-1: new SuperSpeed USB device number 2 using xhci_hcd
[ 7.013061] usb 2-1.1: new SuperSpeed USB device number 3 using xhci_hcd
[ 7.120657] ax88179_178a 2-1.1:1.0 eth0: register 'ax88179_178a' at usb-0001:04:00.0-1.1, ASIX AX88179 USB 3.0 Gigabit Ethernet, 3e:9e:5e:ff:d3:fb
[ 7.120767] usbcore: registered new interface driver ax88179_178a
Copy to clipboard
**USB**: Display device
information.
lsusbCopy to clipboard
The following message is
displayed.
Bus 002 Device 003: ID 0b95:1790 ASIX Electronics Corp. AX88179 Gigabit Ethernet
Bus 002 Device 002: ID 05e3:0625 Genesys Logic, Inc. USB3.2 Hub
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 002: ID 05e3:0610 Genesys Logic, Inc. Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Copy to clipboard
**PCIe**: Display device
information.
lspciCopy to clipboard
The following message is
displayed.
0001:00:00.0 PCI bridge: Qualcomm Device 010b
0001:01:00.0 PCI bridge: Toshiba Corporation Device 0623
0001:02:01.0 PCI bridge: Toshiba Corporation Device 0623
0001:02:02.0 PCI bridge: Toshiba Corporation Device 0623
0001:02:03.0 PCI bridge: Toshiba Corporation Device 0623
0001:04:00.0 USB controller: Renesas Technology Corp. uPD720201 USB 3.0 Host Controller (rev 03)
0001:05:00.0 Ethernet controller: Toshiba Corporation Device 0220
0001:05:00.1 Ethernet controller: Toshiba Corporation Device 0220
Copy to clipboard
## PCIe sample client driver reference
Source: [https://docs.qualcomm.com/doc/80-70014-8/topic/pcie.html](https://docs.qualcomm.com/doc/80-70014-8/topic/pcie.html)
The client driver defines the `device-id` table and
`pci_driver` structures, and registers with the PCIe framework.
/*
* Sample data structure which hold client specific private data.
* you can have your client driver specific data in this structure.
*/
struct sample_driver_data {
int driver_data;
};
/*
* Since its sample driver, we are not supplying any valid data.
* You can supply valid data for your driver specific data structure which was defined above
*/
struct sample_driver_data info = {};
/*
* Prepare the device id table. And supply the driver specific data along with device-id.
* Here sample client driver is interested in the (acts as PCIe endpoint) whose device id is 0x306.
*/
static const struct pci_device_id sample_pci_id_table[] = {
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0306, PCI_VENDOR_ID_QCOM, 0x010c),
.driver_data = (kernel_ulong_t) &info },
{ } /* This is must */
};
MODULE_DEVICE_TABLE(pci, sample_pci_id_table); /* This statement is must */
/*
* Prepare the pci_driver data structure with client driver name, pci-id table and with other needed callbacks.
* Pointer to this structure would be passed while registering with PCI frame work.
*/
static struct pci_driver sample_pci_driver = {
.name = "Sample-PCI-Client-driver", /* Give the name that suites your driver description */
.id_table = sample_pci_id_table, /* pci core driver will compare from ids's supplied in this table with the enumerated endpoints */
.probe = sample_pci_probe, /* probe function is invoked by the PCI f/w when id matches with the endpoint id's */
.remove = sample_pci_remove, /* Remove function is invoked by PCI f/w when senses the attached endpoint/function is detached or down */
.driver.pm = &sample_pci_pm_ops /* pm ops that will be called from the pci core driver*/
};
/*
* Ideally we should calling pci_register_driver(&sample_pci_driver) to register with PCI f/w.
* You can do the same from module_init() if your driver is a module.
* But we already have pre-defined macros, which does the same. So we are making use of that
*/
module_pci_driver(sample_pci_driver);Copy to clipboard
## PCIe bringup
Source: [https://docs.qualcomm.com/doc/80-70014-8/topic/pcie.html](https://docs.qualcomm.com/doc/80-70014-8/topic/pcie.html)
For information on PCIe bringup, seeĀ [PCIe-related configurations](https://docs.qualcomm.com/doc/80-70014-8/topic/pcie.html#pcie-software-support-feature-for-qps615__section_xbl_hhd_l1c) andĀ [QPS615 switch support](https://docs.qualcomm.com/doc/80-70014-8/topic/pcie.html#pcie-software-support-feature-for-qps615__section_nmw_5jd_l1c).
## PCIe power optimization
Source: [https://docs.qualcomm.com/doc/80-70014-8/topic/pcie.html](https://docs.qualcomm.com/doc/80-70014-8/topic/pcie.html)
PCIe defines two types of power management methods.
- Power management software that determines the power management capability of
each device and manages each device individually
- System that does not require software intervention such as active state power
management (ASPM)
During a time period when no packet is transmitted over the link, a device places the
link into a power-saving state.
### PCIe L0 link states
PCIe power management defines the following L0 link states:
- L0: active state where all PCIe transactions and other operations are
enabled
- L0s: ASPM state with low-resume latency (energy saving standby state)
### PCIe device states
PCIe power management defines the following
device states:
- D0 (mandatory): The device is in full ON state, where there are two
substates
- D0uninitialized: The function is present in the
D0uninitialized state after the device comes out of
reset, waiting to be enumerated and configured
- D0active
- The function is present in the D0active state
following the completion of the enumeration and configuration
process
- The function enters the D0active state when the
system software enables one or more (in any combination)
function parameters, such as memory Space enable, I/O Space
enable, or bus master enable (BME) bits
- D1 (optional): light-sleep state
- The function cannot initiate a TLP except for the PME message
- The function cannot act as the target of transactions other than for
configuration transactions
- The function issues a software command to enter the D1 state by
programming the PM control and status register
- D2 (optional): deep-sleep state
- The function cannot initiate a TLP except for the PME message
- The function cannot act as the target of transactions other than
configuration transactions
- The function issues a software command to enter the D2 state by
programming the PM control and status register
- D3 (mandatory): device is the lowest power state, where the function must
support both the D3 states
- D3hot
- The function cannot initiate a TLP except for the PME message
- The function cannot act as the target of transactions other than
configuration transactions
- The function issues a software command to enter the D3hot
state by programming the power state field
- D3cold: device enters the D3cold state and power is
removed; when power is restored, the device enters the
D0uninitialized state
## PCIe verification
Source: [https://docs.qualcomm.com/doc/80-70014-8/topic/pcie.html](https://docs.qualcomm.com/doc/80-70014-8/topic/pcie.html)
For information on PCIe verification, seeĀ [PCIe-related configurations](https://docs.qualcomm.com/doc/80-70014-8/topic/pcie.html#pcie-software-support-feature-for-qps615__section_xbl_hhd_l1c) andĀ [QPS615 switch support](https://docs.qualcomm.com/doc/80-70014-8/topic/pcie.html#pcie-software-support-feature-for-qps615__section_nmw_5jd_l1c).
## PCIe debugging
Source: [https://docs.qualcomm.com/doc/80-70014-8/topic/pcie.html](https://docs.qualcomm.com/doc/80-70014-8/topic/pcie.html)
The `lspci` and `setpci` commands are native to Linux
distributions. These commands have various levels of output. These commands also provide
a useful point-in-time look at the capabilities and status of the different components
trained on the PCI bus. Most of these capabilities are reflections of the configuration
space registers required by the PCIe base specification. For more details, seeĀ [https://pcisig.com/specifications](https://pcisig.com/specifications). To view
the usage instructions, run the following command.
lspci --helpCopy to clipboard
The following features are useful in troubleshooting PCIe issues.
- Display device information
lspciCopy to clipboard
The following message is
displayed.
0001:00:00.0 PCI bridge: Qualcomm Device 010b
0001:01:00.0 PCI bridge: Toshiba Corporation Device 0623
0001:02:01.0 PCI bridge: Toshiba Corporation Device 0623
0001:02:02.0 PCI bridge: Toshiba Corporation Device 0623
0001:02:03.0 PCI bridge: Toshiba Corporation Device 0623
0001:04:00.0 USB controller: Renesas Technology Corp. uPD720201 USB 3.0 Host Controller (rev 03)
0001:05:00.0 Ethernet controller: Toshiba Corporation Device 0220
0001:05:00.1 Ethernet controller: Toshiba Corporation Device 0220Copy to clipboard
- Display PCIe device and vendor IDs in the device control
register.
lspci -nvmmCopy to clipboard
The
following message is displayed.
Slot: 0001:00:00.0
Class: 0604
Vendor: 17cb
Device: 010b
DTNode: /sys/firmware/devicetree/base/soc@0/pci@1c08000/pcie@0
IOMMUGroup: 33
Slot: 0001:01:00.0
Class: 0604
Vendor: 1179
Device: 0623
DTNode: /sys/firmware/devicetree/base/soc@0/pci@1c08000/pcie@0/pcie1_bus1_dev0_fn0
IOMMUGroup: 33
Slot: 0001:02:01.0
Class: 0604
Vendor: 1179
Device: 0623
DTNode: /sys/firmware/devicetree/base/soc@0/pci@1c08000/pcie@0/pcie1_bus1_dev0_fn0/pcie1_bus2_dev1_fn0
IOMMUGroup: 33
Slot: 0001:02:02.0
Class: 0604
Vendor: 1179
Device: 0623
DTNode: /sys/firmware/devicetree/base/soc@0/pci@1c08000/pcie@0/pcie1_bus1_dev0_fn0/pcie1_bus2_dev2_fn0
IOMMUGroup: 33
Slot: 0001:02:03.0
Class: 0604
Vendor: 1179
Device: 0623
DTNode: /sys/firmware/devicetree/base/soc@0/pci@1c08000/pcie@0/pcie1_bus1_dev0_fn0/pcie1_bus2_dev3_fn0
IOMMUGroup: 33
Slot: 0001:04:00.0
Class: 0c03
Vendor: 1912
Device: 0014
Rev: 03
ProgIf: 30
DTNode: /sys/firmware/devicetree/base/soc@0/pci@1c08000/pcie@0/pcie1_bus1_dev0_fn0/pcie1_bus2_dev2_fn0/pcie1_bus4_dev0_fn0
IOMMUGroup: 33
Slot: 0001:05:00.0
Class: 0200
Vendor: 1179
Device: 0220
SVendor: 1179
SDevice: 0001
DTNode: /sys/firmware/devicetree/base/soc@0/pci@1c08000/pcie@0/pcie1_bus1_dev0_fn0/pcie1_bus2_dev3_fn0/qps615_eth0,qps615_eth0@pcie1_rp
IOMMUGroup: 33
Slot: 0001:05:00.1
Class: 0200
Vendor: 1179
Device: 0220
SVendor: 1179
SDevice: 0001
DTNode: /sys/firmware/devicetree/base/soc@0/pci@1c08000/pcie@0/pcie1_bus1_dev0_fn0/pcie1_bus2_dev3_fn0/qps615_eth1,qps615_eth1@pcie1_rp
IOMMUGroup: 33Copy to clipboard
For more info on PCIe debugging, seeĀ [https://www.kernel.org/doc/html/v4.17/driver-api/pci.html](https://www.kernel.org/doc/html/v4.17/driver-api/pci.html).
## PCIe examples
Source: [https://docs.qualcomm.com/doc/80-70014-8/topic/pcie.html](https://docs.qualcomm.com/doc/80-70014-8/topic/pcie.html)
For information on the upstream device tree reference, seeĀ [https://git.linaro.org/kernel-org/linux-next.git/tree/arch/arm64/boot/dts/qcom/sc7280.dtsi](https://git.linaro.org/kernel-org/linux-next.git/tree/arch/arm64/boot/dts/qcom/sc7280.dtsi) andĀ [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/pci/controller/dwc/pcie-qcom.c?h=v6.8-rc6#n1634](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/pci/controller/dwc/pcie-qcom.c?h=v6.8-rc6#n1634).
For information on the Qualcomm Linux chip product device-tree node, seeĀ [https://git.linaro.org/kernel-org/linux-next.git/tree/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts](https://git.linaro.org/kernel-org/linux-next.git/tree/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts).
### Client and PCI driver operation flow
The following figure shows the sequence that the PCIe client driver follows to
configure the PCIe driver for a client.

### Client and PCI driver high-level call flow
The following figure shows the high-level call flow and call details between the PCIe
client driver and PCIe driver.

Last Published: Jul 13, 2024
[Previous Topic
I3C](https://docs.qualcomm.com/bundle/publicresource/80-70014-8/topics/i3c.md) [Next Topic
USB](https://docs.qualcomm.com/bundle/publicresource/80-70014-8/topics/usb.md)