usb: dwc2: add support for STM32MP1

Add compatible "st,stm32mp1-hsotg" and associated driver data to manage
the usb33d-supply and the ST specific register for VBus sensing.

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
# Conflicts:
#	drivers/usb/gadget/dwc2_udc_otg.c
Reviewed-by: Lukasz Majewski <lukma@denx.de>
This commit is contained in:
Patrick Delaunay 2019-03-29 15:42:21 +01:00 committed by Marek Vasut
parent 763bb106f6
commit 931e9d7aa7
4 changed files with 56 additions and 2 deletions

View file

@ -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-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-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. - 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: Deprecated properties:
- g-use-dma: gadget DMA mode is automatically detected - g-use-dma: gadget DMA mode is automatically detected

View file

@ -942,6 +942,7 @@ struct dwc2_priv_data {
struct reset_ctl_bulk resets; struct reset_ctl_bulk resets;
struct phy *phys; struct phy *phys;
int num_phys; int num_phys;
struct udevice *usb33d_supply;
}; };
int dm_usb_gadget_handle_interrupts(struct udevice *dev) 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); struct dwc2_plat_otg_data *platdata = dev_get_platdata(dev);
int node = dev_of_offset(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) { if (usb_get_dr_mode(node) != USB_DR_MODE_PERIPHERAL) {
dev_dbg(dev, "Invalid mode\n"); 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 = platdata->force_b_session_valid =
dev_read_bool(dev, "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; 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, static int dwc2_udc_otg_reset_init(struct udevice *dev,
struct reset_ctl_bulk *resets) struct reset_ctl_bulk *resets)
{ {
@ -1122,6 +1144,26 @@ static int dwc2_udc_otg_probe(struct udevice *dev)
if (ret) if (ret)
return 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) if (platdata->force_b_session_valid)
/* Override B session bits : value and enable */ /* Override B session bits : value and enable */
setbits_le32(&usbotg_reg->gotgctl, B_VALOEN | B_VALOVAL); 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[] = { static const struct udevice_id dwc2_udc_otg_ids[] = {
{ .compatible = "snps,dwc2" }, { .compatible = "snps,dwc2" },
{ .compatible = "st,stm32mp1-hsotg",
.data = (ulong)dwc2_set_stm32mp1_hsotg_params },
{},
}; };
U_BOOT_DRIVER(dwc2_udc_otg) = { U_BOOT_DRIVER(dwc2_udc_otg) = {

View file

@ -60,8 +60,9 @@ struct dwc2_usbotg_reg {
u32 grxstsp; /* Receive Status Debug Pop/Status Pop */ u32 grxstsp; /* Receive Status Debug Pop/Status Pop */
u32 grxfsiz; /* Receive FIFO Size */ u32 grxfsiz; /* Receive FIFO Size */
u32 gnptxfsiz; /* Non-Periodic Transmit FIFO Size */ u32 gnptxfsiz; /* Non-Periodic Transmit FIFO Size */
u8 res0[12];
u8 res1[36]; u32 ggpio; /* 0x038 */
u8 res1[20];
u32 ghwcfg4; /* User HW Config4 */ u32 ghwcfg4; /* User HW Config4 */
u8 res2[176]; u8 res2[176];
u32 dieptxf[15]; /* Device Periodic Transmit FIFO size register */ u32 dieptxf[15]; /* Device Periodic Transmit FIFO size register */
@ -280,4 +281,9 @@ struct dwc2_usbotg_reg {
/* User HW Config4 */ /* User HW Config4 */
#define GHWCFG4_NUM_IN_EPS_MASK (0xf << 26) #define GHWCFG4_NUM_IN_EPS_MASK (0xf << 26)
#define GHWCFG4_NUM_IN_EPS_SHIFT 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 #endif

View file

@ -26,6 +26,7 @@ struct dwc2_plat_otg_data {
unsigned int tx_fifo_sz_array[DWC2_MAX_HW_ENDPOINTS]; unsigned int tx_fifo_sz_array[DWC2_MAX_HW_ENDPOINTS];
unsigned char tx_fifo_sz_nb; unsigned char tx_fifo_sz_nb;
bool force_b_session_valid; bool force_b_session_valid;
bool activate_stm_id_vb_detection;
}; };
int dwc2_udc_probe(struct dwc2_plat_otg_data *pdata); int dwc2_udc_probe(struct dwc2_plat_otg_data *pdata);