Merge branch 'master' of git://git.denx.de/u-boot-usb
authorTom Rini <trini@konsulko.com>
Sun, 21 Apr 2019 23:00:04 +0000 (19:00 -0400)
committerTom Rini <trini@konsulko.com>
Sun, 21 Apr 2019 23:00:04 +0000 (19:00 -0400)
- Various fastboot, dwc2/stm32 updates

39 files changed:
arch/arm/dts/stm32mp157-pinctrl.dtsi
arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi
arch/arm/dts/stm32mp157a-dk1.dts
arch/arm/dts/stm32mp157c-ed1.dts
arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi
arch/arm/dts/stm32mp157c.dtsi
board/st/stm32mp1/stm32mp1.c
cmd/dfu.c
cmd/usb_mass_storage.c
configs/am335x_boneblack_vboot_defconfig
configs/am335x_evm_defconfig
configs/am335x_hs_evm_defconfig
configs/am335x_hs_evm_uart_defconfig
configs/brppt1_mmc_defconfig
configs/brppt1_nand_defconfig
configs/brppt1_spi_defconfig
configs/chiliboard_defconfig
configs/stm32mp15_basic_defconfig
configs/stm32mp15_trusted_defconfig
doc/device-tree-bindings/phy/phy-stm32-usbphyc.txt
doc/device-tree-bindings/usb/dwc2.txt [new file with mode: 0644]
drivers/fastboot/fb_getvar.c
drivers/fastboot/fb_mmc.c
drivers/phy/phy-stm32-usbphyc.c
drivers/usb/gadget/dwc2_udc_otg.c
drivers/usb/gadget/dwc2_udc_otg_priv.h
drivers/usb/gadget/dwc2_udc_otg_regs.h
drivers/usb/gadget/dwc2_udc_otg_xfer_dma.c
drivers/usb/musb-new/Kconfig
include/configs/am335x_evm.h
include/configs/baltos.h
include/configs/bav335x.h
include/configs/brppt1.h
include/configs/brxre1.h
include/configs/chiliboard.h
include/configs/pengwyn.h
include/configs/siemens-am33x-common.h
include/usb/dwc2_udc.h
scripts/config_whitelist.txt

index c06987548612083159bf7bb3d7fbd3539f35b5cf..0aae69b0a04818a8e94075dfdf7ba3d8d88bc9d6 100644 (file)
                                };
                        };
 
+                       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 */
index af7acfa0375d0a13800bed69022abf78591de334..0f32a38dc9476d050ac815f6a5ce02a738004166 100644 (file)
@@ -11,6 +11,7 @@
        aliases {
                i2c3 = &i2c4;
                mmc0 = &sdmmc1;
+               usb0 = &usbotg_hs;
        };
        config {
                u-boot,boot-led = "heartbeat";
 };
 
 &usbotg_hs {
-       usb1600;
+       u-boot,force-b-session-valid;
        hnp-srp-disable;
 };
 
index 0882765d0c9a7f1535ef6c9de697f8b5696bfbab..e36773dde917ecbf91691c9b32f23f8fc3d8ceb1 100644 (file)
        /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>;
        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>;
index 2664c9ce904d07b410602b53fb277571c4882d7e..0366782fda9b1b49b73a60d24798dcd400e03067 100644 (file)
        status = "okay";
 };
 
-&usbotg_hs {
-       usb33d-supply = <&usb33>;
-};
-
 &usbphyc_port0 {
        phy-supply = <&vdd_usb>;
-       vdda1v1-supply = <&reg11>;
-       vdda1v8-supply = <&reg18>;
 };
 
 &usbphyc_port1 {
        phy-supply = <&vdd_usb>;
-       vdda1v1-supply = <&reg11>;
-       vdda1v8-supply = <&reg18>;
 };
index 8b92b1fa2eeea286f1ce7728906517e57b9bafde..5b19e44d2fb4627d9448bd61d7ab2ee6ef44ee78 100644 (file)
@@ -12,6 +12,7 @@
                i2c4 = &i2c5;
                pinctrl2 = &stmfx_pinctrl;
                spi0 = &qspi;
+               usb0 = &usbotg_hs;
        };
 };
 
index 7eb4bee31cfcacc08d1bcc2f75d440286c9302fb..94634336a5e17eb5dadfd4dcfdadedb8363a00be 100644 (file)
                };
 
                usbotg_hs: usb-otg@49000000 {
-                       compatible = "snps,dwc2";
+                       compatible = "st,stm32mp1-hsotg", "snps,dwc2";
                        reg = <0x49000000 0x10000>;
                        clocks = <&rcc USBO_K>;
                        clock-names = "otg";
                        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";
                };
 
                        reg = <0x5a006000 0x1000>;
                        clocks = <&rcc USBPHY_K>;
                        resets = <&rcc USBPHY_R>;
+                       vdda1v1-supply = <&reg11>;
+                       vdda1v8-supply = <&reg18>;
                        status = "disabled";
 
                        usbphyc_port0: usb-phy@0 {
index 24d299ac33bddf7803ce129e23d12aee85793dc0..76917b022ede019176244bdd007b8f3b9b74c8d7 100644 (file)
@@ -7,7 +7,9 @@
 #include <config.h>
 #include <clk.h>
 #include <dm.h>
+#include <g_dnl.h>
 #include <generic-phy.h>
+#include <i2c.h>
 #include <led.h>
 #include <misc.h>
 #include <phy.h>
  */
 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 +152,75 @@ 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;
+/* STMicroelectronics STUSB1600 Type-C controller */
+#define STUSB1600_CC_CONNECTION_STATUS         0x0E
 
-int board_usb_init(int index, enum usb_init_type init)
+/* STUSB1600_CC_CONNECTION_STATUS bitfields */
+#define STUSB1600_CC_ATTACH                    BIT(0)
+
+static int stusb1600_init(struct udevice **dev_stusb1600)
 {
-       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;
+       ofnode node;
+       struct udevice *dev, *bus;
        int ret;
+       u32 chip_addr;
 
-       /* 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;
-       }
+       *dev_stusb1600 = NULL;
 
-       if (!fdtdec_get_is_enabled(blob, node)) {
-               debug("stm32 usbotg is disabled in the device tree\n");
+       /* if node stusb1600 is present, means DK1 or DK2 board */
+       node = ofnode_by_compatible(ofnode_null(), "st,stusb1600");
+       if (!ofnode_valid(node))
                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);
+       ret = ofnode_read_u32(node, "reg", &chip_addr);
        if (ret)
-               return ret;
+               return -EINVAL;
 
-       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);
+       ret = uclass_get_device_by_ofnode(UCLASS_I2C, ofnode_get_parent(node),
+                                         &bus);
        if (ret) {
-               debug("usbotg has no resets defined in the device tree\n");
-               goto clk_err;
+               printf("bus for stusb1600 not found\n");
+               return -ENODEV;
        }
 
-       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 = dm_i2c_probe(bus, chip_addr, 0, &dev);
+       if (!ret)
+               *dev_stusb1600 = dev;
 
-               ret = generic_phy_init(&phy);
-               if (ret) {
-                       debug("failed to init usb phy\n");
-                       goto phy_power_err;
-               }
-       }
+       return ret;
+}
 
-       /* 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;
-       }
+static int stusb1600_cable_connected(struct udevice *dev)
+{
+       u8 status;
 
-       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);
+       if (dm_i2c_read(dev, STUSB1600_CC_CONNECTION_STATUS, &status, 1))
+               return 0;
 
-       return dwc2_udc_probe(&stm32mp_otg_data);
+       return status & STUSB1600_CC_ATTACH;
+}
 
-phy_init_err:
-       generic_phy_exit(&phy);
+#include <usb/dwc2_udc.h>
+int g_dnl_board_usb_cable_connected(void)
+{
+       struct udevice *stusb1600;
+       struct udevice *dwc2_udc_otg;
+       int ret;
 
-phy_power_err:
-       generic_phy_power_off(&phy);
+       if (!stusb1600_init(&stusb1600))
+               return stusb1600_cable_connected(stusb1600);
 
-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 +361,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
index c9ba0621970d4386a529403084ba96e37f7d9b6f..91a750a4fcaac1a688bd950713ce2ef1fb732c8c 100644 (file)
--- a/cmd/dfu.c
+++ b/cmd/dfu.c
@@ -27,8 +27,10 @@ static int do_dfu(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 #ifdef CONFIG_DFU_OVER_USB
        char *usb_controller = argv[1];
 #endif
+#if defined(CONFIG_DFU_OVER_USB) || defined(CONFIG_DFU_OVER_TFTP)
        char *interface = argv[2];
        char *devstring = argv[3];
+#endif
 
        int ret = 0;
 #ifdef CONFIG_DFU_OVER_TFTP
@@ -63,6 +65,7 @@ done:
 
 U_BOOT_CMD(dfu, CONFIG_SYS_MAXARGS, 1, do_dfu,
        "Device Firmware Upgrade",
+       ""
 #ifdef CONFIG_DFU_OVER_USB
        "<USB_controller> <interface> <dev> [list]\n"
        "  - device firmware upgrade via <USB_controller>\n"
index 753ae4f42a7a0bd3671032f14ddfb61a82205a71..570cf3aa508bd03828b1b654043d844feb237ab2 100644 (file)
@@ -14,6 +14,7 @@
 #include <part.h>
 #include <usb.h>
 #include <usb_mass_storage.h>
+#include <watchdog.h>
 
 static int ums_read_sector(struct ums *ums_dev,
                           ulong start, lbaint_t blkcnt, void *buf)
@@ -226,6 +227,8 @@ static int do_usb_mass_storage(cmd_tbl_t *cmdtp, int flag,
                        rc = CMD_RET_SUCCESS;
                        goto cleanup_register;
                }
+
+               WATCHDOG_RESET();
        }
 
 cleanup_register:
index 6afda7245372f49583e0322e15b5d9a6e86370cd..ffe013fa2df7d7b136c66fb523e9e67764ac7d81 100644 (file)
@@ -56,7 +56,6 @@ CONFIG_SPL_DM_USB_GADGET=y
 CONFIG_USB_MUSB_HOST=y
 CONFIG_USB_MUSB_GADGET=y
 CONFIG_USB_MUSB_TI=y
-CONFIG_USB_MUSB_DSPS=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
 CONFIG_USB_GADGET_VENDOR_NUM=0x0451
index a396a3931050f83d6843b53a453797234e70c2f5..105ff01d14de3f0d6ee58becb2bb8fe47da7a8a5 100644 (file)
@@ -64,7 +64,6 @@ CONFIG_SPL_DM_USB_GADGET=y
 CONFIG_USB_MUSB_HOST=y
 CONFIG_USB_MUSB_GADGET=y
 CONFIG_USB_MUSB_TI=y
-CONFIG_USB_MUSB_DSPS=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
 CONFIG_USB_GADGET_VENDOR_NUM=0x0451
index 1746df90f411bcb79008e63220050d83bc3b9a0e..a37966bc6dcb3038e4e5a004abed4d8f3424db29 100644 (file)
@@ -60,7 +60,6 @@ CONFIG_DM_USB=y
 CONFIG_USB_MUSB_HOST=y
 CONFIG_USB_MUSB_GADGET=y
 CONFIG_USB_MUSB_TI=y
-CONFIG_USB_MUSB_DSPS=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
 CONFIG_USB_GADGET_VENDOR_NUM=0x0451
index d2d6f2fb6e4d11595d256642c1742e08f817864b..ff131eb60178d60d04b1c7e2037b19f25823bcaa 100644 (file)
@@ -62,7 +62,6 @@ CONFIG_DM_USB=y
 CONFIG_USB_MUSB_HOST=y
 CONFIG_USB_MUSB_GADGET=y
 CONFIG_USB_MUSB_TI=y
-CONFIG_USB_MUSB_DSPS=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
 CONFIG_USB_GADGET_VENDOR_NUM=0x0451
index 6b0d0242f2ebd5bb94e59543513032deb3b1ee48..63cb240ea89b1af23bd997a925f49da6ff806dba 100644 (file)
@@ -84,7 +84,6 @@ CONFIG_DM_USB=y
 CONFIG_USB_MUSB_HOST=y
 CONFIG_USB_MUSB_GADGET=y
 CONFIG_USB_MUSB_TI=y
-CONFIG_USB_MUSB_DSPS=y
 CONFIG_USB_STORAGE=y
 CONFIG_USB_GADGET=y
 CONFIG_FAT_WRITE=y
index 4578f74a62089265a9991d9f772097ac5e7d125b..57cd54bac26da6e16ee3d26ac551ce550999646a 100644 (file)
@@ -88,7 +88,6 @@ CONFIG_DM_USB=y
 CONFIG_USB_MUSB_HOST=y
 CONFIG_USB_MUSB_GADGET=y
 CONFIG_USB_MUSB_TI=y
-CONFIG_USB_MUSB_DSPS=y
 CONFIG_USB_STORAGE=y
 CONFIG_USB_GADGET=y
 CONFIG_FAT_WRITE=y
index 739b0786f34a8810dfbe3b6fd3d324e9bb14dab7..31ba5158b5865f9abd2f38b43dfb0ad8d83bc312 100644 (file)
@@ -99,7 +99,6 @@ CONFIG_DM_USB=y
 CONFIG_USB_MUSB_HOST=y
 CONFIG_USB_MUSB_GADGET=y
 CONFIG_USB_MUSB_TI=y
-CONFIG_USB_MUSB_DSPS=y
 CONFIG_USB_STORAGE=y
 CONFIG_USB_GADGET=y
 CONFIG_FAT_WRITE=y
index a6c36eda503d7377e698b15b4a76449459d293fb..944dd0db3c87164461bb909f1527020ca88b3324 100644 (file)
@@ -50,6 +50,5 @@ CONFIG_USB=y
 CONFIG_DM_USB=y
 CONFIG_USB_MUSB_HOST=y
 CONFIG_USB_MUSB_TI=y
-CONFIG_USB_MUSB_DSPS=y
 CONFIG_FAT_WRITE=y
 CONFIG_LZO=y
index 6781adb81e738a3f46e232eea9ceabca98b7df80..fd164fa596ddc66f181a793f4cddb5f9e7f00317 100644 (file)
@@ -69,9 +69,9 @@ 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_DWC2=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_MANUFACTURER="STMicroelectronics"
 CONFIG_USB_GADGET_VENDOR_NUM=0x0483
index a050cee6918e871c4f105c9c8c94d02cc3d2c75c..f82b770bc873a798326af54d028da3c61a99231d 100644 (file)
@@ -60,9 +60,9 @@ 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_DWC2=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_MANUFACTURER="STMicroelectronics"
 CONFIG_USB_GADGET_VENDOR_NUM=0x0483
index 725ae71ae6535a0bdb8ccbf2ed83e168d3002d56..da98407403d5509190fe95aff5a07155711f3f65 100644 (file)
@@ -23,6 +23,8 @@ Required properties:
 - compatible: must be "st,stm32mp1-usbphyc"
 - reg: address and length of the usb phy control register set
 - clocks: phandle + clock specifier for the PLL phy clock
+- vdda1v1-supply: phandle to the regulator providing 1V1 power to the PHY
+- vdda1v8-supply: phandle to the regulator providing 1V8 power to the PHY
 - #address-cells: number of address cells for phys sub-nodes, must be <1>
 - #size-cells: number of size cells for phys sub-nodes, must be <0>
 
@@ -40,8 +42,6 @@ Required properties:
 - reg: phy port index
 - phy-supply: phandle to the regulator providing 3V3 power to the PHY,
              see phy-bindings.txt in the same directory.
-- vdda1v1-supply: phandle to the regulator providing 1V1 power to the PHY
-- vdda1v8-supply: phandle to the regulator providing 1V8 power to the PHY
 - #phy-cells: see phy-bindings.txt in the same directory, must be <0> for PHY
   port#1 and must be <1> for PHY port#2, to select USB controller
 
diff --git a/doc/device-tree-bindings/usb/dwc2.txt b/doc/device-tree-bindings/usb/dwc2.txt
new file mode 100644 (file)
index 0000000..61493f7
--- /dev/null
@@ -0,0 +1,58 @@
+Platform DesignWare HS OTG USB 2.0 controller
+-----------------------------------------------------
+
+Required properties:
+- compatible : One of:
+  - brcm,bcm2835-usb: The DWC2 USB controller instance in the BCM2835 SoC.
+  - hisilicon,hi6220-usb: The DWC2 USB controller instance in the hi6220 SoC.
+  - rockchip,rk3066-usb: The DWC2 USB controller instance in the rk3066 Soc;
+  - "rockchip,px30-usb", "rockchip,rk3066-usb", "snps,dwc2": for px30 Soc;
+  - "rockchip,rk3188-usb", "rockchip,rk3066-usb", "snps,dwc2": for rk3188 Soc;
+  - "rockchip,rk3288-usb", "rockchip,rk3066-usb", "snps,dwc2": for rk3288 Soc;
+  - "lantiq,arx100-usb": The DWC2 USB controller instance in Lantiq ARX SoCs;
+  - "lantiq,xrx200-usb": The DWC2 USB controller instance in Lantiq XRX SoCs;
+  - "amlogic,meson8-usb": The DWC2 USB controller instance in Amlogic Meson8 SoCs;
+  - "amlogic,meson8b-usb": The DWC2 USB controller instance in Amlogic Meson8b SoCs;
+  - "amlogic,meson-gxbb-usb": The DWC2 USB controller instance in Amlogic S905 SoCs;
+  - "amcc,dwc-otg": The DWC2 USB controller instance in AMCC Canyonlands 460EX SoCs;
+  - snps,dwc2: A generic DWC2 USB controller with default parameters.
+  - "st,stm32f4x9-fsotg": The DWC2 USB FS/HS controller instance in STM32F4x9 SoCs
+  configured in FS mode;
+  - "st,stm32f4x9-hsotg": The DWC2 USB HS controller instance in STM32F4x9 SoCs
+  configured in HS mode;
+  - "st,stm32f7-hsotg": The DWC2 USB HS controller instance in STM32F7 SoCs
+    configured in HS mode;
+- reg : Should contain 1 register range (address and length)
+- interrupts : Should contain 1 interrupt
+- clocks: clock provider specifier
+- clock-names: shall be "otg"
+Refer to clk/clock-bindings.txt for generic clock consumer properties
+
+Optional properties:
+- phys: phy provider specifier
+- phy-names: shall be "usb2-phy"
+Refer to phy/phy-bindings.txt for generic phy consumer properties
+- dr_mode: shall be one of "host", "peripheral" and "otg"
+  Refer to usb/generic.txt
+- g-rx-fifo-size: size of rx fifo size in gadget mode.
+- g-np-tx-fifo-size: size of non-periodic tx fifo size in gadget mode.
+- 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
+
+Example:
+
+        usb@101c0000 {
+                compatible = "ralink,rt3050-usb, snps,dwc2";
+                reg = <0x101c0000 40000>;
+                interrupts = <18>;
+               clocks = <&usb_otg_ahb_clk>;
+               clock-names = "otg";
+               phys = <&usbphy>;
+               phy-names = "usb2-phy";
+        };
index 4d264c985d7e9593932b270c98a0477f126cc52e..4268628f5ef0210507c5d23f2e4209b2afc07029 100644 (file)
@@ -17,6 +17,7 @@ static void getvar_downloadsize(char *var_parameter, char *response);
 static void getvar_serialno(char *var_parameter, char *response);
 static void getvar_version_baseband(char *var_parameter, char *response);
 static void getvar_product(char *var_parameter, char *response);
+static void getvar_platform(char *var_parameter, char *response);
 static void getvar_current_slot(char *var_parameter, char *response);
 static void getvar_slot_suffixes(char *var_parameter, char *response);
 static void getvar_has_slot(char *var_parameter, char *response);
@@ -55,6 +56,9 @@ static const struct {
        }, {
                .variable = "product",
                .dispatch = getvar_product
+       }, {
+               .variable = "platform",
+               .dispatch = getvar_platform
        }, {
                .variable = "current-slot",
                .dispatch = getvar_current_slot
@@ -62,7 +66,7 @@ static const struct {
                .variable = "slot-suffixes",
                .dispatch = getvar_slot_suffixes
        }, {
-               .variable = "has_slot",
+               .variable = "has-slot",
                .dispatch = getvar_has_slot
 #if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
        }, {
@@ -117,6 +121,16 @@ static void getvar_product(char *var_parameter, char *response)
                fastboot_fail("Board not set", response);
 }
 
+static void getvar_platform(char *var_parameter, char *response)
+{
+       const char *p = env_get("platform");
+
+       if (p)
+               fastboot_okay(p, response);
+       else
+               fastboot_fail("platform not set", response);
+}
+
 static void getvar_current_slot(char *var_parameter, char *response)
 {
        /* A/B not implemented, for now always return _a */
index 4c1c7fd2cd8d08d1c90817beadb2341827d4cb24..90ca81da9b5f338f09a27873fb142d142a07933e 100644 (file)
@@ -31,13 +31,13 @@ static int part_get_info_by_name_or_alias(struct blk_desc *dev_desc,
 
        ret = part_get_info_by_name(dev_desc, name, info);
        if (ret < 0) {
-               /* strlen("fastboot_partition_alias_") + 32(part_name) + 1 */
-               char env_alias_name[25 + 32 + 1];
+               /* strlen("fastboot_partition_alias_") + PART_NAME_LEN + 1 */
+               char env_alias_name[25 + PART_NAME_LEN + 1];
                char *aliased_part_name;
 
                /* check for alias */
                strcpy(env_alias_name, "fastboot_partition_alias_");
-               strncat(env_alias_name, name, 32);
+               strncat(env_alias_name, name, PART_NAME_LEN);
                aliased_part_name = env_get(env_alias_name);
                if (aliased_part_name != NULL)
                        ret = part_get_info_by_name(dev_desc,
@@ -308,8 +308,8 @@ int fastboot_mmc_get_part_info(char *part_name, struct blk_desc **dev_desc,
                fastboot_fail("block device not found", response);
                return -ENOENT;
        }
-       if (!part_name) {
-               fastboot_fail("partition not found", response);
+       if (!part_name || !strcmp(part_name, "")) {
+               fastboot_fail("partition not given", response);
                return -ENOENT;
        }
 
index 8e98b4b627bf6cef5046484a21c9b7d169911297..6f1119036d787573bfab94ab803587087c238616 100644 (file)
@@ -37,7 +37,8 @@
 
 #define MAX_PHYS               2
 
-#define PLL_LOCK_TIME_US       100
+/* max 100 us for PLL lock and 100 us for PHY init */
+#define PLL_INIT_TIME_US       200
 #define PLL_PWR_DOWN_TIME_US   5
 #define PLL_FVCO               2880     /* in MHz */
 #define PLL_INFF_MIN_RATE      19200000 /* in Hz */
@@ -51,17 +52,17 @@ struct pll_params {
 struct stm32_usbphyc {
        fdt_addr_t base;
        struct clk clk;
+       struct udevice *vdda1v1;
+       struct udevice *vdda1v8;
        struct stm32_usbphyc_phy {
                struct udevice *vdd;
-               struct udevice *vdda1v1;
-               struct udevice *vdda1v8;
-               int index;
                bool init;
                bool powered;
        } phys[MAX_PHYS];
 };
 
-void stm32_usbphyc_get_pll_params(u32 clk_rate, struct pll_params *pll_params)
+static void stm32_usbphyc_get_pll_params(u32 clk_rate,
+                                        struct pll_params *pll_params)
 {
        unsigned long long fvco, ndiv, frac;
 
@@ -154,6 +155,18 @@ static int stm32_usbphyc_phy_init(struct phy *phy)
        if (pllen && stm32_usbphyc_is_init(usbphyc))
                goto initialized;
 
+       if (usbphyc->vdda1v1) {
+               ret = regulator_set_enable(usbphyc->vdda1v1, true);
+               if (ret)
+                       return ret;
+       }
+
+       if (usbphyc->vdda1v8) {
+               ret = regulator_set_enable(usbphyc->vdda1v8, true);
+               if (ret)
+                       return ret;
+       }
+
        if (pllen) {
                clrbits_le32(usbphyc->base + STM32_USBPHYC_PLL, PLLEN);
                udelay(PLL_PWR_DOWN_TIME_US);
@@ -165,11 +178,8 @@ static int stm32_usbphyc_phy_init(struct phy *phy)
 
        setbits_le32(usbphyc->base + STM32_USBPHYC_PLL, PLLEN);
 
-       /*
-        * We must wait PLL_LOCK_TIME_US before checking that PLLEN
-        * bit is still set
-        */
-       udelay(PLL_LOCK_TIME_US);
+       /* We must wait PLL_INIT_TIME_US before using PHY */
+       udelay(PLL_INIT_TIME_US);
 
        if (!(readl(usbphyc->base + STM32_USBPHYC_PLL) & PLLEN))
                return -EIO;
@@ -184,6 +194,7 @@ static int stm32_usbphyc_phy_exit(struct phy *phy)
 {
        struct stm32_usbphyc *usbphyc = dev_get_priv(phy->dev);
        struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + phy->id;
+       int ret;
 
        pr_debug("%s phy ID = %lu\n", __func__, phy->id);
        usbphyc_phy->init = false;
@@ -203,6 +214,18 @@ static int stm32_usbphyc_phy_exit(struct phy *phy)
        if (readl(usbphyc->base + STM32_USBPHYC_PLL) & PLLEN)
                return -EIO;
 
+       if (usbphyc->vdda1v1) {
+               ret = regulator_set_enable(usbphyc->vdda1v1, false);
+               if (ret)
+                       return ret;
+       }
+
+       if (usbphyc->vdda1v8) {
+               ret = regulator_set_enable(usbphyc->vdda1v8, false);
+               if (ret)
+                       return ret;
+       }
+
        return 0;
 }
 
@@ -213,17 +236,6 @@ static int stm32_usbphyc_phy_power_on(struct phy *phy)
        int ret;
 
        pr_debug("%s phy ID = %lu\n", __func__, phy->id);
-       if (usbphyc_phy->vdda1v1) {
-               ret = regulator_set_enable(usbphyc_phy->vdda1v1, true);
-               if (ret)
-                       return ret;
-       }
-
-       if (usbphyc_phy->vdda1v8) {
-               ret = regulator_set_enable(usbphyc_phy->vdda1v8, true);
-               if (ret)
-                       return ret;
-       }
        if (usbphyc_phy->vdd) {
                ret = regulator_set_enable(usbphyc_phy->vdd, true);
                if (ret)
@@ -247,18 +259,6 @@ static int stm32_usbphyc_phy_power_off(struct phy *phy)
        if (stm32_usbphyc_is_powered(usbphyc))
                return 0;
 
-       if (usbphyc_phy->vdda1v1) {
-               ret = regulator_set_enable(usbphyc_phy->vdda1v1, false);
-               if (ret)
-                       return ret;
-       }
-
-       if (usbphyc_phy->vdda1v8) {
-               ret = regulator_set_enable(usbphyc_phy->vdda1v8, false);
-               if (ret)
-                       return ret;
-       }
-
        if (usbphyc_phy->vdd) {
                ret = regulator_set_enable(usbphyc_phy->vdd, false);
                if (ret)
@@ -298,19 +298,20 @@ static int stm32_usbphyc_get_regulator(struct udevice *dev, ofnode node,
 static int stm32_usbphyc_of_xlate(struct phy *phy,
                                  struct ofnode_phandle_args *args)
 {
-       if (args->args_count > 1) {
-               pr_debug("%s: invalid args_count: %d\n", __func__,
-                        args->args_count);
-               return -EINVAL;
-       }
+       if (args->args_count < 1)
+               return -ENODEV;
 
        if (args->args[0] >= MAX_PHYS)
                return -ENODEV;
 
-       if (args->args_count)
-               phy->id = args->args[0];
-       else
-               phy->id = 0;
+       phy->id = args->args[0];
+
+       if ((phy->id == 0 && args->args_count != 1) ||
+           (phy->id == 1 && args->args_count != 2)) {
+               dev_err(dev, "invalid number of cells for phy port%ld\n",
+                       phy->id);
+               return -EINVAL;
+       }
 
        return 0;
 }
@@ -351,6 +352,21 @@ static int stm32_usbphyc_probe(struct udevice *dev)
                reset_deassert(&reset);
        }
 
+       /* get usbphyc regulator */
+       ret = device_get_supply_regulator(dev, "vdda1v1-supply",
+                                         &usbphyc->vdda1v1);
+       if (ret) {
+               dev_err(dev, "Can't get vdda1v1-supply regulator\n");
+               return ret;
+       }
+
+       ret = device_get_supply_regulator(dev, "vdda1v8-supply",
+                                         &usbphyc->vdda1v8);
+       if (ret) {
+               dev_err(dev, "Can't get vdda1v8-supply regulator\n");
+               return ret;
+       }
+
        /*
         * parse all PHY subnodes in order to populate regulator associated
         * to each PHY port
@@ -359,7 +375,6 @@ static int stm32_usbphyc_probe(struct udevice *dev)
        for (i = 0; i < MAX_PHYS; i++) {
                struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + i;
 
-               usbphyc_phy->index = i;
                usbphyc_phy->init = false;
                usbphyc_phy->powered = false;
                ret = stm32_usbphyc_get_regulator(dev, node, "phy-supply",
@@ -367,16 +382,6 @@ static int stm32_usbphyc_probe(struct udevice *dev)
                if (ret)
                        return ret;
 
-               ret = stm32_usbphyc_get_regulator(dev, node, "vdda1v1-supply",
-                                                 &usbphyc_phy->vdda1v1);
-               if (ret)
-                       return ret;
-
-               ret = stm32_usbphyc_get_regulator(dev, node, "vdda1v8-supply",
-                                                 &usbphyc_phy->vdda1v8);
-               if (ret)
-                       return ret;
-
                node = dev_read_next_subnode(node);
        }
 
index 3c7ad033e3f799ae1a085c7bb7e15f60cef355f6..494ab533cca31a3c19b530ed44d2545625e4168d 100644 (file)
  */
 #undef DEBUG
 #include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <generic-phy.h>
+#include <malloc.h>
+#include <reset.h>
+
 #include <linux/errno.h>
 #include <linux/list.h>
-#include <malloc.h>
 
 #include <linux/usb/ch9.h>
+#include <linux/usb/otg.h>
 #include <linux/usb/gadget.h>
 
 #include <asm/byteorder.h>
@@ -31,6 +37,8 @@
 
 #include <asm/mach-types.h>
 
+#include <power/regulator.h>
+
 #include "dwc2_udc_otg_regs.h"
 #include "dwc2_udc_otg_priv.h"
 
@@ -140,7 +148,6 @@ static struct usb_ep_ops dwc2_ep_ops = {
 
 /***********************************************************/
 
-void __iomem           *regs_otg;
 struct dwc2_usbotg_reg *reg;
 
 bool dfu_usb_get_reset(void)
@@ -223,6 +230,7 @@ static int udc_enable(struct dwc2_udc *dev)
        return 0;
 }
 
+#if !CONFIG_IS_ENABLED(DM_USB_GADGET)
 /*
   Register entry point for the peripheral controller driver.
 */
@@ -297,6 +305,54 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
        udc_disable(dev);
        return 0;
 }
+#else /* !CONFIG_IS_ENABLED(DM_USB_GADGET) */
+
+static int dwc2_gadget_start(struct usb_gadget *g,
+                            struct usb_gadget_driver *driver)
+{
+       struct dwc2_udc *dev = the_controller;
+
+       debug_cond(DEBUG_SETUP != 0, "%s: %s\n", __func__, "no name");
+
+       if (!driver ||
+           (driver->speed != USB_SPEED_FULL &&
+            driver->speed != USB_SPEED_HIGH) ||
+           !driver->bind || !driver->disconnect || !driver->setup)
+               return -EINVAL;
+
+       if (!dev)
+               return -ENODEV;
+
+       if (dev->driver)
+               return -EBUSY;
+
+       /* first hook up the driver ... */
+       dev->driver = driver;
+
+       debug_cond(DEBUG_SETUP != 0,
+                  "Registered gadget driver %s\n", dev->gadget.name);
+       return udc_enable(dev);
+}
+
+static int dwc2_gadget_stop(struct usb_gadget *g)
+{
+       struct dwc2_udc *dev = the_controller;
+
+       if (!dev)
+               return -ENODEV;
+
+       if (!dev->driver)
+               return -EINVAL;
+
+       dev->driver = 0;
+       stop_activity(dev, dev->driver);
+
+       udc_disable(dev);
+
+       return 0;
+}
+
+#endif /* !CONFIG_IS_ENABLED(DM_USB_GADGET) */
 
 /*
  *     done - retire a request; caller blocked irqs
@@ -400,6 +456,8 @@ static void reconfig_usbd(struct dwc2_udc *dev)
        unsigned int uTemp = writel(CORE_SOFT_RESET, &reg->grstctl);
        uint32_t dflt_gusbcfg;
        uint32_t rx_fifo_sz, tx_fifo_sz, np_tx_fifo_sz;
+       u32 max_hw_ep;
+       int pdata_hw_ep;
 
        debug("Reseting OTG controller\n");
 
@@ -482,10 +540,23 @@ static void reconfig_usbd(struct dwc2_udc *dev)
        writel((np_tx_fifo_sz << 16) | rx_fifo_sz,
               &reg->gnptxfsiz);
 
-       for (i = 1; i < DWC2_MAX_HW_ENDPOINTS; i++)
-               writel((rx_fifo_sz + np_tx_fifo_sz + tx_fifo_sz*(i-1)) |
-                       tx_fifo_sz << 16, &reg->dieptxf[i-1]);
+       /* retrieve the number of IN Endpoints (excluding ep0) */
+       max_hw_ep = (readl(&reg->ghwcfg4) & GHWCFG4_NUM_IN_EPS_MASK) >>
+                   GHWCFG4_NUM_IN_EPS_SHIFT;
+       pdata_hw_ep = dev->pdata->tx_fifo_sz_nb;
+
+       /* tx_fifo_sz_nb should equal to number of IN Endpoint */
+       if (pdata_hw_ep && max_hw_ep != pdata_hw_ep)
+               pr_warn("Got %d hw endpoint but %d tx-fifo-size in array !!\n",
+                       max_hw_ep, pdata_hw_ep);
+
+       for (i = 0; i < max_hw_ep; i++) {
+               if (pdata_hw_ep)
+                       tx_fifo_sz = dev->pdata->tx_fifo_sz_array[i];
 
+               writel((rx_fifo_sz + np_tx_fifo_sz + (tx_fifo_sz * i)) |
+                       tx_fifo_sz << 16, &reg->dieptxf[i]);
+       }
        /* Flush the RX FIFO */
        writel(RX_FIFO_FLUSH, &reg->grstctl);
        while (readl(&reg->grstctl) & RX_FIFO_FLUSH)
@@ -731,6 +802,10 @@ static void dwc2_fifo_flush(struct usb_ep *_ep)
 
 static const struct usb_gadget_ops dwc2_udc_ops = {
        /* current versions must always be self-powered */
+#if CONFIG_IS_ENABLED(DM_USB_GADGET)
+       .udc_start              = dwc2_gadget_start,
+       .udc_stop               = dwc2_gadget_stop,
+#endif
 };
 
 static struct dwc2_udc memory = {
@@ -818,8 +893,6 @@ int dwc2_udc_probe(struct dwc2_plat_otg_data *pdata)
 
        reg = (struct dwc2_usbotg_reg *)pdata->regs_otg;
 
-       /* regs_otg = (void *)pdata->regs_otg; */
-
        dev->gadget.is_dualspeed = 1;   /* Hack only*/
        dev->gadget.is_otg = 0;
        dev->gadget.is_a_peripheral = 0;
@@ -844,12 +917,311 @@ int dwc2_udc_probe(struct dwc2_plat_otg_data *pdata)
        return retval;
 }
 
-int usb_gadget_handle_interrupts(int index)
+int dwc2_udc_handle_interrupt(void)
 {
        u32 intr_status = readl(&reg->gintsts);
        u32 gintmsk = readl(&reg->gintmsk);
 
        if (intr_status & gintmsk)
                return dwc2_udc_irq(1, (void *)the_controller);
+
+       return 0;
+}
+
+#if !CONFIG_IS_ENABLED(DM_USB_GADGET)
+
+int usb_gadget_handle_interrupts(int index)
+{
+       return dwc2_udc_handle_interrupt();
+}
+
+#else /* CONFIG_IS_ENABLED(DM_USB_GADGET) */
+
+struct dwc2_priv_data {
+       struct clk_bulk         clks;
+       struct reset_ctl_bulk   resets;
+       struct phy *phys;
+       int num_phys;
+       struct udevice *usb33d_supply;
+};
+
+int dm_usb_gadget_handle_interrupts(struct udevice *dev)
+{
+       return dwc2_udc_handle_interrupt();
+}
+
+int dwc2_phy_setup(struct udevice *dev, struct phy **array, int *num_phys)
+{
+       int i, ret, count;
+       struct phy *usb_phys;
+
+       /* Return if no phy declared */
+       if (!dev_read_prop(dev, "phys", NULL))
+               return 0;
+
+       count = dev_count_phandle_with_args(dev, "phys", "#phy-cells");
+       if (count <= 0)
+               return count;
+
+       usb_phys = devm_kcalloc(dev, count, sizeof(struct phy),
+                               GFP_KERNEL);
+       if (!usb_phys)
+               return -ENOMEM;
+
+       for (i = 0; i < count; i++) {
+               ret = generic_phy_get_by_index(dev, i, &usb_phys[i]);
+               if (ret && ret != -ENOENT) {
+                       dev_err(dev, "Failed to get USB PHY%d for %s\n",
+                               i, dev->name);
+                       return ret;
+               }
+       }
+
+       for (i = 0; i < count; i++) {
+               ret = generic_phy_init(&usb_phys[i]);
+               if (ret) {
+                       dev_err(dev, "Can't init USB PHY%d for %s\n",
+                               i, dev->name);
+                       goto phys_init_err;
+               }
+       }
+
+       for (i = 0; i < count; i++) {
+               ret = generic_phy_power_on(&usb_phys[i]);
+               if (ret) {
+                       dev_err(dev, "Can't power USB PHY%d for %s\n",
+                               i, dev->name);
+                       goto phys_poweron_err;
+               }
+       }
+
+       *array = usb_phys;
+       *num_phys =  count;
+
        return 0;
+
+phys_poweron_err:
+       for (i = count - 1; i >= 0; i--)
+               generic_phy_power_off(&usb_phys[i]);
+
+       for (i = 0; i < count; i++)
+               generic_phy_exit(&usb_phys[i]);
+
+       return ret;
+
+phys_init_err:
+       for (; i >= 0; i--)
+               generic_phy_exit(&usb_phys[i]);
+
+       return ret;
+}
+
+void dwc2_phy_shutdown(struct udevice *dev, struct phy *usb_phys, int num_phys)
+{
+       int i, ret;
+
+       for (i = 0; i < num_phys; i++) {
+               if (!generic_phy_valid(&usb_phys[i]))
+                       continue;
+
+               ret = generic_phy_power_off(&usb_phys[i]);
+               ret |= generic_phy_exit(&usb_phys[i]);
+               if (ret) {
+                       dev_err(dev, "Can't shutdown USB PHY%d for %s\n",
+                               i, dev->name);
+               }
+       }
+}
+
+static int dwc2_udc_otg_ofdata_to_platdata(struct udevice *dev)
+{
+       struct dwc2_plat_otg_data *platdata = dev_get_platdata(dev);
+       int node = dev_of_offset(dev);
+       ulong drvdata;
+       void (*set_params)(struct dwc2_plat_otg_data *data);
+
+       if (usb_get_dr_mode(node) != USB_DR_MODE_PERIPHERAL) {
+               dev_dbg(dev, "Invalid mode\n");
+               return -ENODEV;
+       }
+
+       platdata->regs_otg = dev_read_addr(dev);
+
+       platdata->rx_fifo_sz = dev_read_u32_default(dev, "g-rx-fifo-size", 0);
+       platdata->np_tx_fifo_sz = dev_read_u32_default(dev,
+                                                      "g-np-tx-fifo-size", 0);
+       platdata->tx_fifo_sz = dev_read_u32_default(dev, "g-tx-fifo-size", 0);
+
+       platdata->force_b_session_valid =
+               dev_read_bool(dev, "u-boot,force-b-session-valid");
+
+       /* force platdata according compatible */
+       drvdata = dev_get_driver_data(dev);
+       if (drvdata) {
+               set_params = (void *)drvdata;
+               set_params(platdata);
+       }
+
+       return 0;
+}
+
+static void dwc2_set_stm32mp1_hsotg_params(struct dwc2_plat_otg_data *p)
+{
+       p->activate_stm_id_vb_detection = true;
+       p->usb_gusbcfg =
+               0 << 15         /* PHY Low Power Clock sel*/
+               | 0x9 << 10     /* USB Turnaround time (0x9 for HS phy) */
+               | 0 << 9        /* [0:HNP disable,1:HNP enable]*/
+               | 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,
+                                  struct reset_ctl_bulk *resets)
+{
+       int ret;
+
+       ret = reset_get_bulk(dev, resets);
+       if (ret == -ENOTSUPP)
+               return 0;
+
+       if (ret)
+               return ret;
+
+       ret = reset_assert_bulk(resets);
+
+       if (!ret) {
+               udelay(2);
+               ret = reset_deassert_bulk(resets);
+       }
+       if (ret) {
+               reset_release_bulk(resets);
+               return ret;
+       }
+
+       return 0;
+}
+
+static int dwc2_udc_otg_clk_init(struct udevice *dev,
+                                struct clk_bulk *clks)
+{
+       int ret;
+
+       ret = clk_get_bulk(dev, clks);
+       if (ret == -ENOSYS)
+               return 0;
+
+       if (ret)
+               return ret;
+
+       ret = clk_enable_bulk(clks);
+       if (ret) {
+               clk_release_bulk(clks);
+               return ret;
+       }
+
+       return 0;
+}
+
+static int dwc2_udc_otg_probe(struct udevice *dev)
+{
+       struct dwc2_plat_otg_data *platdata = dev_get_platdata(dev);
+       struct dwc2_priv_data *priv = dev_get_priv(dev);
+       struct dwc2_usbotg_reg *usbotg_reg =
+               (struct dwc2_usbotg_reg *)platdata->regs_otg;
+       int ret;
+
+       ret = dwc2_udc_otg_clk_init(dev, &priv->clks);
+       if (ret)
+               return ret;
+
+       ret = dwc2_udc_otg_reset_init(dev, &priv->resets);
+       if (ret)
+               return ret;
+
+       ret = dwc2_phy_setup(dev, &priv->phys, &priv->num_phys);
+       if (ret)
+               return ret;
+
+       if (CONFIG_IS_ENABLED(DM_REGULATOR) &&
+           platdata->activate_stm_id_vb_detection &&
+           !platdata->force_b_session_valid) {
+               ret = device_get_supply_regulator(dev, "usb33d-supply",
+                                                 &priv->usb33d_supply);
+               if (ret) {
+                       dev_err(dev, "can't get voltage level detector supply\n");
+                       return ret;
+               }
+               ret = regulator_set_enable(priv->usb33d_supply, true);
+               if (ret) {
+                       dev_err(dev, "can't enable voltage level detector supply\n");
+                       return ret;
+               }
+               /* Enable vbus sensing */
+               setbits_le32(&usbotg_reg->ggpio,
+                            GGPIO_STM32_OTG_GCCFG_VBDEN |
+                            GGPIO_STM32_OTG_GCCFG_IDEN);
+       }
+
+       if (platdata->force_b_session_valid)
+               /* Override B session bits : value and enable */
+               setbits_le32(&usbotg_reg->gotgctl,
+                            A_VALOEN | A_VALOVAL | B_VALOEN | B_VALOVAL);
+
+       ret = dwc2_udc_probe(platdata);
+       if (ret)
+               return ret;
+
+       the_controller->driver = 0;
+
+       ret = usb_add_gadget_udc((struct device *)dev, &the_controller->gadget);
+
+       return ret;
+}
+
+static int dwc2_udc_otg_remove(struct udevice *dev)
+{
+       struct dwc2_priv_data *priv = dev_get_priv(dev);
+
+       usb_del_gadget_udc(&the_controller->gadget);
+
+       reset_release_bulk(&priv->resets);
+
+       clk_release_bulk(&priv->clks);
+
+       dwc2_phy_shutdown(dev, priv->phys, priv->num_phys);
+
+       return dm_scan_fdt_dev(dev);
+}
+
+static const struct udevice_id dwc2_udc_otg_ids[] = {
+       { .compatible = "snps,dwc2" },
+       { .compatible = "st,stm32mp1-hsotg",
+         .data = (ulong)dwc2_set_stm32mp1_hsotg_params },
+       {},
+};
+
+U_BOOT_DRIVER(dwc2_udc_otg) = {
+       .name   = "dwc2-udc-otg",
+       .id     = UCLASS_USB_GADGET_GENERIC,
+       .of_match = dwc2_udc_otg_ids,
+       .ofdata_to_platdata = dwc2_udc_otg_ofdata_to_platdata,
+       .probe = dwc2_udc_otg_probe,
+       .remove = dwc2_udc_otg_remove,
+       .platdata_auto_alloc_size = sizeof(struct dwc2_plat_otg_data),
+       .priv_auto_alloc_size = sizeof(struct dwc2_priv_data),
+};
+
+int dwc2_udc_B_session_valid(struct udevice *dev)
+{
+       struct dwc2_plat_otg_data *platdata = dev_get_platdata(dev);
+       struct dwc2_usbotg_reg *usbotg_reg =
+               (struct dwc2_usbotg_reg *)platdata->regs_otg;
+
+       return readl(&usbotg_reg->gotgctl) & B_SESSION_VALID;
 }
+#endif /* CONFIG_IS_ENABLED(DM_USB_GADGET) */
index aaa90187fb765b49061ea2764589bdeda8415cd6..e72b22ac61e1a9e9c70e64ba7baca549b5e407c9 100644 (file)
@@ -23,7 +23,6 @@
 #define EP_FIFO_SIZE2          1024
 /* ep0-control, ep1in-bulk, ep2out-bulk, ep3in-int */
 #define DWC2_MAX_ENDPOINTS     4
-#define DWC2_MAX_HW_ENDPOINTS  16
 
 #define WAIT_FOR_SETUP          0
 #define DATA_STATE_XMIT         1
index a1829b3fd1219db975b0e95e85120ad311200122..434db5ba39ad4b1d12b6ebf8776fcdd7fb7f69fa 100644 (file)
@@ -60,22 +60,26 @@ struct dwc2_usbotg_reg {
        u32 grxstsp; /* Receive Status Debug Pop/Status Pop */
        u32 grxfsiz; /* Receive FIFO Size */
        u32 gnptxfsiz; /* Non-Periodic Transmit FIFO Size */
-       u8  res1[216];
+       u8  res0[12];
+       u32 ggpio;     /* 0x038 */
+       u8  res1[20];
+       u32 ghwcfg4; /* User HW Config4 */
+       u8  res2[176];
        u32 dieptxf[15]; /* Device Periodic Transmit FIFO size register */
-       u8  res2[1728];
+       u8  res3[1728];
        /* Device Configuration */
        u32 dcfg; /* Device Configuration Register */
        u32 dctl; /* Device Control */
        u32 dsts; /* Device Status */
-       u8  res3[4];
+       u8  res4[4];
        u32 diepmsk; /* Device IN Endpoint Common Interrupt Mask */
        u32 doepmsk; /* Device OUT Endpoint Common Interrupt Mask */
        u32 daint; /* Device All Endpoints Interrupt */
        u32 daintmsk; /* Device All Endpoints Interrupt Mask */
-       u8  res4[224];
+       u8  res5[224];
        struct dwc2_dev_in_endp in_endp[16];
        struct dwc2_dev_out_endp out_endp[16];
-       u8  res5[768];
+       u8  res6[768];
        struct ep_fifo ep[16];
 };
 
@@ -83,8 +87,15 @@ struct dwc2_usbotg_reg {
 /*definitions related to CSR setting */
 
 /* DWC2_UDC_OTG_GOTGCTL */
-#define B_SESSION_VALID                (0x1<<19)
-#define A_SESSION_VALID                (0x1<<18)
+#define B_SESSION_VALID                        BIT(19)
+#define A_SESSION_VALID                        BIT(18)
+#define B_VALOVAL                      BIT(7)
+#define B_VALOEN                       BIT(6)
+#define A_VALOVAL                      BIT(5)
+#define A_VALOEN                       BIT(4)
+
+/* DWC2_UDC_OTG_GOTINT */
+#define GOTGINT_SES_END_DET            (1<<2)
 
 /* DWC2_UDC_OTG_GAHBCFG */
 #define PTXFE_HALF                     (0<<8)
@@ -118,6 +129,7 @@ struct dwc2_usbotg_reg {
 #define INT_NP_TX_FIFO_EMPTY           (0x1<<5)
 #define INT_RX_FIFO_NOT_EMPTY          (0x1<<4)
 #define INT_SOF                        (0x1<<3)
+#define INT_OTG                        (0x1<<2)
 #define INT_DEV_MODE                   (0x0<<0)
 #define INT_HOST_MODE                  (0x1<<1)
 #define INT_GOUTNakEff                 (0x01<<7)
@@ -246,7 +258,7 @@ struct dwc2_usbotg_reg {
 
 /* Masks definitions */
 #define GINTMSK_INIT   (INT_OUT_EP | INT_IN_EP | INT_RESUME | INT_ENUMDONE\
-                       | INT_RESET | INT_SUSPEND)
+                       | INT_RESET | INT_SUSPEND | INT_OTG)
 #define DOEPMSK_INIT   (CTRL_OUT_EP_SETUP_PHASE_DONE | AHB_ERROR|TRANSFER_DONE)
 #define DIEPMSK_INIT   (NON_ISO_IN_EP_TIMEOUT|AHB_ERROR|TRANSFER_DONE)
 #define GAHBCFG_INIT   (PTXFE_HALF | NPTXFE_HALF | MODE_DMA | BURST_INCR4\
@@ -269,4 +281,13 @@ struct dwc2_usbotg_reg {
 /* Device ALL Endpoints Interrupt Register (DAINT) */
 #define DAINT_IN_EP_INT(x)                        (x << 0)
 #define DAINT_OUT_EP_INT(x)                       (x << 16)
+
+/* User HW Config4 */
+#define GHWCFG4_NUM_IN_EPS_MASK                (0xf << 26)
+#define GHWCFG4_NUM_IN_EPS_SHIFT       26
+
+/* OTG general core configuration register (OTG_GCCFG:0x38) for STM32MP1 */
+#define GGPIO_STM32_OTG_GCCFG_VBDEN               BIT(21)
+#define GGPIO_STM32_OTG_GCCFG_IDEN                BIT(22)
+
 #endif
index a75af4987f8f91d1fc1a928f4159068b8850a68b..7eb632d3b1417ba76e8a45d72df9bf21a2d5b243 100644 (file)
@@ -467,7 +467,7 @@ static void process_ep_out_intr(struct dwc2_udc *dev)
 static int dwc2_udc_irq(int irq, void *_dev)
 {
        struct dwc2_udc *dev = _dev;
-       u32 intr_status;
+       u32 intr_status, gotgint;
        u32 usb_status, gintmsk;
        unsigned long flags = 0;
 
@@ -521,14 +521,24 @@ static int dwc2_udc_irq(int irq, void *_dev)
                    && dev->driver) {
                        if (dev->driver->suspend)
                                dev->driver->suspend(&dev->gadget);
+               }
+       }
+
+       if (intr_status & INT_OTG) {
+               gotgint = readl(&reg->gotgint);
+               debug_cond(DEBUG_ISR,
+                          "\tOTG interrupt: (GOTGINT):0x%x\n", gotgint);
 
-                       /* HACK to let gadget detect disconnected state */
+               if (gotgint & GOTGINT_SES_END_DET) {
+                       debug_cond(DEBUG_ISR, "\t\tSession End Detected\n");
+                       /* Let gadget detect disconnected state */
                        if (dev->driver->disconnect) {
                                spin_unlock_irqrestore(&dev->lock, flags);
                                dev->driver->disconnect(&dev->gadget);
                                spin_lock_irqsave(&dev->lock, flags);
                        }
                }
+               writel(gotgint, &reg->gotgint);
        }
 
        if (intr_status & INT_RESUME) {
index f8f2205a62d317b63b0bc771a6bf6a1945b5e801..75005ccdd1b406c99abdec9b0edead4477ef5b73 100644 (file)
@@ -21,6 +21,7 @@ config USB_MUSB_GADGET
 config USB_MUSB_TI
        bool "Enable TI OTG USB controller"
        depends on DM_USB
+       select USB_MUSB_DSPS
        default n
        help
          Say y here to enable support for the dual role high
@@ -54,6 +55,15 @@ config USB_MUSB_SUNXI
        Say y here to enable support for the sunxi OTG / DRC USB controller
        used on almost all sunxi boards.
 
+config USB_MUSB_DISABLE_BULK_COMBINE_SPLIT
+       bool "Disable MUSB bulk split/combine"
+       default y
+       help
+         On TI AM335x devices, MUSB has bulk split/combine feature enabled
+         in the ConfigData register, but the current MUSB driver does not
+         support it yet. Select this option to disable the feature until the
+         driver adds the support.
+
 endif
 
 config USB_MUSB_PIO_ONLY
index 0834ff502193cf2e8dd26fe4b2abfc5e3cc8aa42..7721907d8f0db2ca3df5de7a2fe669548f36651a 100644 (file)
  * add mass storage support and for gadget we add both RNDIS ethernet
  * and DFU.
  */
-#define CONFIG_USB_MUSB_DISABLE_BULK_COMBINE_SPLIT
 #define CONFIG_AM335X_USB0
 #define CONFIG_AM335X_USB0_MODE        MUSB_PERIPHERAL
 #define CONFIG_AM335X_USB1
index ccbdc0a335664787fdccbbae10fec1d7d2b679b3..98ec0d626ea873fdabe099a9cc8e7798dd4b2019 100644 (file)
  * add mass storage support and for gadget we add both RNDIS ethernet
  * and DFU.
  */
-#define CONFIG_USB_MUSB_DISABLE_BULK_COMBINE_SPLIT
 #define CONFIG_AM335X_USB0
 #define CONFIG_AM335X_USB0_MODE        MUSB_HOST
 #define CONFIG_AM335X_USB1
index fb9c2a6d04d0e143238eed355f4ffe0cec4f9b3d..3d4d08aa70e10645fde27682a703e2f03ab7344c 100644 (file)
@@ -387,7 +387,6 @@ DEFAULT_LINUX_BOOT_ENV \
  * add mass storage support and for gadget we add both RNDIS ethernet
  * and DFU.
  */
-#define CONFIG_USB_MUSB_DISABLE_BULK_COMBINE_SPLIT
 #define CONFIG_AM335X_USB0
 #define CONFIG_AM335X_USB0_MODE        MUSB_PERIPHERAL
 #define CONFIG_AM335X_USB1
index ae9b75bb87ad0c65a101b1efe60f444d9bd14570..84c801d10a992faa20a623f511a3a2692e27c47a 100644 (file)
@@ -182,9 +182,6 @@ NANDTGTS \
 #define CONFIG_NAND_OMAP_GPMC_WSCFG    1
 #endif /* CONFIG_NAND */
 
-/* USB configuration */
-#define CONFIG_USB_MUSB_DISABLE_BULK_COMBINE_SPLIT
-
 #if defined(CONFIG_SPI)
 /* SPI Flash */
 #define CONFIG_SYS_SPI_U_BOOT_OFFS             0x40000
index 601b30dffd5fa9661920bf684e4fb4cd52a95ee4..7309e7d4831d2401467b73d60fe781733a7b4764 100644 (file)
@@ -68,9 +68,6 @@ BUR_COMMON_ENV \
 #define CONFIG_SETUP_MEMORY_TAGS
 #define CONFIG_INITRD_TAG
 
-/* USB configuration */
-#define CONFIG_USB_MUSB_DISABLE_BULK_COMBINE_SPLIT
-
 /* Environment */
 #define CONFIG_SYS_MMC_ENV_DEV         1
 #define CONFIG_SYS_MMC_ENV_PART                2
index 4372280d2bbe7ae63f36be47c71485e919c99b20..db990fcb2b474df294bfc7f1f93fb1ed9be3c8af 100644 (file)
 
 /* USB configuration */
 #define CONFIG_ARCH_MISC_INIT
-#define CONFIG_USB_MUSB_DISABLE_BULK_COMBINE_SPLIT
 #define CONFIG_AM335X_USB1
 #define CONFIG_AM335X_USB1_MODE MUSB_HOST
 
index 48f1f7baccba1616885a4185204e251675e2ccb5..a535d0c2f2d02a4558fcb234dd7961941c4ce64f 100644 (file)
  * board schematic and physical port wired to each.  Then for host we
  * add mass storage support.
  */
-#define CONFIG_USB_MUSB_DISABLE_BULK_COMBINE_SPLIT
 #define CONFIG_AM335X_USB0
 #define CONFIG_AM335X_USB0_MODE        MUSB_PERIPHERAL
 #define CONFIG_AM335X_USB1
index f44a4280f435bb02e6831e118291fe1eb83c2108..1170f24748d9d6d718362adcae1b19eee189b200 100644 (file)
 /*
  * USB configuration
  */
-#define CONFIG_USB_MUSB_DISABLE_BULK_COMBINE_SPLIT
-
 #define CONFIG_AM335X_USB0
 #define CONFIG_AM335X_USB0_MODE        MUSB_PERIPHERAL
 #define CONFIG_AM335X_USB1
index 4068de045dc2c4e204a0cc0ec9da3c7536ebaa7e..a6c12212a9b0cabe4a86dc47114b4d6e33b8fceb 100644 (file)
@@ -9,6 +9,7 @@
 #define __DWC2_USB_GADGET
 
 #define PHY0_SLEEP              (1 << 5)
+#define DWC2_MAX_HW_ENDPOINTS  16
 
 struct dwc2_plat_otg_data {
        void            *priv;
@@ -22,8 +23,14 @@ struct dwc2_plat_otg_data {
        unsigned int    rx_fifo_sz;
        unsigned int    np_tx_fifo_sz;
        unsigned int    tx_fifo_sz;
+       unsigned int    tx_fifo_sz_array[DWC2_MAX_HW_ENDPOINTS];
+       unsigned char   tx_fifo_sz_nb;
+       bool            force_b_session_valid;
+       bool            activate_stm_id_vb_detection;
 };
 
 int dwc2_udc_probe(struct dwc2_plat_otg_data *pdata);
 
+int dwc2_udc_B_session_valid(struct udevice *dev);
+
 #endif /* __DWC2_USB_GADGET */
index 5092c3fb4ce573c3a5e6ab759d5291499560259d..421362d9532fa2fa1f369dce9a4cf0ef34dcbc2d 100644 (file)
@@ -4537,7 +4537,6 @@ CONFIG_USB_GADGET_SUPERH
 CONFIG_USB_INVENTRA_DMA
 CONFIG_USB_ISP1301_I2C_ADDR
 CONFIG_USB_MAX_CONTROLLER_COUNT
-CONFIG_USB_MUSB_DISABLE_BULK_COMBINE_SPLIT
 CONFIG_USB_MUSB_TIMEOUT
 CONFIG_USB_MUSB_TUSB6010
 CONFIG_USB_OHCI_EP93XX