[PATCH v2 10/10] board: imx8mp_evk: add USB Type-C OTG support with TCPCI
Peng Fan (OSS)
peng.fan at oss.nxp.com
Sun Jun 21 04:06:46 CEST 2026
From: Peng Fan <peng.fan at nxp.com>
Enable runtime USB host/device mode switching on USB1 Type-C port:
- Add PTN5110 TCPCI node on I2C2 with pd-disable (data port only,
PD negotiation handled by port2 on I2C3)
- Set dr_mode="otg" on usb_dwc3_0 with USB PHY tuning parameters
- Add board_usb_init(): host mode uses tcpm_setup_host_mode(),
device mode uses tcpm_setup_device_mode() via TCPM uclass ops
- Add board_usb_cleanup(): disable source VBUS on host stop
- SS mux GPIO (GPIO4_IO20) set based on CC polarity
- Enable USB_DWC3_GENERIC, DM_USB_GADGET in defconfig
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
arch/arm/dts/imx8mp-evk-u-boot.dtsi | 34 +++++++++++++++-
board/nxp/imx8mp_evk/imx8mp_evk.c | 78 +++++++++++++++++++++++++++++++++++++
2 files changed, 111 insertions(+), 1 deletion(-)
diff --git a/arch/arm/dts/imx8mp-evk-u-boot.dtsi b/arch/arm/dts/imx8mp-evk-u-boot.dtsi
index fc9e9da09dd..d315dfb3d03 100644
--- a/arch/arm/dts/imx8mp-evk-u-boot.dtsi
+++ b/arch/arm/dts/imx8mp-evk-u-boot.dtsi
@@ -88,6 +88,24 @@
&i2c2 {
bootph-pre-ram;
+
+ tcpc_port1: i2c2-ptcpc at 50 {
+ compatible = "nxp,ptn5110", "tcpci";
+ reg = <0x50>;
+
+ connector {
+ compatible = "usb-c-connector";
+ label = "USB-C-1";
+ power-role = "dual";
+ data-role = "dual";
+ try-power-role = "sink";
+ pd-disable;
+ source-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
+ sink-pdos =
+ <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
+ op-sink-microwatt = <15000000>;
+ };
+ };
};
&i2c3 {
@@ -124,7 +142,15 @@
};
&usb_dwc3_0 {
- dr_mode = "peripheral";
+ dr_mode = "otg";
+ maximum-speed = "high-speed";
+ hnp-disable;
+ srp-disable;
+ adp-disable;
+ usb-role-switch;
+ role-switch-default-mode = "none";
+ snps,dis-u1-entry-quirk;
+ snps,dis-u2-entry-quirk;
status = "okay";
};
@@ -133,6 +159,12 @@
};
&usb3_phy0 {
+ fsl,phy-tx-vref-tune = <0xe>;
+ fsl,phy-tx-preemp-amp-tune = <3>;
+ fsl,phy-tx-vboost-level = <5>;
+ fsl,phy-comp-dis-tune = <7>;
+ fsl,pcs-tx-deemph-3p5db = <0x21>;
+ fsl,phy-pcs-tx-swing-full = <0x7f>;
status = "okay";
};
diff --git a/board/nxp/imx8mp_evk/imx8mp_evk.c b/board/nxp/imx8mp_evk/imx8mp_evk.c
index e17100e51ec..37a391908c4 100644
--- a/board/nxp/imx8mp_evk/imx8mp_evk.c
+++ b/board/nxp/imx8mp_evk/imx8mp_evk.c
@@ -4,9 +4,14 @@
*/
#include <config.h>
+#include <dm.h>
#include <efi_loader.h>
#include <env.h>
+#include <init.h>
+#include <usb.h>
#include <asm/arch/sys_proto.h>
+#include <asm/gpio.h>
+#include <usb/tcpm.h>
#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT)
#define IMX_BOOT_IMAGE_GUID \
@@ -35,6 +40,79 @@ int board_mmc_get_env_dev(int devno)
}
#endif
+#define USB_TYPEC_SEL IMX_GPIO_NR(4, 20)
+#define USB_TYPEC_EN IMX_GPIO_NR(2, 20)
+
+static struct udevice *tcpc1_tcpm;
+static bool usb1_gpio_inited;
+
+static int usb1_tcpm_init(void)
+{
+ if (tcpc1_tcpm)
+ return 0;
+
+ return tcpm_get(0, &tcpc1_tcpm);
+}
+
+static void ss_mux_select(enum typec_cc_polarity polarity)
+{
+ if (polarity == TYPEC_POLARITY_CC1)
+ gpio_direction_output(USB_TYPEC_SEL, 0);
+ else
+ gpio_direction_output(USB_TYPEC_SEL, 1);
+}
+
+int board_usb_init(int index, enum usb_init_type init)
+{
+ enum typec_cc_polarity pol;
+ int ret;
+
+ if (index != 0)
+ return 0;
+
+ if (!usb1_gpio_inited) {
+ gpio_request(USB_TYPEC_SEL, "typec_sel");
+ gpio_request(USB_TYPEC_EN, "typec_en");
+ usb1_gpio_inited = true;
+ }
+ gpio_direction_output(USB_TYPEC_EN, 0);
+
+ ret = usb1_tcpm_init();
+ if (ret) {
+ printf("USB1: TCPM init failed: %d\n", ret);
+ return ret;
+ }
+
+ if (init == USB_INIT_HOST) {
+ ret = tcpm_setup_host_mode(tcpc1_tcpm, &pol);
+ if (ret) {
+ printf("USB1: no device detected\n");
+ return 0;
+ }
+ } else {
+ ret = tcpm_setup_device_mode(tcpc1_tcpm, &pol);
+ if (ret) {
+ printf("USB1: no host detected\n");
+ return 0;
+ }
+ }
+
+ ss_mux_select(pol);
+
+ return 0;
+}
+
+int board_usb_cleanup(int index, enum usb_init_type init)
+{
+ if (index != 0)
+ return 0;
+
+ if (init == USB_INIT_HOST && tcpc1_tcpm)
+ tcpm_disable_src_vbus(tcpc1_tcpm);
+
+ return 0;
+}
+
int board_late_init(void)
{
#if CONFIG_IS_ENABLED(ENV_IS_IN_MMC)
--
2.51.0
More information about the U-Boot
mailing list