drivers: usb: udc: stm32: configure OTGFS/HS RxFIFO size using Kconfig
Create a new Kconfig option allowing to tweak the RxFIFO size on OTG_FS
and OTG_HS instances, and replace the old hardcoded method with this new
mecanism.
The default value of 600 bytes yields a similar size to the the previous
hardcoded default of 160 words (= 640 bytes) when combined with the fixed
overhead computed by the driver (~56 bytes on OTG_FS with 6 endpoints).
Also fix a tiny error in a logging message (DRAM size in bytes, not bits).
Signed-off-by: Mathieu Choplain <mathieu.choplain-ext@st.com>
diff --git a/drivers/usb/udc/Kconfig.stm32 b/drivers/usb/udc/Kconfig.stm32
index bf58095..11f885f 100644
--- a/drivers/usb/udc/Kconfig.stm32
+++ b/drivers/usb/udc/Kconfig.stm32
@@ -36,6 +36,26 @@
help
Maximum number of messages for handling of STM32 USBD ISR events.
+config UDC_STM32_OTG_RXFIFO_BASELINE_SIZE
+ int "Baseline RxFIFO size (in bytes)"
+ default 600
+ depends on DT_HAS_ST_STM32_OTGFS_ENABLED \
+ || DT_HAS_ST_STM32_OTGHS_ENABLED
+ help
+ Baseline value for RXFIFO size computation
+
+ The OTG_FS and OTG_HS USB controllers use a single "RxFIFO" to hold
+ data received by all OUT endpoints. The RxFIFO's size is influenced
+ by various parameters: the optimal value depends on the exact USB
+ configuration that will be used, which the driver does not know by
+ the time it has to configure the RxFIFO size.
+
+ The total RxFIFO size will be equal to the value of this option
+ plus a fixed overhead that the driver can derive from the hardware
+ configuration (e.g., number of endpoints implemented).
+
+ Refer to STM32 Reference Manuals for more details about the RxFIFO.
+
config UDC_STM32_CLOCK_CHECK
bool "Runtime USB 48MHz clock check"
default y if !(SOC_SERIES_STM32F1X || SOC_SERIES_STM32F3X || SOC_SERIES_STM32U5X)
diff --git a/drivers/usb/udc/udc_stm32.c b/drivers/usb/udc/udc_stm32.c
index a0dcf4f..4d51730 100644
--- a/drivers/usb/udc/udc_stm32.c
+++ b/drivers/usb/udc/udc_stm32.c
@@ -659,16 +659,27 @@
{
struct udc_stm32_data *priv = udc_get_private(dev);
const struct udc_stm32_config *cfg = dev->config;
- int words;
+ uint32_t rxfifo_size; /* in words */
- LOG_DBG("DRAM size: %ub", cfg->dram_size);
+ LOG_DBG("DRAM size: %uB", cfg->dram_size);
- /* The documentation is not clear at all about RX FiFo size requirement,
- * 160 has been selected through trial and error.
+ /*
+ * In addition to the user-provided baseline, RxFIFO should fit:
+ * - Global OUT NAK (1 word)
+ * - Received packet information (1 word)
+ * - Transfer complete status information (2 words per OUT endpoint)
+ *
+ * Align user-provided baseline up to 32-bit word size then
+ * add this "fixed" overhead to obtain the final RxFIFO size.
*/
- words = MAX(160, DIV_ROUND_UP(cfg->ep_mps, 4U));
- HAL_PCDEx_SetRxFiFo(&priv->pcd, words);
- priv->occupied_mem = words * 4;
+ rxfifo_size = DIV_ROUND_UP(CONFIG_UDC_STM32_OTG_RXFIFO_BASELINE_SIZE, 4U);
+ rxfifo_size += 2U; /* Global OUT NAK and Rx packet info */
+ rxfifo_size += 2U * cfg->num_endpoints;
+
+ LOG_DBG("RxFIFO size: %uB", rxfifo_size * 4U);
+
+ HAL_PCDEx_SetRxFiFo(&priv->pcd, rxfifo_size);
+ priv->occupied_mem = rxfifo_size * 4U;
/* For EP0 TX, reserve only one MPS */
HAL_PCDEx_SetTxFiFo(&priv->pcd, 0, DIV_ROUND_UP(UDC_STM32_EP0_MAX_PACKET_SIZE, 4U));