From c50151d43f78738d3d9fef4c4f4611e83178dc88 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Fri, 29 Mar 2019 15:42:11 +0100 Subject: phy: usbphyc: Binding update of vdda supply Move supply vdda1v1 and vdda1v8 in usbphyc node and no more in port Signed-off-by: Patrick Delaunay --- arch/arm/dts/stm32mp157c-ed1.dts | 8 -------- arch/arm/dts/stm32mp157c.dtsi | 3 +++ 2 files changed, 3 insertions(+), 8 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/dts/stm32mp157c-ed1.dts b/arch/arm/dts/stm32mp157c-ed1.dts index 2664c9ce904..0366782fda9 100644 --- a/arch/arm/dts/stm32mp157c-ed1.dts +++ b/arch/arm/dts/stm32mp157c-ed1.dts @@ -382,18 +382,10 @@ status = "okay"; }; -&usbotg_hs { - usb33d-supply = <&usb33>; -}; - &usbphyc_port0 { phy-supply = <&vdd_usb>; - vdda1v1-supply = <®11>; - vdda1v8-supply = <®18>; }; &usbphyc_port1 { phy-supply = <&vdd_usb>; - vdda1v1-supply = <®11>; - vdda1v8-supply = <®18>; }; diff --git a/arch/arm/dts/stm32mp157c.dtsi b/arch/arm/dts/stm32mp157c.dtsi index 7eb4bee31cf..472637bb554 100644 --- a/arch/arm/dts/stm32mp157c.dtsi +++ b/arch/arm/dts/stm32mp157c.dtsi @@ -836,6 +836,7 @@ g-np-tx-fifo-size = <32>; g-tx-fifo-size = <128 128 64 64 64 64 32 32>; dr_mode = "otg"; + usb33d-supply = <&usb33>; status = "disabled"; }; @@ -1161,6 +1162,8 @@ reg = <0x5a006000 0x1000>; clocks = <&rcc USBPHY_K>; resets = <&rcc USBPHY_R>; + vdda1v1-supply = <®11>; + vdda1v8-supply = <®18>; status = "disabled"; usbphyc_port0: usb-phy@0 { -- cgit v1.2.3 From c31000c534c6d62dd3a3ae58f30eae3ed572d856 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Fri, 29 Mar 2019 15:42:23 +0100 Subject: stm32mp1: migrate USBOTG device to driver model Use the DWC2 device driver with DM_USB_GADGET support and cleanup the USB support in STM32MP1 board. Signed-off-by: Patrick Delaunay --- arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi | 3 +- arch/arm/dts/stm32mp157a-dk1.dts | 16 ++- arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi | 1 + arch/arm/dts/stm32mp157c.dtsi | 2 +- board/st/stm32mp1/stm32mp1.c | 165 +++---------------------------- configs/stm32mp15_basic_defconfig | 1 + configs/stm32mp15_trusted_defconfig | 1 + 7 files changed, 32 insertions(+), 157 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi b/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi index af7acfa0375..7e2c5d0de35 100644 --- a/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi +++ b/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi @@ -11,6 +11,7 @@ aliases { i2c3 = &i2c4; mmc0 = &sdmmc1; + usb0 = &usbotg_hs; }; config { u-boot,boot-led = "heartbeat"; @@ -190,7 +191,7 @@ }; &usbotg_hs { - usb1600; + force-b-session-valid; hnp-srp-disable; }; diff --git a/arch/arm/dts/stm32mp157a-dk1.dts b/arch/arm/dts/stm32mp157a-dk1.dts index 0882765d0c9..b8ef82015b0 100644 --- a/arch/arm/dts/stm32mp157a-dk1.dts +++ b/arch/arm/dts/stm32mp157a-dk1.dts @@ -249,11 +249,25 @@ status = "okay"; }; +&usbotg_hs { + dr_mode = "peripheral"; + phys = <&usbphyc_port1 0>; + phy-names = "usb2-phy"; + status = "okay"; +}; + &usbphyc { - vdd3v3-supply = <&vdd_usb>; status = "okay"; }; +&usbphyc_port0 { + phy-supply = <&vdd_usb>; +}; + +&usbphyc_port1 { + phy-supply = <&vdd_usb>; +}; + &vrefbuf { regulator-min-microvolt = <2500000>; regulator-max-microvolt = <2500000>; diff --git a/arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi b/arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi index 8b92b1fa2ee..5b19e44d2fb 100644 --- a/arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi +++ b/arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi @@ -12,6 +12,7 @@ i2c4 = &i2c5; pinctrl2 = &stmfx_pinctrl; spi0 = &qspi; + usb0 = &usbotg_hs; }; }; diff --git a/arch/arm/dts/stm32mp157c.dtsi b/arch/arm/dts/stm32mp157c.dtsi index 472637bb554..94634336a5e 100644 --- a/arch/arm/dts/stm32mp157c.dtsi +++ b/arch/arm/dts/stm32mp157c.dtsi @@ -825,7 +825,7 @@ }; usbotg_hs: usb-otg@49000000 { - compatible = "snps,dwc2"; + compatible = "st,stm32mp1-hsotg", "snps,dwc2"; reg = <0x49000000 0x10000>; clocks = <&rcc USBO_K>; clock-names = "otg"; diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c index 24d299ac33b..b369b7a54b6 100644 --- a/board/st/stm32mp1/stm32mp1.c +++ b/board/st/stm32mp1/stm32mp1.c @@ -7,18 +7,17 @@ #include #include #include +#include #include #include #include #include #include #include -#include #include #include #include #include -#include /* SYSCFG registers */ #define SYSCFG_BOOTR 0x00 @@ -58,11 +57,6 @@ */ DECLARE_GLOBAL_DATA_PTR; -#define STM32MP_GUSBCFG 0x40002407 - -#define STM32MP_GGPIO 0x38 -#define STM32MP_GGPIO_VBUS_SENSING BIT(21) - #define USB_WARNING_LOW_THRESHOLD_UV 660000 #define USB_START_LOW_THRESHOLD_UV 1230000 #define USB_START_HIGH_THRESHOLD_UV 2100000 @@ -155,149 +149,22 @@ static void board_key_check(void) #endif } -static struct dwc2_plat_otg_data stm32mp_otg_data = { - .usb_gusbcfg = STM32MP_GUSBCFG, -}; +#if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG) -static struct reset_ctl usbotg_reset; - -int board_usb_init(int index, enum usb_init_type init) +int g_dnl_board_usb_cable_connected(void) { - struct fdtdec_phandle_args args; - struct udevice *dev; - const void *blob = gd->fdt_blob; - struct clk clk; - struct phy phy; - int node; - int phy_provider; + struct udevice *dwc2_udc_otg; int ret; - /* find the usb otg node */ - node = fdt_node_offset_by_compatible(blob, -1, "snps,dwc2"); - if (node < 0) { - debug("Not found usb_otg device\n"); - return -ENODEV; - } - - if (!fdtdec_get_is_enabled(blob, node)) { - debug("stm32 usbotg is disabled in the device tree\n"); - return -ENODEV; - } - - /* Enable clock */ - ret = fdtdec_parse_phandle_with_args(blob, node, "clocks", - "#clock-cells", 0, 0, &args); - if (ret) { - debug("usbotg has no clocks defined in the device tree\n"); - return ret; - } - - ret = uclass_get_device_by_of_offset(UCLASS_CLK, args.node, &dev); - if (ret) - return ret; - - if (args.args_count != 1) { - debug("Can't find clock ID in the device tree\n"); - return -ENODATA; - } - - clk.dev = dev; - clk.id = args.args[0]; - - ret = clk_enable(&clk); - if (ret) { - debug("Failed to enable usbotg clock\n"); - return ret; - } - - /* Reset */ - ret = fdtdec_parse_phandle_with_args(blob, node, "resets", - "#reset-cells", 0, 0, &args); - if (ret) { - debug("usbotg has no resets defined in the device tree\n"); - goto clk_err; - } - - ret = uclass_get_device_by_of_offset(UCLASS_RESET, args.node, &dev); - if (ret || args.args_count != 1) - goto clk_err; - - usbotg_reset.dev = dev; - usbotg_reset.id = args.args[0]; - - reset_assert(&usbotg_reset); - udelay(2); - reset_deassert(&usbotg_reset); - - /* Get USB PHY */ - ret = fdtdec_parse_phandle_with_args(blob, node, "phys", - "#phy-cells", 0, 0, &args); - if (!ret) { - phy_provider = fdt_parent_offset(blob, args.node); - ret = uclass_get_device_by_of_offset(UCLASS_PHY, - phy_provider, &dev); - if (ret) - goto clk_err; - - phy.dev = dev; - phy.id = fdtdec_get_uint(blob, args.node, "reg", -1); - - ret = generic_phy_power_on(&phy); - if (ret) { - debug("unable to power on the phy\n"); - goto clk_err; - } - - ret = generic_phy_init(&phy); - if (ret) { - debug("failed to init usb phy\n"); - goto phy_power_err; - } - } - - /* Parse and store data needed for gadget */ - stm32mp_otg_data.regs_otg = fdtdec_get_addr(blob, node, "reg"); - if (stm32mp_otg_data.regs_otg == FDT_ADDR_T_NONE) { - debug("usbotg: can't get base address\n"); - ret = -ENODATA; - goto phy_init_err; - } - - stm32mp_otg_data.rx_fifo_sz = fdtdec_get_int(blob, node, - "g-rx-fifo-size", 0); - stm32mp_otg_data.np_tx_fifo_sz = fdtdec_get_int(blob, node, - "g-np-tx-fifo-size", 0); - stm32mp_otg_data.tx_fifo_sz = fdtdec_get_int(blob, node, - "g-tx-fifo-size", 0); - /* Enable voltage level detector */ - if (!(fdtdec_parse_phandle_with_args(blob, node, "usb33d-supply", - NULL, 0, 0, &args))) { - if (!uclass_get_device_by_of_offset(UCLASS_REGULATOR, - args.node, &dev)) { - ret = regulator_set_enable(dev, true); - if (ret) { - debug("Failed to enable usb33d\n"); - goto phy_init_err; - } - } - } - /* Enable vbus sensing */ - setbits_le32(stm32mp_otg_data.regs_otg + STM32MP_GGPIO, - STM32MP_GGPIO_VBUS_SENSING); - - return dwc2_udc_probe(&stm32mp_otg_data); - -phy_init_err: - generic_phy_exit(&phy); - -phy_power_err: - generic_phy_power_off(&phy); - -clk_err: - clk_disable(&clk); + ret = uclass_get_device_by_driver(UCLASS_USB_GADGET_GENERIC, + DM_GET_DRIVER(dwc2_udc_otg), + &dwc2_udc_otg); + if (!ret) + debug("dwc2_udc_otg init failed\n"); - return ret; + return dwc2_udc_B_session_valid(dwc2_udc_otg); } +#endif /* CONFIG_USB_GADGET */ static int get_led(struct udevice **dev, char *led_string) { @@ -438,16 +305,6 @@ static int board_check_usb_power(void) return 0; } -int board_usb_cleanup(int index, enum usb_init_type init) -{ - /* Reset usbotg */ - reset_assert(&usbotg_reset); - udelay(2); - reset_deassert(&usbotg_reset); - - return 0; -} - static void sysconf_init(void) { #ifndef CONFIG_STM32MP1_TRUSTED diff --git a/configs/stm32mp15_basic_defconfig b/configs/stm32mp15_basic_defconfig index b6c19724cae..fd164fa596d 100644 --- a/configs/stm32mp15_basic_defconfig +++ b/configs/stm32mp15_basic_defconfig @@ -69,6 +69,7 @@ CONFIG_SERIAL_RX_BUFFER=y CONFIG_STM32_SERIAL=y CONFIG_USB=y CONFIG_DM_USB=y +CONFIG_DM_USB_GADGET=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_GENERIC=y CONFIG_USB_GADGET=y diff --git a/configs/stm32mp15_trusted_defconfig b/configs/stm32mp15_trusted_defconfig index ed2a2e61c81..f82b770bc87 100644 --- a/configs/stm32mp15_trusted_defconfig +++ b/configs/stm32mp15_trusted_defconfig @@ -60,6 +60,7 @@ CONFIG_SERIAL_RX_BUFFER=y CONFIG_STM32_SERIAL=y CONFIG_USB=y CONFIG_DM_USB=y +CONFIG_DM_USB_GADGET=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_GENERIC=y CONFIG_USB_GADGET=y -- cgit v1.2.3 From 6fe7dd3327d552bacf4266d7f1ed074bf98ffb92 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Fri, 29 Mar 2019 15:42:24 +0100 Subject: stm32mp1: add stusb1600 support for DK1 and DK2 board The DK1 and DK2 boards use the USB Type-C controller STUSB1600. This patch updates: - the device tree to add the I2C node in the DT - the board stm32mp1 to probe this I2C device and use this controller to check cable detection. - the DWC2 driver to support a new dt property "u-boot,force-b-session-valid" which forces B session and device mode; it is a workaround because the VBUS sensing and ID detection isn't available with stusb1600. Signed-off-by: Patrick Delaunay Reviewed-by: Lukasz Majewski --- arch/arm/dts/stm32mp157-pinctrl.dtsi | 7 ++++ arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi | 2 +- arch/arm/dts/stm32mp157a-dk1.dts | 18 ++++++++++ board/st/stm32mp1/stm32mp1.c | 56 ++++++++++++++++++++++++++++++++ doc/device-tree-bindings/usb/dwc2.txt | 2 ++ drivers/usb/gadget/dwc2_udc_otg.c | 8 +++-- 6 files changed, 90 insertions(+), 3 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/dts/stm32mp157-pinctrl.dtsi b/arch/arm/dts/stm32mp157-pinctrl.dtsi index c0698754861..0aae69b0a04 100644 --- a/arch/arm/dts/stm32mp157-pinctrl.dtsi +++ b/arch/arm/dts/stm32mp157-pinctrl.dtsi @@ -375,6 +375,13 @@ }; }; + stusb1600_pins_a: stusb1600-0 { + pins { + pinmux = ; + bias-pull-up; + }; + }; + uart4_pins_a: uart4-0 { pins1 { pinmux = ; /* UART4_TX */ diff --git a/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi b/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi index 7e2c5d0de35..0f32a38dc94 100644 --- a/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi +++ b/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi @@ -191,7 +191,7 @@ }; &usbotg_hs { - force-b-session-valid; + u-boot,force-b-session-valid; hnp-srp-disable; }; diff --git a/arch/arm/dts/stm32mp157a-dk1.dts b/arch/arm/dts/stm32mp157a-dk1.dts index b8ef82015b0..e36773dde91 100644 --- a/arch/arm/dts/stm32mp157a-dk1.dts +++ b/arch/arm/dts/stm32mp157a-dk1.dts @@ -67,6 +67,24 @@ /delete-property/dmas; /delete-property/dma-names; + typec: stusb1600@28 { + compatible = "st,stusb1600"; + reg = <0x28>; + interrupts = <11 IRQ_TYPE_EDGE_FALLING>; + interrupt-parent = <&gpioi>; + pinctrl-names = "default"; + pinctrl-0 = <&stusb1600_pins_a>; + + status = "okay"; + + typec_con: connector { + compatible = "usb-c-connector"; + label = "USB-C"; + power-role = "sink"; + power-opmode = "default"; + }; + }; + pmic: stpmic@33 { compatible = "st,stpmic1"; reg = <0x33>; diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c index b369b7a54b6..76917b022ed 100644 --- a/board/st/stm32mp1/stm32mp1.c +++ b/board/st/stm32mp1/stm32mp1.c @@ -9,15 +9,18 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include #include +#include /* SYSCFG registers */ #define SYSCFG_BOOTR 0x00 @@ -151,11 +154,64 @@ static void board_key_check(void) #if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG) +/* STMicroelectronics STUSB1600 Type-C controller */ +#define STUSB1600_CC_CONNECTION_STATUS 0x0E + +/* STUSB1600_CC_CONNECTION_STATUS bitfields */ +#define STUSB1600_CC_ATTACH BIT(0) + +static int stusb1600_init(struct udevice **dev_stusb1600) +{ + ofnode node; + struct udevice *dev, *bus; + int ret; + u32 chip_addr; + + *dev_stusb1600 = NULL; + + /* if node stusb1600 is present, means DK1 or DK2 board */ + node = ofnode_by_compatible(ofnode_null(), "st,stusb1600"); + if (!ofnode_valid(node)) + return -ENODEV; + + ret = ofnode_read_u32(node, "reg", &chip_addr); + if (ret) + return -EINVAL; + + ret = uclass_get_device_by_ofnode(UCLASS_I2C, ofnode_get_parent(node), + &bus); + if (ret) { + printf("bus for stusb1600 not found\n"); + return -ENODEV; + } + + ret = dm_i2c_probe(bus, chip_addr, 0, &dev); + if (!ret) + *dev_stusb1600 = dev; + + return ret; +} + +static int stusb1600_cable_connected(struct udevice *dev) +{ + u8 status; + + if (dm_i2c_read(dev, STUSB1600_CC_CONNECTION_STATUS, &status, 1)) + return 0; + + return status & STUSB1600_CC_ATTACH; +} + +#include int g_dnl_board_usb_cable_connected(void) { + struct udevice *stusb1600; struct udevice *dwc2_udc_otg; int ret; + if (!stusb1600_init(&stusb1600)) + return stusb1600_cable_connected(stusb1600); + ret = uclass_get_device_by_driver(UCLASS_USB_GADGET_GENERIC, DM_GET_DRIVER(dwc2_udc_otg), &dwc2_udc_otg); diff --git a/doc/device-tree-bindings/usb/dwc2.txt b/doc/device-tree-bindings/usb/dwc2.txt index eb60ffae58b..61493f7cb0c 100644 --- a/doc/device-tree-bindings/usb/dwc2.txt +++ b/doc/device-tree-bindings/usb/dwc2.txt @@ -39,6 +39,8 @@ Refer to phy/phy-bindings.txt for generic phy consumer properties - g-tx-fifo-size: size of periodic tx fifo per endpoint (except ep0) in gadget mode. - usb33d-supply: external VBUS and ID sensing comparators supply, in order to perform OTG operation, used on STM32MP1 SoCs. +- u-boot,force-b-session-valid: force B-peripheral session instead of relying on + VBUS sensing (only valid when dr_mode = "peripheral" and for u-boot). Deprecated properties: - g-use-dma: gadget DMA mode is automatically detected diff --git a/drivers/usb/gadget/dwc2_udc_otg.c b/drivers/usb/gadget/dwc2_udc_otg.c index 3fdaa102bae..494ab533cca 100644 --- a/drivers/usb/gadget/dwc2_udc_otg.c +++ b/drivers/usb/gadget/dwc2_udc_otg.c @@ -1053,7 +1053,7 @@ static int dwc2_udc_otg_ofdata_to_platdata(struct udevice *dev) platdata->tx_fifo_sz = dev_read_u32_default(dev, "g-tx-fifo-size", 0); platdata->force_b_session_valid = - dev_read_bool(dev, "force-b-session-valid"); + dev_read_bool(dev, "u-boot,force-b-session-valid"); /* force platdata according compatible */ drvdata = dev_get_driver_data(dev); @@ -1075,6 +1075,9 @@ static void dwc2_set_stm32mp1_hsotg_params(struct dwc2_plat_otg_data *p) | 0 << 8 /* [0:SRP disable 1:SRP enable]*/ | 0 << 6 /* 0: high speed utmi+, 1: full speed serial*/ | 0x7 << 0; /* FS timeout calibration**/ + + if (p->force_b_session_valid) + p->usb_gusbcfg |= 1 << 30; /* FDMOD: Force device mode */ } static int dwc2_udc_otg_reset_init(struct udevice *dev, @@ -1166,7 +1169,8 @@ static int dwc2_udc_otg_probe(struct udevice *dev) if (platdata->force_b_session_valid) /* Override B session bits : value and enable */ - setbits_le32(&usbotg_reg->gotgctl, B_VALOEN | B_VALOVAL); + setbits_le32(&usbotg_reg->gotgctl, + A_VALOEN | A_VALOVAL | B_VALOEN | B_VALOVAL); ret = dwc2_udc_probe(platdata); if (ret) -- cgit v1.2.3