Proposal for QCOM PCIe switch power and configuration driver

From: Krishna Chaitanya Chundru
Date: Thu Jan 11 2024 - 12:39:22 EST


Hi DT maintainers,

We are trying to upstream the QCOM PCIe switch which has I2C interface
to configure the switch.

In generic a PCIe switch is a device that allows expansion of PCI
Express hierarchy, which allows more devices(PCIe endpoints) to be
connected to a single PCIe port.

We need to configure the QCOM switch like L0s, L1ss entry times, Tx
amplitudes etc.. through I2C interface before PCIe link is established
as these settings can affect link stability if we don't configure them.

Once PCIe switch is configured, PCIe link between the PCIe switch and
PCIe port connected should be established by the QCOM PCIe controller
driver to enumerate the PCIe endpoints connected to the PCIe switch.

We had a QCOM switch driver which powers on the switch and do the I2C
configurations.

This is how the flow goes.
-->Power on the switch
-->Do Switch configuration (over i2c) with qcom switch driver
-->PCIe link training and enumeration.

From the the above requirements we want a I2C client driver which probes
first and power's on the switch and do switch configurations through
I2C, and then PCIe driver needs to probe and do the link training and
enumeration. And for suspend resume usecase also we need these probe
dependencies.

As we can't keep the probe dependencies between PCIe controller driver
and I2C client driver in the DT, we want to propose following solution.

Since the I2C driver need to configure the switch and power it on before
the PCIe driver attempts to probe the device, we thought of exposing a
reset controller from the I2C driver.

We came up with this reset controller idea because the I2C driver
essentially has to configure the switch and power on the device, then
only the PCIe driver has to probe the switch. This aligns with how reset
controller operates in general.

This is how sample DT looks like

diff --git a/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi b/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi
index 2ff549f4dc7a..222206902305 100644
--- a/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi
@@ -414,6 +414,18 @@ &lpass_va_macro {
vdd-micb-supply = <&vreg_bob>;
};

+&i2c0 {
+ clock-frequency = <100000>;
+ status = "okay";
+
+ pcie_switch: pcie-switch@77 {
+ compatible = "qcom,switch-i2c";
+ reg = <0x77>;
+ vdda-supply = <&pcie_switch_rest_vreg>;
+ status = "okay";
+ };
+};
+
&pcie1 {
status = "okay";
perst-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>;
@@ -422,6 +434,10 @@ &pcie1 {

pinctrl-names = "default";
pinctrl-0 = <&pcie1_reset_n>, <&pcie1_wake_n>;
+
+ resets = <&gcc GCC_PCIE_1_BCR>,
+ <&pcie_switch 0>;
+ reset-names = "pci","device";
};

Can you please tell us whether this approach is acceptable or not?
we are open for any other suggestions also.

Thanks & Regards,
Krishna Chaitanya.