From 0fdd0bc621f060fcf60fd4ba48a2a32f338ffeac Mon Sep 17 00:00:00 2001
From: Patrick Delaunay <patrick.delaunay@st.com>
Date: Fri, 29 Mar 2019 15:42:17 +0100
Subject: [PATCH] usb: dwc2: Add force-b-session-valid support

Handle "force-b-session-valid" property from DT.

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
Reviewed-by: Lukasz Majewski <lukma@denx.de>
---
 drivers/usb/gadget/dwc2_udc_otg.c      | 9 +++++++++
 drivers/usb/gadget/dwc2_udc_otg_regs.h | 8 ++++++--
 include/usb/dwc2_udc.h                 | 1 +
 3 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/gadget/dwc2_udc_otg.c b/drivers/usb/gadget/dwc2_udc_otg.c
index 8169fdbb11..146f11e710 100644
--- a/drivers/usb/gadget/dwc2_udc_otg.c
+++ b/drivers/usb/gadget/dwc2_udc_otg.c
@@ -1034,6 +1034,9 @@ static int dwc2_udc_otg_ofdata_to_platdata(struct udevice *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, "force-b-session-valid");
+
 	return 0;
 }
 
@@ -1088,6 +1091,8 @@ 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);
@@ -1102,6 +1107,10 @@ static int dwc2_udc_otg_probe(struct udevice *dev)
 	if (ret)
 		return ret;
 
+	if (platdata->force_b_session_valid)
+		/* Override B session bits : value and enable */
+		setbits_le32(&usbotg_reg->gotgctl,  B_VALOEN | B_VALOVAL);
+
 	ret = dwc2_udc_probe(platdata);
 	if (ret)
 		return ret;
diff --git a/drivers/usb/gadget/dwc2_udc_otg_regs.h b/drivers/usb/gadget/dwc2_udc_otg_regs.h
index a1829b3fd1..0aee4ee929 100644
--- a/drivers/usb/gadget/dwc2_udc_otg_regs.h
+++ b/drivers/usb/gadget/dwc2_udc_otg_regs.h
@@ -83,8 +83,12 @@ 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_GAHBCFG */
 #define PTXFE_HALF			(0<<8)
diff --git a/include/usb/dwc2_udc.h b/include/usb/dwc2_udc.h
index 4068de045d..3cf20eab92 100644
--- a/include/usb/dwc2_udc.h
+++ b/include/usb/dwc2_udc.h
@@ -22,6 +22,7 @@ struct dwc2_plat_otg_data {
 	unsigned int	rx_fifo_sz;
 	unsigned int	np_tx_fifo_sz;
 	unsigned int	tx_fifo_sz;
+	bool		force_b_session_valid;
 };
 
 int dwc2_udc_probe(struct dwc2_plat_otg_data *pdata);
-- 
2.39.5