[U-Boot] [PATCH 13/16] usb: dwc2: add support for STM32MP1

Patrick Delaunay
2019-03-29T14:42:21Z

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

---

doc/device-tree-bindings/usb/dwc2.txt | 2 ++
drivers/usb/gadget/dwc2_udc_otg.c | 45 ++++++++++++++++++++++++++++++++++
drivers/usb/gadget/dwc2_udc_otg_regs.h | 10 ++++++--
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 6dc3c4a..eb60ffa 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 106dec5..3fdaa10 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 a389923..b2a28d7 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 369f6fb..a6c1221 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);
--
2.7.4