[U-Boot] [PATCH v5 15/21] rockchip: add early uart driver

Simon Glass sjg at chromium.org
Fri Nov 13 19:13:40 CET 2015


Hi Lin,

On 10 November 2015 at 03:24, Lin Huang <hl at rock-chips.com> wrote:
> add early uart driver so we can print debug message in
> SPL stage
>
> Signed-off-by: Lin Huang <hl at rock-chips.com>
> ---
> Changes in v1: None
> Changes in v2: None
> Changes in v3:
> - pass uart base address to rk_uart_init() function
> Changes in v4: None
> Changes in v5: None
>
>  arch/arm/include/asm/arch-rockchip/uart.h | 44 ++++++++++++++++++++++++
>  arch/arm/mach-rockchip/Makefile           |  1 +
>  arch/arm/mach-rockchip/rk_early_print.c   | 56 +++++++++++++++++++++++++++++++
>  3 files changed, 101 insertions(+)
>  create mode 100644 arch/arm/include/asm/arch-rockchip/uart.h
>  create mode 100644 arch/arm/mach-rockchip/rk_early_print.c

Acked-by: Simon Glass <sjg at chromium.org>

But can you please add a TODO(email) somewhere to convert this to use
the ns16550 driver when possible? It supports DEBUG_UART which is the
standard way of implementing this. See debug_uart.h for definitions of
printch(), etc.

We can worry about it later, as I understand it will need a little
extra work, but it should be possible to use the same driver code. The
problem currently is that you want to include only the debug UART
portion of the serial driver, not the serial driver itself. That seems
like a generally useful feature for very constrained devices.

Also please see nit below.

>
> diff --git a/arch/arm/include/asm/arch-rockchip/uart.h b/arch/arm/include/asm/arch-rockchip/uart.h
> new file mode 100644
> index 0000000..ea86ce6
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-rockchip/uart.h
> @@ -0,0 +1,44 @@
> +/*
> + * (C) Copyright 2015 Rockchip Electronics Co., Ltd
> + *
> + * SPDX-License-Identifier:     GPL-2.0+
> + */
> +
> +#ifndef __ASM_ARCH_UART_H
> +#define __ASM_ARCH_UART_H
> +struct rk_uart {
> +       unsigned int rbr; /* Receive buffer register. */
> +       unsigned int ier; /* Interrupt enable register. */
> +       unsigned int fcr; /* FIFO control register. */
> +       unsigned int lcr; /* Line control register. */
> +       unsigned int mcr; /* Modem control register. */
> +       unsigned int lsr; /* Line status register. */
> +       unsigned int msr; /* Modem status register. */
> +       unsigned int scr;
> +       unsigned int reserved1[(0x30 - 0x20) / 4];
> +       unsigned int srbr[(0x70 - 0x30) / 4];
> +       unsigned int far;
> +       unsigned int tfr;
> +       unsigned int rfw;
> +       unsigned int usr;
> +       unsigned int tfl;
> +       unsigned int rfl;
> +       unsigned int srr;
> +       unsigned int srts;
> +       unsigned int sbcr;
> +       unsigned int sdmam;
> +       unsigned int sfe;
> +       unsigned int srt;
> +       unsigned int stet;
> +       unsigned int htx;
> +       unsigned int dmasa;
> +       unsigned int reserver2[(0xf4 - 0xac) / 4];
> +       unsigned int cpr;
> +       unsigned int ucv;
> +       unsigned int ctr;
> +};
> +
> +void rk_uart_init(void *base);
> +void print_hex(unsigned int n);
> +void print(char *s);
> +#endif
> diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile
> index 902235b..a29675d 100644
> --- a/arch/arm/mach-rockchip/Makefile
> +++ b/arch/arm/mach-rockchip/Makefile
> @@ -10,5 +10,6 @@ else
>  obj-y += board.o
>  endif
>  obj-y += rk_timer.o
> +obj-y += rk_early_print.o
>  obj-$(CONFIG_$(SPL_)ROCKCHIP_COMMON) += common.o
>  obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288/
> diff --git a/arch/arm/mach-rockchip/rk_early_print.c b/arch/arm/mach-rockchip/rk_early_print.c
> new file mode 100644
> index 0000000..c63ebd5
> --- /dev/null
> +++ b/arch/arm/mach-rockchip/rk_early_print.c
> @@ -0,0 +1,56 @@
> +/*
> + * (C) Copyright 2015 Rockchip Electronics Co., Ltd
> + *
> + * SPDX-License-Identifier:     GPL-2.0+
> + */
> +
> +#include <asm/io.h>
> +#include <asm/arch/uart.h>
> +#include <common.h>
> +
> +static struct rk_uart *uart_ptr;
> +
> +static void uart_wrtie_byte(char byte)
> +{
> +       writel(byte, &uart_ptr->rbr);
> +       while (!(readl(&uart_ptr->lsr) & 0x40))
> +               ;
> +}
> +
> +void print(char *s)
> +{
> +       while (*s) {
> +               if (*s == '\n')
> +                       uart_wrtie_byte('\r');
> +           uart_wrtie_byte(*s);
> +           s++;
> +       }
> +}
> +
> +void print_hex(unsigned int n)
> +{
> +       int i;
> +       int temp;
> +
> +       uart_wrtie_byte('0');
> +       uart_wrtie_byte('x');
> +
> +       for (i = 8; i > 0; i--) {
> +               temp = (n >> (i - 1) * 4) & 0x0f;
> +               if (temp < 10)
> +                       uart_wrtie_byte((char)(temp + '0'));
> +               else
> +                       uart_wrtie_byte((char)(temp - 10 + 'a'));
> +       }
> +       uart_wrtie_byte('\n');
> +       uart_wrtie_byte('\r');
> +}
> +
> +void rk_uart_init(void *base)
> +{
> +       uart_ptr = (struct rk_uart *)base;
> +       writel(0x83, &uart_ptr->lcr);
> +       writel(0x0d, &uart_ptr->rbr);
> +       writel(0x03, &uart_ptr->lcr);
> +       writel(0x01, &uart_ptr->sfe);

What is sfe? Can you add a comment?

> +}
> --
> 1.9.1
>

Regards,
Simon


More information about the U-Boot mailing list