refactor(st-uart): compute the over sampling dynamically

The parameter over_sampling of stm32_uart_init_s is not required
as it can be computed dynamically from clock rate of the serial
device and the requested baudrate.

Oversampling by 8 is allowed only for higher speed
(up to clock_rate / 8) to reduce the maximum receiver tolerance
to clock deviation.

This patch update the driver, the serial init struct and the
only user, the stm32cubeprogrammer over uart support.

Change-Id: I422731089730a288defeb7fa49886db65d0902b2
Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
diff --git a/drivers/st/uart/stm32_uart.c b/drivers/st/uart/stm32_uart.c
index e2e5405..08bd77b 100644
--- a/drivers/st/uart/stm32_uart.c
+++ b/drivers/st/uart/stm32_uart.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -106,7 +106,33 @@
 {
 	uint32_t tmpreg;
 	unsigned long clockfreq;
+	unsigned long int_div;
 	uint32_t brrtemp;
+	uint32_t over_sampling;
+
+	/*---------------------- USART BRR configuration --------------------*/
+	clockfreq = uart_get_clock_freq(huart);
+	if (clockfreq == 0UL) {
+		return -ENODEV;
+	}
+
+	int_div = clockfreq / init->baud_rate;
+	if (int_div < 16U) {
+		uint32_t usartdiv = uart_div_sampling8(clockfreq,
+						       init->baud_rate,
+						       init->prescaler);
+
+		brrtemp = (usartdiv & USART_BRR_DIV_MANTISSA) |
+			  ((usartdiv & USART_BRR_DIV_FRACTION) >> 1);
+		over_sampling = USART_CR1_OVER8;
+	} else {
+		brrtemp = uart_div_sampling16(clockfreq,
+					      init->baud_rate,
+					      init->prescaler) &
+			  (USART_BRR_DIV_FRACTION | USART_BRR_DIV_MANTISSA);
+		over_sampling = 0x0U;
+	}
+	mmio_write_32(huart->base + USART_BRR, brrtemp);
 
 	/*
 	 * ---------------------- USART CR1 Configuration --------------------
@@ -115,12 +141,12 @@
 	 * - set the M bits according to init->word_length value,
 	 * - set PCE and PS bits according to init->parity value,
 	 * - set TE and RE bits according to init->mode value,
-	 * - set OVER8 bit according to init->over_sampling value.
+	 * - set OVER8 bit according baudrate and clock.
 	 */
 	tmpreg = init->word_length |
 		 init->parity |
 		 init->mode |
-		 init->over_sampling |
+		 over_sampling |
 		 init->fifo_mode;
 	mmio_clrsetbits_32(huart->base + USART_CR1, STM32_UART_CR1_FIELDS, tmpreg);
 
@@ -161,27 +187,6 @@
 	mmio_clrsetbits_32(huart->base + USART_PRESC, USART_PRESC_PRESCALER,
 			   init->prescaler);
 
-	/*---------------------- USART BRR configuration --------------------*/
-	clockfreq = uart_get_clock_freq(huart);
-	if (clockfreq == 0UL) {
-		return -ENODEV;
-	}
-
-	if (init->over_sampling == STM32_UART_OVERSAMPLING_8) {
-		uint32_t usartdiv = uart_div_sampling8(clockfreq,
-						       init->baud_rate,
-						       init->prescaler);
-
-		brrtemp = (usartdiv & USART_BRR_DIV_MANTISSA) |
-			  ((usartdiv & USART_BRR_DIV_FRACTION) >> 1);
-	} else {
-		brrtemp = uart_div_sampling16(clockfreq,
-					      init->baud_rate,
-					      init->prescaler) &
-			  (USART_BRR_DIV_FRACTION | USART_BRR_DIV_MANTISSA);
-	}
-	mmio_write_32(huart->base + USART_BRR, brrtemp);
-
 	return 0;
 }