usb: dwc2_udc_otg: Read MAX_HW_ENDPOINT from HWCFG4 register
authorPatrick Delaunay <patrick.delaunay@st.com>
Fri, 29 Mar 2019 14:42:19 +0000 (15:42 +0100)
committerMarek Vasut <marex@denx.de>
Sun, 21 Apr 2019 08:26:52 +0000 (10:26 +0200)
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@st.com>
Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
Reviewed-by: Lukasz Majewski <lukma@denx.de>
drivers/usb/gadget/dwc2_udc_otg.c
drivers/usb/gadget/dwc2_udc_otg_priv.h
drivers/usb/gadget/dwc2_udc_otg_regs.h

index b1efad1..5c7d131 100644 (file)
@@ -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);
index aaa9018..e72b22a 100644 (file)
@@ -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
index 0aee4ee..a389923 100644 (file)
@@ -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