Update the LEON2/3 serial driver to make use of the readl and writel macros as well as the WATCHDOG_RESET() macro.
Also, added readl/writel and friends to the asm/io.h file. Signed-off-by: Francois Retief <fgret...@spaceteq.co.za> --- arch/sparc/cpu/leon2/serial.c | 121 +++++++++++++++++++----------------------- arch/sparc/cpu/leon3/serial.c | 93 +++++++++++++++++--------------- arch/sparc/include/asm/io.h | 43 ++++++++------- 3 files changed, 130 insertions(+), 127 deletions(-) diff --git a/arch/sparc/cpu/leon2/serial.c b/arch/sparc/cpu/leon2/serial.c index 5cfbb9e..9fe4fdd 100644 --- a/arch/sparc/cpu/leon2/serial.c +++ b/arch/sparc/cpu/leon2/serial.c @@ -7,66 +7,68 @@ */ #include <common.h> +#include <asm/io.h> #include <asm/processor.h> -#include <asm/leon.h> #include <serial.h> -#include <linux/compiler.h> +#include <watchdog.h> DECLARE_GLOBAL_DATA_PTR; -static int leon2_serial_init(void) +static inline LEON2_Uart_regs *leon2_get_uart_regs(void) { LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS; - LEON2_Uart_regs *regs; - unsigned int tmp; - /* Init LEON2 UART - * - * Set scaler / baud rate - * - * Receiver & transmitter enable - */ #if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1 - regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1; + return (LEON2_Uart_regs *)&leon2->UART_Channel_1; #else - regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2; + return (LEON2_Uart_regs *)&leon2->UART_Channel_2; #endif +} - regs->UART_Scaler = CONFIG_SYS_LEON2_UART1_SCALER; +static int leon2_serial_init(void) +{ + LEON2_Uart_regs *uart = leon2_get_uart_regs(); + unsigned int tmp; - /* Let bit 11 be unchanged (debug bit for GRMON) */ - tmp = READ_WORD(regs->UART_Control); + /* Init LEON2 UART */ + if (!uart) + return -1; - regs->UART_Control = ((tmp & LEON2_UART_CTRL_DBG) | - (LEON2_UART1_LOOPBACK_ENABLE << 7) | - (LEON2_UART1_FLOWCTRL_ENABLE << 6) | - (LEON2_UART1_PARITY_ENABLE << 5) | - (LEON2_UART1_ODDPAR_ENABLE << 4) | - LEON2_UART_CTRL_RE | LEON2_UART_CTRL_TE); + /* Set scaler / baud rate */ + tmp = (((CONFIG_SYS_CLK_FREQ * 10)/(CONFIG_BAUDRATE * 8)) - 5) / 10; + writel(tmp, &uart->UART_Scaler); + + /* Let bit 11 be unchanged (debug bit for GRMON) */ + tmp = readl(&uart->UART_Control) & LEON2_UART_CTRL_DBG; + tmp |= (LEON2_UART1_LOOPBACK_ENABLE << 7); + tmp |= (LEON2_UART1_FLOWCTRL_ENABLE << 6); + tmp |= (LEON2_UART1_PARITY_ENABLE << 5); + tmp |= (LEON2_UART1_ODDPAR_ENABLE << 4); + /* Receiver & transmitter enable */ + tmp |= (LEON2_UART_CTRL_RE | LEON2_UART_CTRL_TE); + writel(tmp, &uart->UART_Control); return 0; } static void leon2_serial_putc_raw(const char c) { - LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS; - LEON2_Uart_regs *regs; + LEON2_Uart_regs *uart = leon2_get_uart_regs(); -#if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1 - regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1; -#else - regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2; -#endif + if (!uart) + return; /* Wait for last character to go. */ - while (!(READ_WORD(regs->UART_Status) & LEON2_UART_STAT_THE)) ; + while (!(readl(&uart->UART_Status) & LEON2_UART_STAT_THE)) + WATCHDOG_RESET(); /* Send data */ - regs->UART_Channel = c; + writel(c, &uart->UART_Channel); #ifdef LEON_DEBUG /* Wait for data to be sent */ - while (!(READ_WORD(regs->UART_Status) & LEON2_UART_STAT_TSE)) ; + while (!(readl(&uart->UART_Status) & LEON2_UART_STAT_TSE)) + WATCHDOG_RESET(); #endif } @@ -80,56 +82,43 @@ static void leon2_serial_putc(const char c) static int leon2_serial_getc(void) { - LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS; - LEON2_Uart_regs *regs; + LEON2_Uart_regs *uart = leon2_get_uart_regs(); -#if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1 - regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1; -#else - regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2; -#endif + if (!uart) + return 0; - /* Wait for a character to arrive. */ - while (!(READ_WORD(regs->UART_Status) & LEON2_UART_STAT_DR)) ; + /* Wait for a character to arrive */ + while (!(readl(&uart->UART_Status) & LEON2_UART_STAT_DR)) + WATCHDOG_RESET(); - /* read data */ - return READ_WORD(regs->UART_Channel); + /* Read character data */ + return readl(&uart->UART_Channel); } static int leon2_serial_tstc(void) { - LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS; - LEON2_Uart_regs *regs; + LEON2_Uart_regs *uart = leon2_get_uart_regs(); -#if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1 - regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1; -#else - regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2; -#endif + if (!uart) + return 0; - return (READ_WORD(regs->UART_Status) & LEON2_UART_STAT_DR); + return readl(&uart->UART_Status) & LEON2_UART_STAT_DR; } -/* set baud rate for uart */ static void leon2_serial_setbrg(void) { - /* update baud rate settings, read it from gd->baudrate */ + LEON2_Uart_regs *uart = leon2_get_uart_regs(); unsigned int scaler; - LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS; - LEON2_Uart_regs *regs; -#if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1 - regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1; -#else - regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2; -#endif + if (!uart) + return; + + if (!gd->baudrate) + gd->baudrate = CONFIG_BAUDRATE; + + scaler = (((CONFIG_SYS_CLK_FREQ * 10)/(gd->baudrate * 8)) - 5) / 10; - if (gd->baudrate > 0) { - scaler = - (((CONFIG_SYS_CLK_FREQ * 10) / (gd->baudrate * 8)) - - 5) / 10; - regs->UART_Scaler = scaler; - } + writel(scaler, &uart->UART_Scaler); } static struct serial_device leon2_serial_drv = { diff --git a/arch/sparc/cpu/leon3/serial.c b/arch/sparc/cpu/leon3/serial.c index bca6b65..bd3b09b 100644 --- a/arch/sparc/cpu/leon3/serial.c +++ b/arch/sparc/cpu/leon3/serial.c @@ -7,11 +7,10 @@ */ #include <common.h> -#include <asm/processor.h> -#include <asm/leon.h> +#include <asm/io.h> #include <ambapp.h> #include <serial.h> -#include <linux/compiler.h> +#include <watchdog.h> DECLARE_GLOBAL_DATA_PTR; @@ -19,48 +18,49 @@ ambapp_dev_apbuart *leon3_apbuart = NULL; static int leon3_serial_init(void) { + ambapp_dev_apbuart *uart; ambapp_apbdev apbdev; unsigned int tmp; /* find UART */ - if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_APBUART, &apbdev) == 1) { + if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_APBUART, &apbdev) != 1) + return -1; /* didn't find hardware */ - leon3_apbuart = (ambapp_dev_apbuart *) apbdev.address; + /* found apbuart, let's init .. */ + uart = (ambapp_dev_apbuart *) apbdev.address; - /* found apbuart, let's init... - * - * Set scaler / baud rate - * - * Receiver & transmitter enable - */ - leon3_apbuart->scaler = CONFIG_SYS_GRLIB_APBUART_SCALER; + /* Set scaler / baud rate */ + tmp = (((CONFIG_SYS_CLK_FREQ * 10)/(CONFIG_BAUDRATE * 8)) - 5) / 10; + writel(tmp, &uart->scaler); - /* Let bit 11 be unchanged (debug bit for GRMON) */ - tmp = READ_WORD(leon3_apbuart->ctrl); + /* Let bit 11 be unchanged (debug bit for GRMON) */ + tmp = readl(&uart->ctrl) & LEON_REG_UART_CTRL_DBG; + /* Receiver & transmitter enable */ + tmp |= LEON_REG_UART_CTRL_RE | LEON_REG_UART_CTRL_TE; + writel(tmp, &uart->ctrl); - leon3_apbuart->ctrl = ((tmp & LEON_REG_UART_CTRL_DBG) | - LEON_REG_UART_CTRL_RE | - LEON_REG_UART_CTRL_TE); - - return 0; - } - return -1; /* didn't find hardware */ + leon3_apbuart = uart; + return 0; } static void leon3_serial_putc_raw(const char c) { - if (!leon3_apbuart) + ambapp_dev_apbuart * const uart = leon3_apbuart; + + if (!uart) return; /* Wait for last character to go. */ - while (!(READ_WORD(leon3_apbuart->status) & LEON_REG_UART_STATUS_THE)) ; + while (!(readl(&uart->status) & LEON_REG_UART_STATUS_THE)) + WATCHDOG_RESET(); /* Send data */ - leon3_apbuart->data = c; + writel(c, &uart->data); #ifdef LEON_DEBUG /* Wait for data to be sent */ - while (!(READ_WORD(leon3_apbuart->status) & LEON_REG_UART_STATUS_TSE)) ; + while (!(readl(&uart->status) & LEON_REG_UART_STATUS_TSE)) + WATCHDOG_RESET(); #endif } @@ -74,36 +74,43 @@ static void leon3_serial_putc(const char c) static int leon3_serial_getc(void) { - if (!leon3_apbuart) + ambapp_dev_apbuart * const uart = leon3_apbuart; + + if (!uart) return 0; - /* Wait for a character to arrive. */ - while (!(READ_WORD(leon3_apbuart->status) & LEON_REG_UART_STATUS_DR)) ; + /* Wait for a character to arrive */ + while (!(readl(&uart->status) & LEON_REG_UART_STATUS_DR)) + WATCHDOG_RESET(); - /* read data */ - return READ_WORD(leon3_apbuart->data); + /* Read character data */ + return readl(&uart->data); } static int leon3_serial_tstc(void) { - if (leon3_apbuart) - return (READ_WORD(leon3_apbuart->status) & - LEON_REG_UART_STATUS_DR); - return 0; + ambapp_dev_apbuart * const uart = leon3_apbuart; + + if (!uart) + return 0; + + return readl(&uart->status) & LEON_REG_UART_STATUS_DR; } -/* set baud rate for uart */ static void leon3_serial_setbrg(void) { - /* update baud rate settings, read it from gd->baudrate */ + ambapp_dev_apbuart * const uart = leon3_apbuart; unsigned int scaler; - if (leon3_apbuart && (gd->baudrate > 0)) { - scaler = - (((CONFIG_SYS_CLK_FREQ * 10) / (gd->baudrate * 8)) - - 5) / 10; - leon3_apbuart->scaler = scaler; - } - return; + + if (!uart) + return; + + if (!gd->baudrate) + gd->baudrate = CONFIG_BAUDRATE; + + scaler = (((CONFIG_SYS_CLK_FREQ * 10)/(gd->baudrate * 8)) - 5) / 10; + + writel(scaler, &uart->scaler); } static struct serial_device leon3_serial_drv = { diff --git a/arch/sparc/include/asm/io.h b/arch/sparc/include/asm/io.h index f7b89c8..93aff1d 100644 --- a/arch/sparc/include/asm/io.h +++ b/arch/sparc/include/asm/io.h @@ -12,31 +12,30 @@ /* Nothing to sync, total store ordering (TSO)... */ #define sync() +/* + * Generic virtual read/write. + */ + +#ifndef CONFIG_SYS_HAS_NO_CACHE + /* Forces a cache miss on read/load. * On some architectures we need to bypass the cache when reading * I/O registers so that we are not reading the same status word * over and over again resulting in a hang (until an IRQ if lucky) - * */ -#ifndef CONFIG_SYS_HAS_NO_CACHE -#define READ_BYTE(var) SPARC_NOCACHE_READ_BYTE((unsigned int)(var)) -#define READ_HWORD(var) SPARC_NOCACHE_READ_HWORD((unsigned int)(var)) -#define READ_WORD(var) SPARC_NOCACHE_READ((unsigned int)(var)) -#define READ_DWORD(var) SPARC_NOCACHE_READ_DWORD((unsigned int)(var)) +#define __arch_getb(a) SPARC_NOCACHE_READ_BYTE((unsigned int)(a)) +#define __arch_getw(a) SPARC_NOCACHE_READ_HWORD((unsigned int)(a)) +#define __arch_getl(a) SPARC_NOCACHE_READ((unsigned int)(a)) +#define __arch_getq(a) SPARC_NOCACHE_READ_DWORD((unsigned int)(a)) + #else -#define READ_BYTE(var) (var) -#define READ_HWORD(var) (var) -#define READ_WORD(var) (var) -#define READ_DWORD(var) (var) -#endif -/* - * Generic virtual read/write. - */ -#define __arch_getb(a) (READ_BYTE(a)) -#define __arch_getw(a) (READ_HWORD(a)) -#define __arch_getl(a) (READ_WORD(a)) -#define __arch_getq(a) (READ_DWORD(a)) +#define __arch_getb(a) (*(volatile unsigned char *)(a)) +#define __arch_getw(a) (*(volatile unsigned short *)(a)) +#define __arch_getl(a) (*(volatile unsigned int *)(a)) +#define __arch_getq(a) (*(volatile unsigned long long *)(a)) + +#endif /* CONFIG_SYS_HAS_NO_CACHE */ #define __arch_putb(v,a) (*(volatile unsigned char *)(a) = (v)) #define __arch_putw(v,a) (*(volatile unsigned short *)(a) = (v)) @@ -51,6 +50,14 @@ #define __raw_readl(a) __arch_getl(a) #define __raw_readq(a) __arch_getq(a) +#define writeb __raw_writeb +#define writew __raw_writew +#define writel __raw_writel + +#define readb __raw_readb +#define readw __raw_readw +#define readl __raw_readl + /* * Given a physical address and a length, return a virtual address * that can be used to access the memory range with the caching -- 1.9.3 ________________________________ Disclaimer and confidentiality note – refer to our website for further details: www.spaceteq.co.za <http://www.spaceteq.co.za/home/emaildisclaimer/> _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot