Ronald G. Minnich (rminnich@gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2414
-gerrit
commit eb8fb19a430333f1ce9fbe19ef17dee2d66f49d1 Author: Ronald G. Minnich rminnich@gmail.com Date: Fri Feb 15 09:44:28 2013 -0800
libpayload: add support for the exynos5 UART
This CL adds *limited* support for the exynos5 uart. It's a new BSD-licensed implementation.
We support read, write, and test for input as in the existing serial.c. Because of the plethora of other hardware that it would bring in, we've decided for now to leave out configuration operations such as setting baud rate. Set it right in coreboot and leave it alone.
Add two new variables, EXYNOS5_SERIAL_CONSOLE -- enable it EXYNOS5_SERIAL_BASE -- set the base
in Config.in, add options for selecting the UART and setting its base address; a reasonable default is configured.
Set that default into sysinfo if EXYNOS5_SERIAL_CONSOLE is set.
Compile the UART in if EXYNOS5_SERIAL_CONSOLE is set.
Add the slightly truncated code from coreboot; don't bother with an include file, only this one file needs to see the structs. This is one case where an include file would do more harm than good.
Change-Id: Iff1f601a8ba5e69d63eb10763e748c92a03a3df8 Signed-off-by: Ronald G. Minnich rminnich@gmail.com --- payloads/libpayload/Config.in | 12 ++- payloads/libpayload/arch/armv7/sysinfo.c | 3 + payloads/libpayload/drivers/Makefile.inc | 1 + payloads/libpayload/drivers/exynos5250_uart.c | 117 ++++++++++++++++++++++++++ 4 files changed, 132 insertions(+), 1 deletion(-)
diff --git a/payloads/libpayload/Config.in b/payloads/libpayload/Config.in index a14291d..ccc9449 100644 --- a/payloads/libpayload/Config.in +++ b/payloads/libpayload/Config.in @@ -70,7 +70,7 @@ choice config ARCH_ARMV7 bool "ARMv7" help - Support the x86 architecture + Support the ARMV7 architecture
config ARCH_POWERPC bool "PowerPC" @@ -168,6 +168,16 @@ config SERIAL_CONSOLE bool "See output on the serial port console" default y
+config EXYNOS5_SERIAL_CONSOLE + bool "Exynos 5xxx serial console" + depends on ARCH_ARMV7 + default n + +config EXYNOS5_SERIAL_BASE + hex "Base for the Exynos5 serial port" + depends on EXYNOS5_SERIAL_CONSOLE + default 0x12c30000 + config SERIAL_IOBASE hex "I/O base for the serial port (default 0x3f8)" depends on SERIAL_CONSOLE diff --git a/payloads/libpayload/arch/armv7/sysinfo.c b/payloads/libpayload/arch/armv7/sysinfo.c index 5aa5175..fc527d2 100644 --- a/payloads/libpayload/arch/armv7/sysinfo.c +++ b/payloads/libpayload/arch/armv7/sysinfo.c @@ -37,6 +37,9 @@ */ struct sysinfo_t lib_sysinfo = { .cpu_khz = 200, +#ifdef CONFIG_SERIAL_CONSOLE + .ser_base = CONFIG_EXYNOS5_SERIAL_BASE, +#endif };
int lib_get_sysinfo(void) diff --git a/payloads/libpayload/drivers/Makefile.inc b/payloads/libpayload/drivers/Makefile.inc index e3bb995..71c2519 100644 --- a/payloads/libpayload/drivers/Makefile.inc +++ b/payloads/libpayload/drivers/Makefile.inc @@ -34,6 +34,7 @@ libc-$(CONFIG_PCI) += pci.c libc-$(CONFIG_SPEAKER) += speaker.c
libc-$(CONFIG_SERIAL_CONSOLE) += serial.c +libc-$(CONFIG_EXYNOS5_SERIAL_CONSOLE) += exynos5250_uart.c
libc-$(CONFIG_PC_KEYBOARD) += keyboard.c
diff --git a/payloads/libpayload/drivers/exynos5250_uart.c b/payloads/libpayload/drivers/exynos5250_uart.c new file mode 100644 index 0000000..d051f36 --- /dev/null +++ b/payloads/libpayload/drivers/exynos5250_uart.c @@ -0,0 +1,117 @@ +/* + * This file is part of the libpayload project. + * + * Copyright (C) 2013 Google, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <libpayload-config.h> +#include <libpayload.h> + +/* + * this is a seriously cut-down UART implementation, the assumption + * being that you should let coreboot set it up. It's quite + * messy to keep doing UART setup everywhere on these ARM SOCs. + */ + +/* word offset of registers from MEMBASE */ +enum { + /* RX and TX data. + * these are the lsb of the word + */ + RXDATA = 9, + TXDATA = 8, + + ERR = 5, + FIFOSTAT = 6, + RXCOUNT = 0xff, + RXFULL = 0x100, + RXREADY = 0x1ff, + TXFULL = 1<<24, +}; + +#define MEMBASE (u32 *)(phys_to_virt(lib_sysinfo.serial->baseaddr)) + +static inline u8 regreadb(u32 reg) +{ + return readb(MEMBASE + reg); +} + +static inline u32 regreadl(u32 reg) +{ + return readl(MEMBASE + reg); +} + +static inline void regwritel(u32 val, u32 reg) +{ + writel(val, MEMBASE + reg); +} + +static inline void regwriteb(u8 val, u32 reg) +{ + writeb(val, MEMBASE + reg); +} + +/* + * Initialise the serial port. + * This hardware is really complex, and we're not going to pretend + * it's a good idea to mess with it here. So, take what coreboot did + * and leave it at that. + */ +void serial_init(void) +{ +} + +int serial_havechar(void) +{ + return (regreadl(ERR)&RXREADY); +} + +int serial_getchar(void) +{ + /* wait for character to arrive */ + while (! serial_havechar()) + ; + return regreadl(RXDATA); +} + +static int serial_cansend(void) +{ + return (! (regreadl(FIFOSTAT)&TXFULL)); +} + +/* + * Output a single byte to the serial port. + * The function is defined as taking an int; unfortunate. + */ +void serial_putchar(unsigned int c) +{ + + /* wait for room in the tx FIFO */ + while (! serial_cansend()) + ; + + regwriteb(c, TXDATA); +}