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));