summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWenyou Yang <wenyou.yang@atmel.com>2017-04-14 15:01:27 +0800
committerSimon Glass <sjg@chromium.org>2017-05-09 12:14:15 -0600
commit5f29e79915940815a41b1364a213dd2a855cdb6d (patch)
treeb57d42aa7f25ff8de70beea139d976bac800781d
parent3fea809b42cec31b5c179debfc025a2224bb2e70 (diff)
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>
-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 7674f97e8d..8b1e0d55a4 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)