Message ID | 1553870544-15734-17-git-send-email-patrick.delaunay@st.com |
---|---|
State | Accepted |
Commit | 6fe7dd3327d552bacf4266d7f1ed074bf98ffb92 |
Delegated to: | Lukasz Majewski |
Headers | show |
Series | usb: convert dwc2 gadget to driver model, used in stm32mp1 | expand |
On Fri, 29 Mar 2019 15:42:24 +0100 Patrick Delaunay <patrick.delaunay@st.com> wrote: > 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 <patrick.delaunay@st.com> > --- > > 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(-) > > diff --git a/arch/arm/dts/stm32mp157-pinctrl.dtsi > b/arch/arm/dts/stm32mp157-pinctrl.dtsi index 867d244..1962267 100644 > --- a/arch/arm/dts/stm32mp157-pinctrl.dtsi > +++ b/arch/arm/dts/stm32mp157-pinctrl.dtsi > @@ -380,6 +380,13 @@ > }; > }; > > + stusb1600_pins_a: stusb1600-0 { > + pins { > + pinmux = <STM32_PINMUX('I', > 11, ANALOG)>; > + bias-pull-up; > + }; > + }; > + > uart4_pins_a: uart4-0 { > pins1 { > pinmux = <STM32_PINMUX('G', > 11, AF6)>; /* UART4_TX */ diff --git > a/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi > b/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi index 7e2c5d0..0f32a38 > 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 b8ef820..e36773d 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 58b6d78..23737ce 100644 > --- a/board/st/stm32mp1/stm32mp1.c > +++ b/board/st/stm32mp1/stm32mp1.c > @@ -9,15 +9,18 @@ > #include <dm.h> > #include <g_dnl.h> > #include <generic-phy.h> > +#include <i2c.h> > #include <led.h> > #include <misc.h> > #include <phy.h> > #include <reset.h> > #include <syscon.h> > +#include <usb.h> > #include <asm/io.h> > #include <asm/gpio.h> > #include <asm/arch/stm32.h> > #include <power/regulator.h> > +#include <usb/dwc2_udc.h> > > /* 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 <usb/dwc2_udc.h> > 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 eb60ffa..61493f7 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 3fdaa10..494ab53 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) Reviewed-by: Lukasz Majewski <lukma@denx.de> Best regards, Lukasz Majewski -- DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
diff --git a/arch/arm/dts/stm32mp157-pinctrl.dtsi b/arch/arm/dts/stm32mp157-pinctrl.dtsi index 867d244..1962267 100644 --- a/arch/arm/dts/stm32mp157-pinctrl.dtsi +++ b/arch/arm/dts/stm32mp157-pinctrl.dtsi @@ -380,6 +380,13 @@ }; }; + stusb1600_pins_a: stusb1600-0 { + pins { + pinmux = <STM32_PINMUX('I', 11, ANALOG)>; + bias-pull-up; + }; + }; + uart4_pins_a: uart4-0 { pins1 { pinmux = <STM32_PINMUX('G', 11, AF6)>; /* UART4_TX */ diff --git a/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi b/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi index 7e2c5d0..0f32a38 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 b8ef820..e36773d 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 58b6d78..23737ce 100644 --- a/board/st/stm32mp1/stm32mp1.c +++ b/board/st/stm32mp1/stm32mp1.c @@ -9,15 +9,18 @@ #include <dm.h> #include <g_dnl.h> #include <generic-phy.h> +#include <i2c.h> #include <led.h> #include <misc.h> #include <phy.h> #include <reset.h> #include <syscon.h> +#include <usb.h> #include <asm/io.h> #include <asm/gpio.h> #include <asm/arch/stm32.h> #include <power/regulator.h> +#include <usb/dwc2_udc.h> /* 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 <usb/dwc2_udc.h> 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 eb60ffa..61493f7 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 3fdaa10..494ab53 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)
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 <patrick.delaunay@st.com> --- 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(-)