Message ID | 20221212104437.15838-2-fabrice.gasnier@foss.st.com |
---|---|
State | Accepted |
Commit | ba1fa2abde88257c29ee4d8f3884ab6657a3193a |
Delegated to: | Patrice Chotard |
Headers | show |
Series | Add support for USB onboard HUB, used on stm32 boards | expand |
Hi Fabrice On 12/12/22 11:44, Fabrice Gasnier wrote: > The main issue the driver addresses is that a USB hub needs to be > powered before it can be discovered. This is often solved by using > "regulator-always-on". > > This driver is inspired by the Linux v6.1 driver. It only enables (or > disables) the hub vdd (3v3) supply, so it can be enumerated. > Scanning of the device tree is done in a similar manner to the sandbox, > by the usb-uclass. DT part looks like: > > &usbh_ehci { > ... > #address-cells = <1>; > #size-cells = <0>; > hub@1 { > compatible = "usb424,2514"; > reg = <1>; > vdd-supply = <&v3v3>; > }; > }; > > When the bus gets probed, the driver is automatically probed/removed from > the bus tree, as an example on stm32: > STM32MP> usb start > starting USB... > STM32MP> dm tree > Class Index Probed Driver Name > ----------------------------------------------------------- > usb 0 [ + ] ehci_generic | |-- usb@5800d000 > usb_hub 0 [ + ] usb_onboard_hub | | `-- hub@1 > usb_hub 1 [ + ] usb_hub | | `-- usb_hub > > STM32MP> usb tree > USB device tree: > 1 Hub (480 Mb/s, 0mA) > | u-boot EHCI Host Controller > | > +-2 Hub (480 Mb/s, 2mA) > > Signed-off-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com> > --- > > common/Makefile | 1 + > common/usb_onboard_hub.c | 62 +++++++++++++++++++++++++++++++++++ > drivers/usb/Kconfig | 10 ++++++ > drivers/usb/host/usb-uclass.c | 16 +++++---- > 4 files changed, 83 insertions(+), 6 deletions(-) > create mode 100644 common/usb_onboard_hub.c > > diff --git a/common/Makefile b/common/Makefile > index 20addfb244c2..7789aab484fd 100644 > --- a/common/Makefile > +++ b/common/Makefile > @@ -26,6 +26,7 @@ obj-$(CONFIG_PHYLIB) += miiphyutil.o > obj-$(CONFIG_USB_HOST) += usb.o usb_hub.o > obj-$(CONFIG_USB_GADGET) += usb.o usb_hub.o > obj-$(CONFIG_USB_STORAGE) += usb_storage.o > +obj-$(CONFIG_USB_ONBOARD_HUB) += usb_onboard_hub.o > > # others > obj-$(CONFIG_CONSOLE_MUX) += iomux.o > diff --git a/common/usb_onboard_hub.c b/common/usb_onboard_hub.c > new file mode 100644 > index 000000000000..89e18a2ddad6 > --- /dev/null > +++ b/common/usb_onboard_hub.c > @@ -0,0 +1,62 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * Driver for onboard USB hubs > + * > + * Copyright (C) 2022, STMicroelectronics - All Rights Reserved > + * > + * Mostly inspired by Linux kernel v6.1 onboard_usb_hub driver > + */ > + > +#include <common.h> > +#include <dm.h> > +#include <dm/device_compat.h> > +#include <power/regulator.h> > + > +struct onboard_hub { > + struct udevice *vdd; > +}; > + > +static int usb_onboard_hub_probe(struct udevice *dev) > +{ > + struct onboard_hub *hub = dev_get_priv(dev); > + int ret; > + > + ret = device_get_supply_regulator(dev, "vdd-supply", &hub->vdd); > + if (ret) { > + dev_err(dev, "can't get vdd-supply: %d\n", ret); > + return ret; > + } > + > + ret = regulator_set_enable_if_allowed(hub->vdd, true); > + if (ret) > + dev_err(dev, "can't enable vdd-supply: %d\n", ret); > + > + return ret; > +} > + > +static int usb_onboard_hub_remove(struct udevice *dev) > +{ > + struct onboard_hub *hub = dev_get_priv(dev); > + int ret; > + > + ret = regulator_set_enable_if_allowed(hub->vdd, false); > + if (ret) > + dev_err(dev, "can't disable vdd-supply: %d\n", ret); > + > + return ret; > +} > + > +static const struct udevice_id usb_onboard_hub_ids[] = { > + /* Use generic usbVID,PID dt-bindings (usb-device.yaml) */ > + { .compatible = "usb424,2514" }, /* USB2514B USB 2.0 */ > + { } > +}; > + > +U_BOOT_DRIVER(usb_onboard_hub) = { > + .name = "usb_onboard_hub", > + .id = UCLASS_USB_HUB, > + .probe = usb_onboard_hub_probe, > + .remove = usb_onboard_hub_remove, > + .of_match = usb_onboard_hub_ids, > + .priv_auto = sizeof(struct onboard_hub), > +}; > diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig > index 3afb45d5ccb2..d10ee6853d40 100644 > --- a/drivers/usb/Kconfig > +++ b/drivers/usb/Kconfig > @@ -106,6 +106,16 @@ config USB_KEYBOARD > Say Y here if you want to use a USB keyboard for U-Boot command line > input. > > +config USB_ONBOARD_HUB > + bool "Onboard USB hub support" > + depends on DM_USB > + ---help--- > + Say Y here if you want to support discrete onboard USB hubs that > + don't require an additional control bus for initialization, but > + need some non-trivial form of initialization, such as enabling a > + power regulator. An example for such a hub is the Microchip > + USB2514B. > + > if USB_KEYBOARD > > config USB_KEYBOARD_FN_KEYS > diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c > index 060f3441df0c..f5dc93ffee39 100644 > --- a/drivers/usb/host/usb-uclass.c > +++ b/drivers/usb/host/usb-uclass.c > @@ -271,19 +271,23 @@ int usb_init(void) > /* init low_level USB */ > printf("Bus %s: ", bus->name); > > -#ifdef CONFIG_SANDBOX > /* > * For Sandbox, we need scan the device tree each time when we > * start the USB stack, in order to re-create the emulated USB > * devices and bind drivers for them before we actually do the > * driver probe. > + * > + * For USB onboard HUB, we need to do some non-trivial init > + * like enabling a power regulator, before enumeration. > */ > - ret = dm_scan_fdt_dev(bus); > - if (ret) { > - printf("Sandbox USB device scan failed (%d)\n", ret); > - continue; > + if (IS_ENABLED(CONFIG_SANDBOX) || > + IS_ENABLED(CONFIG_USB_ONBOARD_HUB)) { > + ret = dm_scan_fdt_dev(bus); > + if (ret) { > + printf("USB device scan from fdt failed (%d)", ret); > + continue; > + } > } > -#endif > > ret = device_probe(bus); > if (ret == -ENODEV) { /* No such device. */ Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com> Thanks Patrice
Hi, On 12/12/22 11:44, Fabrice Gasnier wrote: > The main issue the driver addresses is that a USB hub needs to be > powered before it can be discovered. This is often solved by using > "regulator-always-on". > > This driver is inspired by the Linux v6.1 driver. It only enables (or > disables) the hub vdd (3v3) supply, so it can be enumerated. > Scanning of the device tree is done in a similar manner to the sandbox, > by the usb-uclass. DT part looks like: > > &usbh_ehci { > ... > #address-cells = <1>; > #size-cells = <0>; > hub@1 { > compatible = "usb424,2514"; > reg = <1>; > vdd-supply = <&v3v3>; > }; > }; > > When the bus gets probed, the driver is automatically probed/removed from > the bus tree, as an example on stm32: > STM32MP> usb start > starting USB... > STM32MP> dm tree > Class Index Probed Driver Name > ----------------------------------------------------------- > usb 0 [ + ] ehci_generic | |-- usb@5800d000 > usb_hub 0 [ + ] usb_onboard_hub | | `-- hub@1 > usb_hub 1 [ + ] usb_hub | | `-- usb_hub > > STM32MP> usb tree > USB device tree: > 1 Hub (480 Mb/s, 0mA) > | u-boot EHCI Host Controller > | > +-2 Hub (480 Mb/s, 2mA) > > Signed-off-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com> > --- > > common/Makefile | 1 + > common/usb_onboard_hub.c | 62 +++++++++++++++++++++++++++++++++++ > drivers/usb/Kconfig | 10 ++++++ > drivers/usb/host/usb-uclass.c | 16 +++++---- > 4 files changed, 83 insertions(+), 6 deletions(-) > create mode 100644 common/usb_onboard_hub.c > Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com> Thanks Patrick
Hi Fabrice On 1/3/23 17:34, Patrick DELAUNAY wrote: > Hi, > > On 12/12/22 11:44, Fabrice Gasnier wrote: >> The main issue the driver addresses is that a USB hub needs to be >> powered before it can be discovered. This is often solved by using >> "regulator-always-on". >> >> This driver is inspired by the Linux v6.1 driver. It only enables (or >> disables) the hub vdd (3v3) supply, so it can be enumerated. >> Scanning of the device tree is done in a similar manner to the sandbox, >> by the usb-uclass. DT part looks like: >> >> &usbh_ehci { >> ... >> #address-cells = <1>; >> #size-cells = <0>; >> hub@1 { >> compatible = "usb424,2514"; >> reg = <1>; >> vdd-supply = <&v3v3>; >> }; >> }; >> >> When the bus gets probed, the driver is automatically probed/removed from >> the bus tree, as an example on stm32: >> STM32MP> usb start >> starting USB... >> STM32MP> dm tree >> Class Index Probed Driver Name >> ----------------------------------------------------------- >> usb 0 [ + ] ehci_generic | |-- usb@5800d000 >> usb_hub 0 [ + ] usb_onboard_hub | | `-- hub@1 >> usb_hub 1 [ + ] usb_hub | | `-- usb_hub >> >> STM32MP> usb tree >> USB device tree: >> 1 Hub (480 Mb/s, 0mA) >> | u-boot EHCI Host Controller >> | >> +-2 Hub (480 Mb/s, 2mA) >> >> Signed-off-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com> >> --- >> >> common/Makefile | 1 + >> common/usb_onboard_hub.c | 62 +++++++++++++++++++++++++++++++++++ >> drivers/usb/Kconfig | 10 ++++++ >> drivers/usb/host/usb-uclass.c | 16 +++++---- >> 4 files changed, 83 insertions(+), 6 deletions(-) >> create mode 100644 common/usb_onboard_hub.c >> > > Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com> > > Thanks > Patrick > > Applied on u-boot-stm32/master Thanks
On 1/12/23 16:24, Patrice CHOTARD wrote: > Hi Fabrice > > On 1/3/23 17:34, Patrick DELAUNAY wrote: >> Hi, >> >> On 12/12/22 11:44, Fabrice Gasnier wrote: >>> The main issue the driver addresses is that a USB hub needs to be >>> powered before it can be discovered. This is often solved by using >>> "regulator-always-on". >>> >>> This driver is inspired by the Linux v6.1 driver. It only enables (or >>> disables) the hub vdd (3v3) supply, so it can be enumerated. >>> Scanning of the device tree is done in a similar manner to the sandbox, >>> by the usb-uclass. DT part looks like: >>> >>> &usbh_ehci { >>> ... >>> #address-cells = <1>; >>> #size-cells = <0>; >>> hub@1 { >>> compatible = "usb424,2514"; >>> reg = <1>; >>> vdd-supply = <&v3v3>; >>> }; >>> }; >>> >>> When the bus gets probed, the driver is automatically probed/removed from >>> the bus tree, as an example on stm32: >>> STM32MP> usb start >>> starting USB... >>> STM32MP> dm tree >>> Class Index Probed Driver Name >>> ----------------------------------------------------------- >>> usb 0 [ + ] ehci_generic | |-- usb@5800d000 >>> usb_hub 0 [ + ] usb_onboard_hub | | `-- hub@1 >>> usb_hub 1 [ + ] usb_hub | | `-- usb_hub >>> >>> STM32MP> usb tree >>> USB device tree: >>> 1 Hub (480 Mb/s, 0mA) >>> | u-boot EHCI Host Controller >>> | >>> +-2 Hub (480 Mb/s, 2mA) >>> >>> Signed-off-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com> >>> --- >>> >>> common/Makefile | 1 + >>> common/usb_onboard_hub.c | 62 +++++++++++++++++++++++++++++++++++ >>> drivers/usb/Kconfig | 10 ++++++ >>> drivers/usb/host/usb-uclass.c | 16 +++++---- >>> 4 files changed, 83 insertions(+), 6 deletions(-) >>> create mode 100644 common/usb_onboard_hub.c >>> >> >> Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com> >> >> Thanks >> Patrick >> >> > > Applied on u-boot-stm32/master There is u-boot-usb tree for these patches and 1/3 should go through it.
On 12/12/22 11:44, Fabrice Gasnier wrote: > The main issue the driver addresses is that a USB hub needs to be > powered before it can be discovered. This is often solved by using > "regulator-always-on". > > This driver is inspired by the Linux v6.1 driver. It only enables (or > disables) the hub vdd (3v3) supply, so it can be enumerated. > Scanning of the device tree is done in a similar manner to the sandbox, > by the usb-uclass. DT part looks like: > > &usbh_ehci { > ... > #address-cells = <1>; > #size-cells = <0>; > hub@1 { > compatible = "usb424,2514"; > reg = <1>; > vdd-supply = <&v3v3>; > }; > }; > > When the bus gets probed, the driver is automatically probed/removed from > the bus tree, as an example on stm32: > STM32MP> usb start > starting USB... > STM32MP> dm tree > Class Index Probed Driver Name > ----------------------------------------------------------- > usb 0 [ + ] ehci_generic | |-- usb@5800d000 > usb_hub 0 [ + ] usb_onboard_hub | | `-- hub@1 > usb_hub 1 [ + ] usb_hub | | `-- usb_hub > > STM32MP> usb tree > USB device tree: > 1 Hub (480 Mb/s, 0mA) > | u-boot EHCI Host Controller > | > +-2 Hub (480 Mb/s, 2mA) > > Signed-off-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com> Reviewed-by: Marek Vasut <marex@denx.de>
diff --git a/common/Makefile b/common/Makefile index 20addfb244c2..7789aab484fd 100644 --- a/common/Makefile +++ b/common/Makefile @@ -26,6 +26,7 @@ obj-$(CONFIG_PHYLIB) += miiphyutil.o obj-$(CONFIG_USB_HOST) += usb.o usb_hub.o obj-$(CONFIG_USB_GADGET) += usb.o usb_hub.o obj-$(CONFIG_USB_STORAGE) += usb_storage.o +obj-$(CONFIG_USB_ONBOARD_HUB) += usb_onboard_hub.o # others obj-$(CONFIG_CONSOLE_MUX) += iomux.o diff --git a/common/usb_onboard_hub.c b/common/usb_onboard_hub.c new file mode 100644 index 000000000000..89e18a2ddad6 --- /dev/null +++ b/common/usb_onboard_hub.c @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Driver for onboard USB hubs + * + * Copyright (C) 2022, STMicroelectronics - All Rights Reserved + * + * Mostly inspired by Linux kernel v6.1 onboard_usb_hub driver + */ + +#include <common.h> +#include <dm.h> +#include <dm/device_compat.h> +#include <power/regulator.h> + +struct onboard_hub { + struct udevice *vdd; +}; + +static int usb_onboard_hub_probe(struct udevice *dev) +{ + struct onboard_hub *hub = dev_get_priv(dev); + int ret; + + ret = device_get_supply_regulator(dev, "vdd-supply", &hub->vdd); + if (ret) { + dev_err(dev, "can't get vdd-supply: %d\n", ret); + return ret; + } + + ret = regulator_set_enable_if_allowed(hub->vdd, true); + if (ret) + dev_err(dev, "can't enable vdd-supply: %d\n", ret); + + return ret; +} + +static int usb_onboard_hub_remove(struct udevice *dev) +{ + struct onboard_hub *hub = dev_get_priv(dev); + int ret; + + ret = regulator_set_enable_if_allowed(hub->vdd, false); + if (ret) + dev_err(dev, "can't disable vdd-supply: %d\n", ret); + + return ret; +} + +static const struct udevice_id usb_onboard_hub_ids[] = { + /* Use generic usbVID,PID dt-bindings (usb-device.yaml) */ + { .compatible = "usb424,2514" }, /* USB2514B USB 2.0 */ + { } +}; + +U_BOOT_DRIVER(usb_onboard_hub) = { + .name = "usb_onboard_hub", + .id = UCLASS_USB_HUB, + .probe = usb_onboard_hub_probe, + .remove = usb_onboard_hub_remove, + .of_match = usb_onboard_hub_ids, + .priv_auto = sizeof(struct onboard_hub), +}; diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 3afb45d5ccb2..d10ee6853d40 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -106,6 +106,16 @@ config USB_KEYBOARD Say Y here if you want to use a USB keyboard for U-Boot command line input. +config USB_ONBOARD_HUB + bool "Onboard USB hub support" + depends on DM_USB + ---help--- + Say Y here if you want to support discrete onboard USB hubs that + don't require an additional control bus for initialization, but + need some non-trivial form of initialization, such as enabling a + power regulator. An example for such a hub is the Microchip + USB2514B. + if USB_KEYBOARD config USB_KEYBOARD_FN_KEYS diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c index 060f3441df0c..f5dc93ffee39 100644 --- a/drivers/usb/host/usb-uclass.c +++ b/drivers/usb/host/usb-uclass.c @@ -271,19 +271,23 @@ int usb_init(void) /* init low_level USB */ printf("Bus %s: ", bus->name); -#ifdef CONFIG_SANDBOX /* * For Sandbox, we need scan the device tree each time when we * start the USB stack, in order to re-create the emulated USB * devices and bind drivers for them before we actually do the * driver probe. + * + * For USB onboard HUB, we need to do some non-trivial init + * like enabling a power regulator, before enumeration. */ - ret = dm_scan_fdt_dev(bus); - if (ret) { - printf("Sandbox USB device scan failed (%d)\n", ret); - continue; + if (IS_ENABLED(CONFIG_SANDBOX) || + IS_ENABLED(CONFIG_USB_ONBOARD_HUB)) { + ret = dm_scan_fdt_dev(bus); + if (ret) { + printf("USB device scan from fdt failed (%d)", ret); + continue; + } } -#endif ret = device_probe(bus); if (ret == -ENODEV) { /* No such device. */
The main issue the driver addresses is that a USB hub needs to be powered before it can be discovered. This is often solved by using "regulator-always-on". This driver is inspired by the Linux v6.1 driver. It only enables (or disables) the hub vdd (3v3) supply, so it can be enumerated. Scanning of the device tree is done in a similar manner to the sandbox, by the usb-uclass. DT part looks like: &usbh_ehci { ... #address-cells = <1>; #size-cells = <0>; hub@1 { compatible = "usb424,2514"; reg = <1>; vdd-supply = <&v3v3>; }; }; When the bus gets probed, the driver is automatically probed/removed from the bus tree, as an example on stm32: STM32MP> usb start starting USB... STM32MP> dm tree Class Index Probed Driver Name ----------------------------------------------------------- usb 0 [ + ] ehci_generic | |-- usb@5800d000 usb_hub 0 [ + ] usb_onboard_hub | | `-- hub@1 usb_hub 1 [ + ] usb_hub | | `-- usb_hub STM32MP> usb tree USB device tree: 1 Hub (480 Mb/s, 0mA) | u-boot EHCI Host Controller | +-2 Hub (480 Mb/s, 2mA) Signed-off-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com> --- common/Makefile | 1 + common/usb_onboard_hub.c | 62 +++++++++++++++++++++++++++++++++++ drivers/usb/Kconfig | 10 ++++++ drivers/usb/host/usb-uclass.c | 16 +++++---- 4 files changed, 83 insertions(+), 6 deletions(-) create mode 100644 common/usb_onboard_hub.c