diff options
-rw-r--r-- | doc/device-tree-bindings/usb/dwc2.txt | 2 | ||||
-rw-r--r-- | drivers/usb/gadget/dwc2_udc_otg.c | 45 | ||||
-rw-r--r-- | drivers/usb/gadget/dwc2_udc_otg_regs.h | 10 | ||||
-rw-r--r-- | include/usb/dwc2_udc.h | 1 |
4 files changed, 56 insertions, 2 deletions
diff --git a/doc/device-tree-bindings/usb/dwc2.txt b/doc/device-tree-bindings/usb/dwc2.txt index 6dc3c4a344..eb60ffae58 100644 --- a/doc/device-tree-bindings/usb/dwc2.txt +++ b/doc/device-tree-bindings/usb/dwc2.txt @@ -37,6 +37,8 @@ Refer to phy/phy-bindings.txt for generic phy consumer properties - 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. Deprecated properties: - g-use-dma: gadget DMA mode is automatically detected diff --git a/drivers/usb/gadget/dwc2_udc_otg.c b/drivers/usb/gadget/dwc2_udc_otg.c index 106dec5d09..3fdaa102ba 100644 --- a/drivers/usb/gadget/dwc2_udc_otg.c +++ b/drivers/usb/gadget/dwc2_udc_otg.c @@ -942,6 +942,7 @@ struct dwc2_priv_data { struct reset_ctl_bulk resets; struct phy *phys; int num_phys; + struct udevice *usb33d_supply; }; int dm_usb_gadget_handle_interrupts(struct udevice *dev) @@ -1036,6 +1037,8 @@ 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"); @@ -1052,9 +1055,28 @@ static int dwc2_udc_otg_ofdata_to_platdata(struct udevice *dev) platdata->force_b_session_valid = dev_read_bool(dev, "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**/ +} + static int dwc2_udc_otg_reset_init(struct udevice *dev, struct reset_ctl_bulk *resets) { @@ -1122,6 +1144,26 @@ static int dwc2_udc_otg_probe(struct udevice *dev) 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, B_VALOEN | B_VALOVAL); @@ -1154,6 +1196,9 @@ static int dwc2_udc_otg_remove(struct udevice *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) = { diff --git a/drivers/usb/gadget/dwc2_udc_otg_regs.h b/drivers/usb/gadget/dwc2_udc_otg_regs.h index a3899236fc..b2a28d7a5d 100644 --- a/drivers/usb/gadget/dwc2_udc_otg_regs.h +++ b/drivers/usb/gadget/dwc2_udc_otg_regs.h @@ -60,8 +60,9 @@ 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[36]; + 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 */ @@ -280,4 +281,9 @@ struct dwc2_usbotg_reg { /* 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 diff --git a/include/usb/dwc2_udc.h b/include/usb/dwc2_udc.h index 369f6fbd4a..a6c12212a9 100644 --- a/include/usb/dwc2_udc.h +++ b/include/usb/dwc2_udc.h @@ -26,6 +26,7 @@ struct dwc2_plat_otg_data { 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); |