diff options
Diffstat (limited to 'payloads/libpayload/drivers/usb/dwc2.c')
-rw-r--r-- | payloads/libpayload/drivers/usb/dwc2.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/payloads/libpayload/drivers/usb/dwc2.c b/payloads/libpayload/drivers/usb/dwc2.c index 1092cb4ee3..71c4967e7e 100644 --- a/payloads/libpayload/drivers/usb/dwc2.c +++ b/payloads/libpayload/drivers/usb/dwc2.c @@ -35,11 +35,12 @@ static void dwc2_reinit(hci_t *controller) gintsts_t gintsts = { .d32 = 0 }; gahbcfg_t gahbcfg = { .d32 = 0 }; grxfsiz_t grxfsiz = { .d32 = 0 }; + ghwcfg3_t hwcfg3 = { .d32 = 0 }; hcintmsk_t hcintmsk = { .d32 = 0 }; gnptxfsiz_t gnptxfsiz = { .d32 = 0 }; const int timeout = 10000; - int i; + int i, fifo_blocks, tx_blocks; /* Wait for AHB idle */ for (i = 0; i < timeout; i++) { @@ -86,10 +87,24 @@ static void dwc2_reinit(hci_t *controller) * The non-periodic tx fifo and rx fifo share one continuous * piece of IP-internal SRAM. */ - grxfsiz.rxfdep = DWC2_RXFIFO_DEPTH; + + /* + * Read total data FIFO depth from HWCFG3 + * this value is in terms of 32-bit words + */ + hwcfg3.d32 = readl(®->core.ghwcfg3); + /* + * Reserve 2 spaces for the status entries of received packets + * and 2 spaces for bulk and control OUT endpoints. Calculate how + * many blocks can be alloted, assume largest packet size is 512. + */ + fifo_blocks = (hwcfg3.dfifodepth - 4) / (512 / 4); + tx_blocks = fifo_blocks / 2; + + grxfsiz.rxfdep = (fifo_blocks - tx_blocks) * (512 / 4) + 4; writel(grxfsiz.d32, ®->core.grxfsiz); - gnptxfsiz.nptxfstaddr = DWC2_RXFIFO_DEPTH; - gnptxfsiz.nptxfdep = DWC2_NPTXFIFO_DEPTH; + gnptxfsiz.nptxfstaddr = grxfsiz.rxfdep; + gnptxfsiz.nptxfdep = tx_blocks * (512 / 4); writel(gnptxfsiz.d32, ®->core.gnptxfsiz); /* Init host channels */ |