[U-Boot] [PATCH v1 00/13] Introduce fastboot support for dragonboard410c

This set of patches introduce fastboot support for Qualcomm db410c. As part of the patch, a small quirk is added to ci_udc through a weaklly linked function.
Ramon Fried (13): ehci: Replace board_prepare_usb with board_usb_init ehci: msm: Add missing platdata dts: db410c: add alias for USB db410c: serial# env using msm board serial phy: db410c: Add MSM USB PHY driver dts: db410c: Add bindings for MSM USB phy configs: db410c: Enable USB PHY ehci: msm: switch to generic PHY uclass ehci: msm: use init_type in probe usb:ci_udc: Introduce init_after_reset phy function usb: ehci-msm: Add init_after_reset for CI_UDC DB410c: Enable fastboot support db410c: automatically launch fastboot
MAINTAINERS | 1 + arch/arm/dts/dragonboard410c.dts | 11 ++ arch/arm/mach-snapdragon/Kconfig | 1 + .../dragonboard410c/dragonboard410c.c | 17 ++- configs/dragonboard410c_defconfig | 11 ++ drivers/phy/Kconfig | 8 ++ drivers/phy/Makefile | 1 + drivers/phy/msm8916-usbh-phy.c | 109 ++++++++++++++++++ drivers/usb/gadget/ci_udc.c | 6 + drivers/usb/host/Kconfig | 3 +- drivers/usb/host/ehci-msm.c | 78 +++++-------- 11 files changed, 190 insertions(+), 56 deletions(-) create mode 100644 drivers/phy/msm8916-usbh-phy.c

Use standard board_usb_init() instead of the specific board_prepare_usb.
Signed-off-by: Ramon Fried ramon.fried@gmail.com
---
board/qualcomm/dragonboard410c/dragonboard410c.c | 4 ++-- drivers/usb/host/ehci-msm.c | 9 ++------- 2 files changed, 4 insertions(+), 9 deletions(-)
diff --git a/board/qualcomm/dragonboard410c/dragonboard410c.c b/board/qualcomm/dragonboard410c/dragonboard410c.c index 53e231e55a..e8a3ed0450 100644 --- a/board/qualcomm/dragonboard410c/dragonboard410c.c +++ b/board/qualcomm/dragonboard410c/dragonboard410c.c @@ -44,7 +44,7 @@ int dram_init_banksize(void) return 0; }
-int board_prepare_usb(enum usb_init_type type) +int board_usb_init(int index, enum usb_init_type init) { static struct udevice *pmic_gpio; static struct gpio_desc hub_reset, usb_sel; @@ -93,7 +93,7 @@ int board_prepare_usb(enum usb_init_type type) } }
- if (type == USB_INIT_HOST) { + if (init == USB_INIT_HOST) { /* Start USB Hub */ dm_gpio_set_dir_flags(&hub_reset, GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c index 17bfa7c02f..db982624dc 100644 --- a/drivers/usb/host/ehci-msm.c +++ b/drivers/usb/host/ehci-msm.c @@ -38,11 +38,6 @@ struct msm_ehci_priv { struct ulpi_viewport ulpi_vp; /* ULPI Viewport */ };
-int __weak board_prepare_usb(enum usb_init_type type) -{ - return 0; -} - static void setup_usb_phy(struct msm_ehci_priv *priv) { /* Select and enable external configuration with USB PHY */ @@ -102,7 +97,7 @@ static int ehci_usb_probe(struct udevice *dev) hcor = (struct ehci_hcor *)((phys_addr_t)hccr + HC_LENGTH(ehci_readl(&(hccr)->cr_capbase)));
- ret = board_prepare_usb(USB_INIT_HOST); + ret = board_usb_init(0, USB_INIT_HOST); if (ret < 0) return ret;
@@ -124,7 +119,7 @@ static int ehci_usb_remove(struct udevice *dev)
reset_usb_phy(p);
- ret = board_prepare_usb(USB_INIT_DEVICE); /* Board specific hook */ + ret = board_usb_init(0, USB_INIT_DEVICE); /* Board specific hook */ if (ret < 0) return ret;

platdata_auto_alloc_size was not initialized in structure. Caused null pointer dereference when configuring device as gadget.
Signed-off-by: Ramon Fried ramon.fried@gmail.com ---
drivers/usb/host/ehci-msm.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c index db982624dc..e7fb76d6da 100644 --- a/drivers/usb/host/ehci-msm.c +++ b/drivers/usb/host/ehci-msm.c @@ -167,5 +167,6 @@ U_BOOT_DRIVER(usb_ehci) = { .remove = ehci_usb_remove, .ops = &ehci_usb_ops, .priv_auto_alloc_size = sizeof(struct msm_ehci_priv), + .platdata_auto_alloc_size = sizeof(struct usb_platdata), .flags = DM_FLAG_ALLOC_PRIV_DMA, };

Alias is required so req-seq will be filled.
Signed-off-by: Ramon Fried ramon.fried@gmail.com ---
arch/arm/dts/dragonboard410c.dts | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/arch/arm/dts/dragonboard410c.dts b/arch/arm/dts/dragonboard410c.dts index f4f7c350ec..75f28300b7 100644 --- a/arch/arm/dts/dragonboard410c.dts +++ b/arch/arm/dts/dragonboard410c.dts @@ -18,6 +18,10 @@ #address-cells = <0x2>; #size-cells = <0x2>;
+ aliases { + usb0 = "/soc/ehci@78d9000"; + }; + memory { device_type = "memory"; reg = <0 0x80000000 0 0x3da00000>;

This should go into a -u-boot.dtsi file so that the dragonboard410c.dts can be synced from the linux kernel without change.
Peter
On Wed, Sep 19, 2018 at 7:31 PM Ramon Fried ramon.fried@gmail.com wrote:
Alias is required so req-seq will be filled.
Signed-off-by: Ramon Fried ramon.fried@gmail.com
arch/arm/dts/dragonboard410c.dts | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/arch/arm/dts/dragonboard410c.dts b/arch/arm/dts/dragonboard410c.dts index f4f7c350ec..75f28300b7 100644 --- a/arch/arm/dts/dragonboard410c.dts +++ b/arch/arm/dts/dragonboard410c.dts @@ -18,6 +18,10 @@ #address-cells = <0x2>; #size-cells = <0x2>;
aliases {
usb0 = "/soc/ehci@78d9000";
};
memory { device_type = "memory"; reg = <0 0x80000000 0 0x3da00000>;
-- 2.18.0
U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot

On Wed, Sep 19, 2018 at 10:28 PM Peter Robinson pbrobinson@gmail.com wrote:
This should go into a -u-boot.dtsi file so that the dragonboard410c.dts can be synced from the linux kernel without change.
Hi Peter. I thought that -u-boot.dtsi is only for u-boot specific stuff, The alias is not specific to u-boot AFAIK. I'll look how other boards handle that. Thanks, Ramon.
Peter
On Wed, Sep 19, 2018 at 7:31 PM Ramon Fried ramon.fried@gmail.com wrote:
Alias is required so req-seq will be filled.
Signed-off-by: Ramon Fried ramon.fried@gmail.com
arch/arm/dts/dragonboard410c.dts | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/arch/arm/dts/dragonboard410c.dts b/arch/arm/dts/dragonboard410c.dts index f4f7c350ec..75f28300b7 100644 --- a/arch/arm/dts/dragonboard410c.dts +++ b/arch/arm/dts/dragonboard410c.dts @@ -18,6 +18,10 @@ #address-cells = <0x2>; #size-cells = <0x2>;
aliases {
usb0 = "/soc/ehci@78d9000";
};
memory { device_type = "memory"; reg = <0 0x80000000 0 0x3da00000>;
-- 2.18.0
U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot

This should go into a -u-boot.dtsi file so that the dragonboard410c.dts can be synced from the linux kernel without change.
Hi Peter. I thought that -u-boot.dtsi is only for u-boot specific stuff, The alias is not specific to u-boot AFAIK.
Yes, I did wonder if some of these changes should also into linux.
Peter
I'll look how other boards handle that. Thanks, Ramon.
Peter
On Wed, Sep 19, 2018 at 7:31 PM Ramon Fried ramon.fried@gmail.com wrote:
Alias is required so req-seq will be filled.
Signed-off-by: Ramon Fried ramon.fried@gmail.com
arch/arm/dts/dragonboard410c.dts | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/arch/arm/dts/dragonboard410c.dts b/arch/arm/dts/dragonboard410c.dts index f4f7c350ec..75f28300b7 100644 --- a/arch/arm/dts/dragonboard410c.dts +++ b/arch/arm/dts/dragonboard410c.dts @@ -18,6 +18,10 @@ #address-cells = <0x2>; #size-cells = <0x2>;
aliases {
usb0 = "/soc/ehci@78d9000";
};
memory { device_type = "memory"; reg = <0 0x80000000 0 0x3da00000>;
-- 2.18.0
U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot

The serial# environment variable needs to be defined so it will be used by fastboot as serial for the endpoint descriptor.
Signed-off-by: Ramon Fried ramon.fried@gmail.com ---
arch/arm/mach-snapdragon/Kconfig | 1 + board/qualcomm/dragonboard410c/dragonboard410c.c | 10 ++++++++++ 2 files changed, 11 insertions(+)
diff --git a/arch/arm/mach-snapdragon/Kconfig b/arch/arm/mach-snapdragon/Kconfig index bfd99db6e2..e562d693c6 100644 --- a/arch/arm/mach-snapdragon/Kconfig +++ b/arch/arm/mach-snapdragon/Kconfig @@ -14,6 +14,7 @@ choice
config TARGET_DRAGONBOARD410C bool "96Boards Dragonboard 410C" + select BOARD_LATE_INIT help Support for 96Boards Dragonboard 410C. This board complies with 96Board Open Platform Specifications. Features: diff --git a/board/qualcomm/dragonboard410c/dragonboard410c.c b/board/qualcomm/dragonboard410c/dragonboard410c.c index e8a3ed0450..b2a72bce38 100644 --- a/board/qualcomm/dragonboard410c/dragonboard410c.c +++ b/board/qualcomm/dragonboard410c/dragonboard410c.c @@ -151,6 +151,16 @@ int board_init(void) return 0; }
+int board_late_init(void) +{ + char serial[16]; + + memset(serial, 0, 16); + snprintf(serial, 13, "%x", msm_board_serial()); + env_set("serial#", serial); + return 0; +} + /* Fixup of DTB for Linux Kernel * 1. Fixup installed DRAM. * 2. Fixup WLAN/BT Mac address:

Add a PHY driver for the Qualcomm dragonboard 410c which allows switching on/off and resetting the phy connected to the EHCI controllers and USBHS controller.
Signed-off-by: Ramon Fried ramon.fried@gmail.com ---
MAINTAINERS | 1 + drivers/phy/Kconfig | 8 +++ drivers/phy/Makefile | 1 + drivers/phy/msm8916-usbh-phy.c | 109 +++++++++++++++++++++++++++++++++ 4 files changed, 119 insertions(+) create mode 100644 drivers/phy/msm8916-usbh-phy.c
diff --git a/MAINTAINERS b/MAINTAINERS index 39d28e5d45..1a5b543dc7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -209,6 +209,7 @@ S: Maintained F: arch/arm/mach-snapdragon/ F: drivers/gpio/msm_gpio.c F: drivers/mmc/msm_sdhci.c +F: drivers/phy/msm8916-usbh-phy.c F: drivers/serial/serial_msm.c F: drivers/smem/msm_smem.c F: drivers/usb/host/ehci-msm.c diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index e0822bb775..bcc8e22795 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -139,4 +139,12 @@ config MESON_GXL_USB_PHY This is the generic phy driver for the Amlogic Meson GXL USB2 and USB3 PHYS.
+config MSM8916_USB_PHY + bool "Qualcomm MSM8916 USB PHY support" + depends on PHY + help + Support the USB PHY in msm8916 + + This PHY is found on qualcomm dragonboard410c development board. + endmenu diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index 178fb4530e..1e1e4ca11e 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -15,3 +15,4 @@ obj-$(CONFIG_STI_USB_PHY) += sti_usb_phy.o obj-$(CONFIG_PHY_RCAR_GEN2) += phy-rcar-gen2.o obj-$(CONFIG_PHY_STM32_USBPHYC) += phy-stm32-usbphyc.o obj-$(CONFIG_MESON_GXL_USB_PHY) += meson-gxl-usb2.o meson-gxl-usb3.o +obj-$(CONFIG_MSM8916_USB_PHY) += msm8916-usbh-phy.o diff --git a/drivers/phy/msm8916-usbh-phy.c b/drivers/phy/msm8916-usbh-phy.c new file mode 100644 index 0000000000..2c90738fca --- /dev/null +++ b/drivers/phy/msm8916-usbh-phy.c @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Ramon Fried ramon.fried@gmail.com + */ + +#include <common.h> +#include <dm.h> +#include <generic-phy.h> +#include <usb/ehci-ci.h> +#include <usb/ulpi.h> +#include <asm/io.h> + +/* PHY viewport regs */ +#define ULPI_MISC_A_READ 0x96 +#define ULPI_MISC_A_SET 0x97 +#define ULPI_MISC_A_CLEAR 0x98 +#define ULPI_MISC_A_VBUSVLDEXT BIT(0) +#define ULPI_MISC_A_VBUSVLDEXTSEL BIT(1) +#define GEN2_SESS_VLD_CTRL_EN BIT(7) +#define SESS_VLD_CTRL BIT(25) + +struct msm_phy_priv { + void __iomem *regs; + struct usb_ehci *ehci; /* Start of IP core*/ + struct ulpi_viewport ulpi_vp; /* ULPI Viewport */ +}; + +static int msm_phy_power_on(struct phy *phy) +{ + struct msm_phy_priv *priv = dev_get_priv(phy->dev); + + /* Select and enable external configuration with USB PHY */ + ulpi_write(&priv->ulpi_vp, (u8 *)ULPI_MISC_A_SET, + ULPI_MISC_A_VBUSVLDEXTSEL | ULPI_MISC_A_VBUSVLDEXT); + + return 0; +} + +static int msm_phy_power_off(struct phy *phy) +{ + struct msm_phy_priv *priv = dev_get_priv(phy->dev); + + /* Disable VBUS mimicing in the controller. */ + ulpi_write(&priv->ulpi_vp, (u8 *)ULPI_MISC_A_CLEAR, + ULPI_MISC_A_VBUSVLDEXTSEL | ULPI_MISC_A_VBUSVLDEXT); + return 0; +} + +static int msm_phy_reset(struct phy *phy) +{ + struct msm_phy_priv *p = dev_get_priv(phy->dev); + + /* select ULPI phy */ + writel(PORT_PTS_ULPI, &p->ehci->portsc); + + /* Enable sess_vld */ + setbits_le32(&p->ehci->genconfig2, GEN2_SESS_VLD_CTRL_EN); + + /* Enable external vbus configuration in the LINK */ + setbits_le32(&p->ehci->usbcmd, SESS_VLD_CTRL); + + /* USB_OTG_HS_AHB_BURST */ + writel(0x0, &p->ehci->sbuscfg); + + /* USB_OTG_HS_AHB_MODE: HPROT_MODE */ + /* Bus access related config. */ + writel(0x08, &p->ehci->sbusmode); + + return 0; +} + +static int msm_phy_probe(struct udevice *dev) +{ + struct msm_phy_priv *priv = dev_get_priv(dev); + + priv->regs = dev_remap_addr(dev); + if (!priv->regs) + return -EINVAL; + + priv->ehci = (struct usb_ehci *)priv->regs; + priv->ulpi_vp.port_num = 0; + + /* Warning: this will not work if viewport address is > 64 bit due to + * ULPI design. + */ + priv->ulpi_vp.viewport_addr = (phys_addr_t)&priv->ehci->ulpi_viewpoint; + + return 0; +} + +static struct phy_ops msm_phy_ops = { + .power_on = msm_phy_power_on, + .power_off = msm_phy_power_off, + .reset = msm_phy_reset, +}; + +static const struct udevice_id msm_phy_ids[] = { + { .compatible = "qcom,apq8016-usbphy" }, + { } +}; + +U_BOOT_DRIVER(msm8916_usbphy) = { + .name = "msm8916_usbphy", + .id = UCLASS_PHY, + .of_match = msm_phy_ids, + .ops = &msm_phy_ops, + .probe = msm_phy_probe, + .priv_auto_alloc_size = sizeof(struct msm_phy_priv), +};

Signed-off-by: Ramon Fried ramon.fried@gmail.com ---
arch/arm/dts/dragonboard410c.dts | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/arch/arm/dts/dragonboard410c.dts b/arch/arm/dts/dragonboard410c.dts index 75f28300b7..fa348bc621 100644 --- a/arch/arm/dts/dragonboard410c.dts +++ b/arch/arm/dts/dragonboard410c.dts @@ -97,6 +97,13 @@ ehci@78d9000 { compatible = "qcom,ehci-host"; reg = <0x78d9000 0x400>; + phys = <&ehci_phy>; + }; + + ehci_phy: ehci_phy@78d9000 { + compatible = "qcom,apq8016-usbphy"; + reg = <0x78d9000 0x400>; + #phy-cells = <0>; };
sdhci@07824000 {

Enable USB PHY driver. Also fixed the alphabetically ordering of the config.
Signed-off-by: Ramon Fried ramon.fried@gmail.com ---
configs/dragonboard410c_defconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/configs/dragonboard410c_defconfig b/configs/dragonboard410c_defconfig index 96a831443a..0d9008deb7 100644 --- a/configs/dragonboard410c_defconfig +++ b/configs/dragonboard410c_defconfig @@ -29,6 +29,7 @@ CONFIG_LED_GPIO=y CONFIG_DM_MMC=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_MSM=y +CONFIG_PHY=y CONFIG_PINCTRL=y CONFIG_PINCONF=y CONFIG_DM_PMIC=y

All the underlying USB PHY was handled in the ehci driver. Use the generic phy API instead.
Signed-off-by: Ramon Fried ramon.fried@gmail.com ---
drivers/usb/host/Kconfig | 3 +-- drivers/usb/host/ehci-msm.c | 52 +++++++------------------------------ 2 files changed, 10 insertions(+), 45 deletions(-)
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index b4dd005651..a213c918bc 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -167,12 +167,11 @@ config USB_EHCI_MSM bool "Support for Qualcomm on-chip EHCI USB controller" depends on DM_USB select USB_ULPI_VIEWPORT + select MSM8916_USB_PHY default n ---help--- Enables support for the on-chip EHCI controller on Qualcomm Snapdragon SoCs. - This driver supports combination of Chipidea USB controller - and Synapsys USB PHY in host mode only.
config USB_EHCI_PCI bool "Support for PCI-based EHCI USB controller" diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c index e7fb76d6da..a27a5833dd 100644 --- a/drivers/usb/host/ehci-msm.c +++ b/drivers/usb/host/ehci-msm.c @@ -21,59 +21,19 @@ #include <linux/compat.h> #include "ehci.h"
-/* PHY viewport regs */ -#define ULPI_MISC_A_READ 0x96 -#define ULPI_MISC_A_SET 0x97 -#define ULPI_MISC_A_CLEAR 0x98 -#define ULPI_MISC_A_VBUSVLDEXTSEL (1 << 1) -#define ULPI_MISC_A_VBUSVLDEXT (1 << 0) - -#define GEN2_SESS_VLD_CTRL_EN (1 << 7) - -#define SESS_VLD_CTRL (1 << 25) - struct msm_ehci_priv { struct ehci_ctrl ctrl; /* Needed by EHCI */ struct usb_ehci *ehci; /* Start of IP core*/ struct ulpi_viewport ulpi_vp; /* ULPI Viewport */ + struct phy phy; };
-static void setup_usb_phy(struct msm_ehci_priv *priv) -{ - /* Select and enable external configuration with USB PHY */ - ulpi_write(&priv->ulpi_vp, (u8 *)ULPI_MISC_A_SET, - ULPI_MISC_A_VBUSVLDEXTSEL | ULPI_MISC_A_VBUSVLDEXT); -} - -static void reset_usb_phy(struct msm_ehci_priv *priv) -{ - /* Disable VBUS mimicing in the controller. */ - ulpi_write(&priv->ulpi_vp, (u8 *)ULPI_MISC_A_CLEAR, - ULPI_MISC_A_VBUSVLDEXTSEL | ULPI_MISC_A_VBUSVLDEXT); -} - - static int msm_init_after_reset(struct ehci_ctrl *dev) { struct msm_ehci_priv *p = container_of(dev, struct msm_ehci_priv, ctrl); struct usb_ehci *ehci = p->ehci;
- /* select ULPI phy */ - writel(PORT_PTS_ULPI, &ehci->portsc); - setup_usb_phy(p); - - /* Enable sess_vld */ - setbits_le32(&ehci->genconfig2, GEN2_SESS_VLD_CTRL_EN); - - /* Enable external vbus configuration in the LINK */ - setbits_le32(&ehci->usbcmd, SESS_VLD_CTRL); - - /* USB_OTG_HS_AHB_BURST */ - writel(0x0, &ehci->sbuscfg); - - /* USB_OTG_HS_AHB_MODE: HPROT_MODE */ - /* Bus access related config. */ - writel(0x08, &ehci->sbusmode); + generic_phy_reset(&p->phy);
/* set mode to host controller */ writel(CM_HOST, &ehci->usbmode); @@ -97,6 +57,10 @@ static int ehci_usb_probe(struct udevice *dev) hcor = (struct ehci_hcor *)((phys_addr_t)hccr + HC_LENGTH(ehci_readl(&(hccr)->cr_capbase)));
+ ret = ehci_setup_phy(dev, &p->phy, 0); + if (ret) + return ret; + ret = board_usb_init(0, USB_INIT_HOST); if (ret < 0) return ret; @@ -117,7 +81,9 @@ static int ehci_usb_remove(struct udevice *dev) /* Stop controller. */ clrbits_le32(&ehci->usbcmd, CMD_RUN);
- reset_usb_phy(p); + ret = ehci_shutdown_phy(dev, &p->phy); + if (ret) + return ret;
ret = board_usb_init(0, USB_INIT_DEVICE); /* Board specific hook */ if (ret < 0)

Change ehci_usb_probe() function to initialize the USB according to the init_type provided.
Signed-off-by: Ramon Fried ramon.fried@gmail.com ---
drivers/usb/host/ehci-msm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c index a27a5833dd..00d6bb8231 100644 --- a/drivers/usb/host/ehci-msm.c +++ b/drivers/usb/host/ehci-msm.c @@ -49,6 +49,7 @@ static int ehci_usb_probe(struct udevice *dev) { struct msm_ehci_priv *p = dev_get_priv(dev); struct usb_ehci *ehci = p->ehci; + struct usb_platdata *plat = dev_get_platdata(dev); struct ehci_hccr *hccr; struct ehci_hcor *hcor; int ret; @@ -61,11 +62,12 @@ static int ehci_usb_probe(struct udevice *dev) if (ret) return ret;
- ret = board_usb_init(0, USB_INIT_HOST); + ret = board_usb_init(0, plat->init_type); if (ret < 0) return ret;
- return ehci_register(dev, hccr, hcor, &msm_ehci_ops, 0, USB_INIT_HOST); + return ehci_register(dev, hccr, hcor, &msm_ehci_ops, 0, + plat->init_type); }
static int ehci_usb_remove(struct udevice *dev)

MSM variant of Chipidea must reinitalize the phy after controller reset. Introduce ci_init_after_reset() weak function that can be used to achieve the above init.
Signed-off-by: Ramon Fried ramon.fried@gmail.com ---
drivers/usb/gadget/ci_udc.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/drivers/usb/gadget/ci_udc.c b/drivers/usb/gadget/ci_udc.c index 2b9dbf06b9..8d23fab3b7 100644 --- a/drivers/usb/gadget/ci_udc.c +++ b/drivers/usb/gadget/ci_udc.c @@ -104,6 +104,10 @@ static struct usb_ep_ops ci_ep_ops = { .free_request = ci_ep_free_request, };
+__weak void ci_init_after_reset(struct ehci_ctrl *ctrl) +{ +} + /* Init values for USB endpoints. */ static const struct usb_ep ci_ep_init[5] = { [0] = { /* EP 0 */ @@ -887,6 +891,8 @@ static int ci_pullup(struct usb_gadget *gadget, int is_on) writel(USBCMD_ITC(MICRO_8FRAME) | USBCMD_RST, &udc->usbcmd); udelay(200);
+ ci_init_after_reset(controller.ctrl); + writel((unsigned long)controller.epts, &udc->epinitaddr);
/* select DEVICE mode */

MSM uses the chipidea controller IP, however it requires to reinit the phy after controller reset. in EHCI mode there's a dedicated callback for it. In device mode however there's no such callback. Add implementaion of ci_init_after_reset() to implement the above requirement in case CI_UDC driver is used.
Signed-off-by: Ramon Fried ramon.fried@gmail.com ---
drivers/usb/host/ehci-msm.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c index 00d6bb8231..5c257ccf4d 100644 --- a/drivers/usb/host/ehci-msm.c +++ b/drivers/usb/host/ehci-msm.c @@ -121,6 +121,18 @@ static int ehci_usb_ofdata_to_platdata(struct udevice *dev) return 0; }
+#if defined(CONFIG_CI_UDC) +/* Little quirk that MSM needs with Chipidea controller + * Must reinit phy after reset + */ +void ci_init_after_reset(struct ehci_ctrl *ctrl) +{ + struct msm_ehci_priv *p = ctrl->priv; + + generic_phy_reset(&p->phy); +} +#endif + static const struct udevice_id ehci_usb_ids[] = { { .compatible = "qcom,ehci-host", }, { }

Signed-off-by: Ramon Fried ramon.fried@gmail.com ---
configs/dragonboard410c_defconfig | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/configs/dragonboard410c_defconfig b/configs/dragonboard410c_defconfig index 0d9008deb7..a55abaf8df 100644 --- a/configs/dragonboard410c_defconfig +++ b/configs/dragonboard410c_defconfig @@ -4,6 +4,7 @@ CONFIG_SYS_TEXT_BASE=0x80080000 CONFIG_IDENT_STRING="\nQualcomm-DragonBoard 410C" CONFIG_DISTRO_DEFAULTS=y CONFIG_NR_DRAM_BANKS=1 +# CONFIG_ANDROID_BOOT_IMAGE is not set CONFIG_FIT=y CONFIG_OF_BOARD_SETUP=y CONFIG_MISC_INIT_R=y @@ -22,6 +23,10 @@ CONFIG_CMD_TIMER=y CONFIG_DEFAULT_DEVICE_TREE="dragonboard410c" CONFIG_ENV_IS_IN_MMC=y CONFIG_CLK=y +CONFIG_USB_FUNCTION_FASTBOOT=y +CONFIG_FASTBOOT_BUF_ADDR=0x91000000 +CONFIG_FASTBOOT_FLASH=y +CONFIG_FASTBOOT_FLASH_MMC_DEV=0 CONFIG_MSM_GPIO=y CONFIG_PM8916_GPIO=y CONFIG_LED=y @@ -43,6 +48,11 @@ CONFIG_USB_EHCI_MSM=y CONFIG_USB_ULPI_VIEWPORT=y CONFIG_USB_ULPI=y CONFIG_USB_STORAGE=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_VENDOR_NUM=0x18d1 +CONFIG_USB_GADGET_PRODUCT_NUM=0xd00d +CONFIG_CI_UDC=y +CONFIG_USB_GADGET_DUALSPEED=n CONFIG_USB_HOST_ETHER=y CONFIG_USB_ETHER_ASIX=y CONFIG_USB_ETHER_ASIX88179=y

If during boot the key-vol-down press is detected we'll fall back to fastboot.
Signed-off-by: Ramon Fried ramon.fried@gmail.com ---
board/qualcomm/dragonboard410c/dragonboard410c.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/board/qualcomm/dragonboard410c/dragonboard410c.c b/board/qualcomm/dragonboard410c/dragonboard410c.c index b2a72bce38..9ceed3ad9b 100644 --- a/board/qualcomm/dragonboard410c/dragonboard410c.c +++ b/board/qualcomm/dragonboard410c/dragonboard410c.c @@ -140,7 +140,8 @@ int misc_init_r(void)
if (dm_gpio_get_value(&resin)) { env_set("bootdelay", "-1"); - printf("Power button pressed - dropping to console.\n"); + env_set("bootcmd", "fastboot 0"); + printf("key_vol_down pressed - Starting fastboot.\n"); }
return 0;
participants (2)
-
Peter Robinson
-
Ramon Fried