diff --git a/drivers/usb/udc/Kconfig.ambiq b/drivers/usb/udc/Kconfig.ambiq index 68a22e81991..0c99caa91b8 100644 --- a/drivers/usb/udc/Kconfig.ambiq +++ b/drivers/usb/udc/Kconfig.ambiq @@ -56,4 +56,20 @@ config UDC_AMBIQ_PIO_MODE Select this option when cache coherency handling is to be avoided. endchoice +config UDC_AMBIQ_DEB_ENABLE + hex "EP Double Buffer Enable" + default 0x0000 + depends on SOC_SERIES_APOLLO5X + help + Double Endpoint Buffer acceleration (DEB) is doubles an EP's FIFO size so + that USB transfer could continue to happen while waiting for DMA/CPU to + load/unload data from the EP FIFO. This hex value is a bitmap of endpoints + for DEB to be enabled. BIT0-4 represents OUT_EP 1-5, while BIT16-20 + represents IN_EP 1-5. Take note that this feature is limited by total EP + FIFO size. Proper calculation should be done before enabling DEB such that + the total usage of FIFO for all endpoint doesn't exceed the FIFO available + on SoC. The list of Soc with its FIFO size is listed below. The FIFO size + here includes 128 bytes required by control endpoints. + - Apollo510: (4096 Bytes FIFO) + endif # UDC_AMBIQ diff --git a/drivers/usb/udc/udc_ambiq.c b/drivers/usb/udc/udc_ambiq.c index 57437703c8b..6c6ed46495c 100644 --- a/drivers/usb/udc/udc_ambiq.c +++ b/drivers/usb/udc/udc_ambiq.c @@ -565,6 +565,29 @@ static int init_apollo5x(const struct udc_ambiq_data *priv) } #endif +#if CONFIG_UDC_AMBIQ_DEB_ENABLE +static void init_double_buffers(const struct udc_ambiq_data *priv) +{ + uint32_t mask; + + mask = CONFIG_UDC_AMBIQ_DEB_ENABLE & 0xFFFF; + while (mask) { + uint32_t ep = find_lsb_set(mask); + + am_hal_usb_enable_ep_double_buffer(priv->usb_handle, ep, AM_HAL_USB_OUT_DIR, true); + mask &= ~(1U << (ep - 1)); + } + + mask = (CONFIG_UDC_AMBIQ_DEB_ENABLE >> 16) & 0xFFFF; + while (mask) { + uint32_t ep = find_lsb_set(mask); + + am_hal_usb_enable_ep_double_buffer(priv->usb_handle, ep, AM_HAL_USB_IN_DIR, true); + mask &= ~(1U << (ep - 1)); + } +} +#endif + static int udc_ambiq_init(const struct device *dev) { struct udc_ambiq_data *priv = udc_get_private(dev); @@ -599,6 +622,10 @@ static int udc_ambiq_init(const struct device *dev) } #endif +#if CONFIG_UDC_AMBIQ_DEB_ENABLE + init_double_buffers(priv); +#endif + /* Set USB Speed */ am_hal_usb_set_dev_speed(priv->usb_handle, priv->usb_speed); /* Enable USB interrupt */