summaryrefslogtreecommitdiff
path: root/drivers/serial
diff options
context:
space:
mode:
authorWenyou Yang <wenyou.yang@atmel.com>2017-04-14 07:01:27 (GMT)
committerSimon Glass <sjg@chromium.org>2017-05-09 18:14:15 (GMT)
commit5f29e79915940815a41b1364a213dd2a855cdb6d (patch)
treeb57d42aa7f25ff8de70beea139d976bac800781d /drivers/serial
parent3fea809b42cec31b5c179debfc025a2224bb2e70 (diff)
downloadu-boot-5f29e79915940815a41b1364a213dd2a855cdb6d.tar.xz
serial: atmel_usart: Fix early debug not work in SPL
Add the uart init function to be used on both probe and the early debug uart init. For the latter, the input clock should be from CONFIG_DEBUG_UART_CLOCK. Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com> Reviewed-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/atmel_usart.c36
1 files changed, 31 insertions, 5 deletions
diff --git a/drivers/serial/atmel_usart.c b/drivers/serial/atmel_usart.c
index 7674f97..8b1e0d5 100644
--- a/drivers/serial/atmel_usart.c
+++ b/drivers/serial/atmel_usart.c
@@ -25,6 +25,7 @@
DECLARE_GLOBAL_DATA_PTR;
+#ifndef CONFIG_DM_SERIAL
static void atmel_serial_setbrg_internal(atmel_usart3_t *usart, int id,
int baudrate)
{
@@ -66,7 +67,6 @@ static void atmel_serial_activate(atmel_usart3_t *usart)
__udelay(100);
}
-#ifndef CONFIG_DM_SERIAL
static void atmel_serial_setbrg(void)
{
atmel_serial_setbrg_internal((atmel_usart3_t *)CONFIG_USART_BASE,
@@ -138,12 +138,37 @@ struct atmel_serial_priv {
atmel_usart3_t *usart;
};
+static void _atmel_serial_set_brg(atmel_usart3_t *usart,
+ ulong usart_clk_rate, int baudrate)
+{
+ unsigned long divisor;
+
+ divisor = (usart_clk_rate / 16 + baudrate / 2) / baudrate;
+ writel(USART3_BF(CD, divisor), &usart->brgr);
+}
+
+void _atmel_serial_init(atmel_usart3_t *usart,
+ ulong usart_clk_rate, int baudrate)
+{
+ writel(USART3_BIT(RXDIS) | USART3_BIT(TXDIS), &usart->cr);
+
+ writel((USART3_BF(USART_MODE, USART3_USART_MODE_NORMAL) |
+ USART3_BF(USCLKS, USART3_USCLKS_MCK) |
+ USART3_BF(CHRL, USART3_CHRL_8) |
+ USART3_BF(PAR, USART3_PAR_NONE) |
+ USART3_BF(NBSTOP, USART3_NBSTOP_1)), &usart->mr);
+
+ _atmel_serial_set_brg(usart, usart_clk_rate, baudrate);
+
+ writel(USART3_BIT(RSTRX) | USART3_BIT(RSTTX), &usart->cr);
+ writel(USART3_BIT(RXEN) | USART3_BIT(TXEN), &usart->cr);
+}
+
int atmel_serial_setbrg(struct udevice *dev, int baudrate)
{
struct atmel_serial_priv *priv = dev_get_priv(dev);
- atmel_serial_setbrg_internal(priv->usart, 0 /* ignored */, baudrate);
- atmel_serial_activate(priv->usart);
+ _atmel_serial_set_brg(priv->usart, get_usart_clk_rate(0), baudrate);
return 0;
}
@@ -202,7 +227,8 @@ static int atmel_serial_probe(struct udevice *dev)
plat->base_addr = (uint32_t)addr_base;
#endif
priv->usart = (atmel_usart3_t *)plat->base_addr;
- atmel_serial_init_internal(priv->usart);
+
+ _atmel_serial_init(priv->usart, get_usart_clk_rate(0), gd->baudrate);
return 0;
}
@@ -233,7 +259,7 @@ static inline void _debug_uart_init(void)
{
atmel_usart3_t *usart = (atmel_usart3_t *)CONFIG_DEBUG_UART_BASE;
- atmel_serial_setbrg_internal(usart, 0, CONFIG_BAUDRATE);
+ _atmel_serial_init(usart, CONFIG_DEBUG_UART_CLOCK, CONFIG_BAUDRATE);
}
static inline void _debug_uart_putc(int ch)