X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;ds=sidebyside;f=drivers%2Fserial%2Fserial_stm32x7.c;h=61e8167a3bc9e1d4df566aaccc61c27de6dacb4c;hb=e2351d5cf1e97408b4c52bafeaa85e0ca85c920c;hp=2e6c67688c83d96f9774bbb98b63c074556837b1;hpb=42bf5e7c27ae73b0e56c29f5af3cae5d15d35afa;p=oweals%2Fu-boot.git diff --git a/drivers/serial/serial_stm32x7.c b/drivers/serial/serial_stm32x7.c index 2e6c67688c..61e8167a3b 100644 --- a/drivers/serial/serial_stm32x7.c +++ b/drivers/serial/serial_stm32x7.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -19,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); @@ -28,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; } @@ -76,6 +86,25 @@ static int stm32_serial_probe(struct udevice *dev) { struct stm32x7_serial_platdata *plat = dev->platdata; struct stm32_usart *const usart = plat->base; + +#ifdef CONFIG_CLK + int ret; + struct clk clk; + + ret = clk_get_by_index(dev, 0, &clk); + if (ret < 0) + return ret; + + ret = clk_enable(&clk); + if (ret) { + dev_err(dev, "failed to enable clock\n"); + return ret; + } +#endif + + /* Disable usart-> disable overrun-> enable usart */ + clrbits_le32(&usart->cr1, USART_CR1_RE | USART_CR1_TE | USART_CR1_UE); + setbits_le32(&usart->cr3, USART_CR3_OVRDIS); setbits_le32(&usart->cr1, USART_CR1_RE | USART_CR1_TE | USART_CR1_UE); return 0; @@ -83,8 +112,8 @@ static int stm32_serial_probe(struct udevice *dev) #if CONFIG_IS_ENABLED(OF_CONTROL) static const struct udevice_id stm32_serial_id[] = { - {.compatible = "st,stm32-usart"}, - {.compatible = "st,stm32-uart"}, + {.compatible = "st,stm32f7-usart"}, + {.compatible = "st,stm32f7-uart"}, {} }; @@ -93,11 +122,12 @@ static int stm32_serial_ofdata_to_platdata(struct udevice *dev) struct stm32x7_serial_platdata *plat = dev_get_platdata(dev); fdt_addr_t addr; - addr = dev_get_addr(dev); + addr = devfdt_get_addr(dev); if (addr == FDT_ADDR_T_NONE) return -EINVAL; plat->base = (struct stm32_usart *)addr; + return 0; } #endif