From: Peng Fan <[email protected]> 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 <[email protected]> --- 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@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

