[U-Boot] [PATCH 0/2] serial: atmel_usart: fix uart init and add clk support

The patches is rework the uart init to fix the early debug not work in SPL, and add the clock support.
Wenyou Yang (2): serial: atmel_usart: fix early debug not work in SPL serial: atmel_usart: add clk support
drivers/serial/atmel_usart.c | 69 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 64 insertions(+), 5 deletions(-)

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 ---
drivers/serial/atmel_usart.c | 36 +++++++++++++++++++++++++++++++----- 1 file 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)

On 22 March 2017 at 22:50, Wenyou Yang wenyou.yang@atmel.com wrote:
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
drivers/serial/atmel_usart.c | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org

Add the clock support.
Signed-off-by: Wenyou Yang wenyou.yang@atmel.com ---
drivers/serial/atmel_usart.c | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-)
diff --git a/drivers/serial/atmel_usart.c b/drivers/serial/atmel_usart.c index 8b1e0d55a4..ab213c13fa 100644 --- a/drivers/serial/atmel_usart.c +++ b/drivers/serial/atmel_usart.c @@ -7,6 +7,7 @@ * SPDX-License-Identifier: GPL-2.0+ */ #include <common.h> +#include <clk.h> #include <dm.h> #include <errno.h> #include <watchdog.h> @@ -136,6 +137,7 @@ __weak struct serial_device *default_serial_console(void)
struct atmel_serial_priv { atmel_usart3_t *usart; + ulong usart_clk_rate; };
static void _atmel_serial_set_brg(atmel_usart3_t *usart, @@ -168,7 +170,7 @@ int atmel_serial_setbrg(struct udevice *dev, int baudrate) { struct atmel_serial_priv *priv = dev_get_priv(dev);
- _atmel_serial_set_brg(priv->usart, get_usart_clk_rate(0), baudrate); + _atmel_serial_set_brg(priv->usart, priv->usart_clk_rate, baudrate);
return 0; } @@ -213,10 +215,37 @@ static const struct dm_serial_ops atmel_serial_ops = { .setbrg = atmel_serial_setbrg, };
+static int atmel_serial_enable_clk(struct udevice *dev) +{ + struct atmel_serial_priv *priv = dev_get_priv(dev); + struct clk clk; + ulong clk_rate; + int ret; + + ret = clk_get_by_index(dev, 0, &clk); + if (ret) + return -EINVAL; + + ret = clk_enable(&clk); + if (ret) + return ret; + + clk_rate = clk_get_rate(&clk); + if (!clk_rate) + return -EINVAL; + + priv->usart_clk_rate = clk_rate; + + clk_free(&clk); + + return 0; +} + static int atmel_serial_probe(struct udevice *dev) { struct atmel_serial_platdata *plat = dev->platdata; struct atmel_serial_priv *priv = dev_get_priv(dev); + int ret; #if CONFIG_IS_ENABLED(OF_CONTROL) fdt_addr_t addr_base;
@@ -228,7 +257,11 @@ static int atmel_serial_probe(struct udevice *dev) #endif priv->usart = (atmel_usart3_t *)plat->base_addr;
- _atmel_serial_init(priv->usart, get_usart_clk_rate(0), gd->baudrate); + ret = atmel_serial_enable_clk(dev); + if (ret) + return ret; + + _atmel_serial_init(priv->usart, priv->usart_clk_rate, gd->baudrate);
return 0; }

On 22 March 2017 at 22:50, Wenyou Yang wenyou.yang@atmel.com wrote:
Add the clock support.
Signed-off-by: Wenyou Yang wenyou.yang@atmel.com
drivers/serial/atmel_usart.c | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org
participants (2)
-
Simon Glass
-
Wenyou Yang