[U-Boot] [PATCH 11/16] usb: dwc2_udc_otg: Read MAX_HW_ENDPOINT from HWCFG4 register

Patrick Delaunay patrick.delaunay at st.com
Fri Mar 29 14:42:19 UTC 2019


Some DWC2 ip variant doesn't use 16 hardware endpoint as hardcoded
in the driver. Bits INEps [29:26] of HWCFG4 register allows to get
this information.

Signed-off-by: Patrice Chotard <patrice.chotard at st.com>
Signed-off-by: Patrick Delaunay <patrick.delaunay at st.com>
---

 drivers/usb/gadget/dwc2_udc_otg.c      | 11 ++++++++---
 drivers/usb/gadget/dwc2_udc_otg_priv.h |  1 -
 drivers/usb/gadget/dwc2_udc_otg_regs.h | 17 ++++++++++++-----
 3 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/drivers/usb/gadget/dwc2_udc_otg.c b/drivers/usb/gadget/dwc2_udc_otg.c
index b1efad1..5c7d131 100644
--- a/drivers/usb/gadget/dwc2_udc_otg.c
+++ b/drivers/usb/gadget/dwc2_udc_otg.c
@@ -456,6 +456,7 @@ 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;
 
 	debug("Reseting OTG controller\n");
 
@@ -538,9 +539,13 @@ 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;
+
+	for (i = 0; i < max_hw_ep; 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);
diff --git a/drivers/usb/gadget/dwc2_udc_otg_priv.h b/drivers/usb/gadget/dwc2_udc_otg_priv.h
index aaa9018..e72b22a 100644
--- a/drivers/usb/gadget/dwc2_udc_otg_priv.h
+++ b/drivers/usb/gadget/dwc2_udc_otg_priv.h
@@ -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
diff --git a/drivers/usb/gadget/dwc2_udc_otg_regs.h b/drivers/usb/gadget/dwc2_udc_otg_regs.h
index 0aee4ee..a389923 100644
--- a/drivers/usb/gadget/dwc2_udc_otg_regs.h
+++ b/drivers/usb/gadget/dwc2_udc_otg_regs.h
@@ -60,22 +60,25 @@ 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  res1[36];
+	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];
 };
 
@@ -273,4 +276,8 @@ 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
 #endif
-- 
2.7.4



More information about the U-Boot mailing list