Same Hardware, new Kernel
We are trying to update to the new Kernel 5.15.32 (old Kernel 4.19.72) but the USB-PD Chip (PTN5110) just does not work:
When we start the module tcpci with our Device Tree (see below) we get the following messages:
devel@europa:/usr/lib/modules/5.15.32+g4122737b2fca$ sudo modprobe tcpci
[ 139.282440] OF: graph: no port node found in /soc/bus@2100000/i2c@21f8000/ptn5110@50
[ 139.332044] OF: graph: no port node found in /soc/bus@2100000/i2c@21f8000/ptn5110@50/connector
[ 139.341524] OF: graph: no port node found in /soc/bus@2100000/i2c@21f8000/ptn5110@50/connector
We did try to specify the port but were unlucky so far (nothing seams to work and we are trying for a few weeks now). The DT below worked wonderful in the old kernel but not the new one. After loading the module we see some communication over the I2C port and everything seams to work fine. As soon as we plug in a USB connection the Kernel gets flooded with IRQ requests (or so it seams). The I2C bus is filled with data exchange and none of the consoles are reacting to any keystroke. After unplugging the USB connection the system reacts normal again. (the system seams to be blocked completely)
Our device tree:
/ {
regulators {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <0>;
reg_usb_otg1_vbus: regulator@2 {
compatible = "regulator-fixed";
reg = <2>;
regulator-name = "usb_otg1_vbus";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usb_otg1_vbus>;
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
gpio = <&gpio2 8 GPIO_ACTIVE_HIGH>;
enable-active-high;
status = "okay";
};
};
};
&usbotg1 {
/*pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usbotg1>;*/
dr_mode = "otg";
status = "okay";
disable-over-current;
vbus-supply = <®_usb_otg1_vbus>;
};
&i2c4 {
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c4>;
status = "okay";
usb_pd: ptn5110@50 {
compatible = "nxp,ptn5110";
reg = <0x50>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usb_pd>;
interrupt-parent = <&gpio2>;
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
wakeup-source;
usb_con: connector {
compatible = "usb-c-connector";
label = "USB-C";
data-role = "dual";
power-role = "dual";
try-power-role = "sink";
source-pdos = <PDO_FIXED(VSAFE5V, 2000, PDO_FIXED_USB_COMM | PDO_FIXED_DUAL_ROLE)>;
sink-pdos = <PDO_FIXED(VSAFE5V, 2000, PDO_FIXED_USB_COMM | PDO_FIXED_DUAL_ROLE)
//PDO_FIXED(VSAFE5V, 3000, 0)
//PDO_FIXED(9000, 3000, 0)
PDO_FIXED(12000, 3000, 0)
PDO_FIXED(20000, 3000, 0)>;
//PDO_FIXED(20000, 5000, 0)>;
op-sink-microwatt = <10000000>;
};
};
};
&iomuxc {
pinctrl_i2c4: i2c4grp {
fsl,pins = <
MX6UL_PAD_UART2_TX_DATA__I2C4_SCL 0x4001b8b0
MX6UL_PAD_UART2_RX_DATA__I2C4_SDA 0x4001b8b0
>;
};
pinctrl_usb_pd: usbpdgrp {
fsl,pins = <
MX6UL_PAD_ENET2_TX_DATA0__GPIO2_IO11 0x0001b020 /* Alert Interrupt */
MX6UL_PAD_ENET2_TX_CLK__GPIO2_IO14 0x0001b020 /* Fault Interrupt */
>;
};
pinctrl_usb_otg1_vbus: usbotg1 {
fsl,pins = <
MX6UL_PAD_ENET2_RX_DATA0__GPIO2_IO08 0x000000b9
MX6UL_PAD_ENET2_RX_DATA1__USB_OTG1_OC 0x000010b0
>;
};
};
As it turned out there is a bug in the Kernel Module tcpci that has this effect on the PTN5110 Chip. NXP already has a patch for their Kernel but it was not ported to the Mainline Kernel. I implemented the same patch for the Kernel 5.15.91 and the chip is working flawlessly now. For anyone with the same problem, here my patch:
diff --git a/drivers/usb/typec/tcpm/tcpci.c b/drivers/usb/typec/tcpm/tcpci.c
index 5340a3a3a81b..0d715e091b78 100644
--- a/drivers/usb/typec/tcpm/tcpci.c
+++ b/drivers/usb/typec/tcpm/tcpci.c
@@ -628,6 +628,9 @@ static int tcpci_init(struct tcpc_dev *tcpc)
if (ret < 0)
return ret;
+ /* Clear fault condition */
+ regmap_write(tcpci->regmap, TCPC_FAULT_STATUS, 0x80);
+
if (tcpci->controls_vbus)
reg = TCPC_POWER_STATUS_VBUS_PRES;
else
@@ -644,7 +647,8 @@ static int tcpci_init(struct tcpc_dev *tcpc)
reg = TCPC_ALERT_TX_SUCCESS | TCPC_ALERT_TX_FAILED |
TCPC_ALERT_TX_DISCARDED | TCPC_ALERT_RX_STATUS |
- TCPC_ALERT_RX_HARD_RST | TCPC_ALERT_CC_STATUS;
+ TCPC_ALERT_RX_HARD_RST | TCPC_ALERT_CC_STATUS |
+ TCPC_ALERT_V_ALARM_LO | TCPC_ALERT_FAULT;
if (tcpci->controls_vbus)
reg |= TCPC_ALERT_POWER_STATUS;
/* Enable VSAFE0V status interrupt when detecting VSAFE0V is supported */
@@ -728,6 +732,13 @@ irqreturn_t tcpci_irq(struct tcpci *tcpci)
tcpm_vbus_change(tcpci->port);
}
+ /* Clear the fault status anyway */
+ if (status & TCPC_ALERT_FAULT) {
+ regmap_read(tcpci->regmap, TCPC_FAULT_STATUS, &raw);
+ regmap_write(tcpci->regmap, TCPC_FAULT_STATUS,
+ raw | TCPC_FAULT_STATUS_MASK);
+ }
+
if (status & TCPC_ALERT_RX_HARD_RST)
tcpm_pd_hard_reset(tcpci->port);
I found this solution here: https://source.codeaurora.org/external/imx/linux-imx/commit/drivers/usb/typec/tcpm/tcpci.c?h=lf-5.15.y&id=2a263f918b25725e0434afa9ff3b83b1bc18ef74