]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
serial: stm32x7: simplify baud rate register calculation
authorPatrice Chotard <patrice.chotard@st.com>
Thu, 8 Jun 2017 07:26:55 +0000 (09:26 +0200)
committerTom Rini <trini@konsulko.com>
Mon, 12 Jun 2017 12:38:38 +0000 (08:38 -0400)
Simplify baud rate register formula and use the oversampling
uart feature.
This code is aligned with what is implemented in kernel driver
drivers/tty/serial/stm32-usart.c since kernel v4.9.

Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
Reviewed-by: Christophe KERELLO <christophe.kerello@st.com>
Reviewed-by: Patrick DELAUNAY <patrick.delaunay@st.com>
Acked-by: Vikas MANOCHA <vikas.manocha@st.com>
drivers/serial/serial_stm32x7.c
drivers/serial/serial_stm32x7.h

index 7693159af21e61c2b27f8b01b91dd46971f6a3a6..61e8167a3bc9e1d4df566aaccc61c27de6dacb4c 100644 (file)
@@ -20,7 +20,7 @@ static int stm32_serial_setbrg(struct udevice *dev, int baudrate)
 {
        struct stm32x7_serial_platdata *plat = dev->platdata;
        struct stm32_usart *const usart = plat->base;
-       u32  clock, int_div, frac_div, tmp;
+       u32  clock, int_div, mantissa, fraction, oversampling;
 
        if (((u32)usart & STM32_BUS_MASK) == APB1_PERIPH_BASE)
                clock = clock_get(CLOCK_APB1);
@@ -29,11 +29,20 @@ static int stm32_serial_setbrg(struct udevice *dev, int baudrate)
        else
                return -EINVAL;
 
-       int_div = (25 * clock) / (4 * baudrate);
-       tmp = ((int_div / 100) << USART_BRR_M_SHIFT) & USART_BRR_M_MASK;
-       frac_div = int_div - (100 * (tmp >> USART_BRR_M_SHIFT));
-       tmp |= (((frac_div * 16) + 50) / 100) & USART_BRR_F_MASK;
-       writel(tmp, &usart->brr);
+       int_div = DIV_ROUND_CLOSEST(clock, baudrate);
+
+       if (int_div < 16) {
+               oversampling = 8;
+               setbits_le32(&usart->cr1, USART_CR1_OVER8);
+       } else {
+               oversampling = 16;
+               clrbits_le32(&usart->cr1, USART_CR1_OVER8);
+       }
+
+       mantissa = (int_div / oversampling) << USART_BRR_M_SHIFT;
+       fraction = int_div % oversampling;
+
+       writel(mantissa | fraction, &usart->brr);
 
        return 0;
 }
index 8c025485cd918550f7441170ce635b2cfae9dd51..facfdbabe89000808e16a4ea1c170fd11374eed3 100644 (file)
@@ -23,8 +23,9 @@ struct stm32_usart {
 };
 
 
-#define USART_CR1_RE                   (1 << 2)
+#define USART_CR1_OVER8                        (1 << 15)
 #define USART_CR1_TE                   (1 << 3)
+#define USART_CR1_RE                   (1 << 2)
 #define USART_CR1_UE                   (1 << 0)
 
 #define USART_CR3_OVRDIS               (1 << 12)