
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.
Lastly, removed baudrate scaler macro variables from board config. It is now calculated in the serial driver using the global data variable.
Signed-off-by: Francois Retief fgretief@spaceteq.co.za ---
arch/sparc/cpu/leon2/serial.c | 121 ++++++++++++++++++--------------------- arch/sparc/cpu/leon3/serial.c | 93 ++++++++++++++++-------------- arch/sparc/include/asm/io.h | 43 ++++++++------ include/configs/gr_cpci_ax2000.h | 4 -- include/configs/gr_ep2s60.h | 4 -- include/configs/gr_xc3s_1500.h | 4 -- include/configs/grsim.h | 3 - 7 files changed, 130 insertions(+), 142 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 diff --git a/include/configs/gr_cpci_ax2000.h b/include/configs/gr_cpci_ax2000.h index 3029f42..344aea1 100644 --- a/include/configs/gr_cpci_ax2000.h +++ b/include/configs/gr_cpci_ax2000.h @@ -343,10 +343,6 @@ #define CONFIG_SYS_GRLIB_DDR2_CFG1 0x00000000 #define CONFIG_SYS_GRLIB_DDR2_CFG3 0x00000000
-/* Calculate scaler register value from default baudrate */ -#define CONFIG_SYS_GRLIB_APBUART_SCALER \ - ((((CONFIG_SYS_CLK_FREQ*10)/(CONFIG_BAUDRATE*8))-5)/10) - /* Identification string */ #define CONFIG_IDENT_STRING " Gaisler LEON3 GR-CPCI-AX2000"
diff --git a/include/configs/gr_ep2s60.h b/include/configs/gr_ep2s60.h index 32ee7c9..4460dde 100644 --- a/include/configs/gr_ep2s60.h +++ b/include/configs/gr_ep2s60.h @@ -318,10 +318,6 @@ #define CONFIG_SYS_GRLIB_DDR2_CFG1 0x00000000 #define CONFIG_SYS_GRLIB_DDR2_CFG3 0x00000000
-/* Calculate scaler register value from default baudrate */ -#define CONFIG_SYS_GRLIB_APBUART_SCALER \ - ((((CONFIG_SYS_CLK_FREQ*10)/(CONFIG_BAUDRATE*8))-5)/10) - /* Identification string */ #define CONFIG_IDENT_STRING " Gaisler LEON3 EP2S60"
diff --git a/include/configs/gr_xc3s_1500.h b/include/configs/gr_xc3s_1500.h index 565310e..e546ed6 100644 --- a/include/configs/gr_xc3s_1500.h +++ b/include/configs/gr_xc3s_1500.h @@ -283,10 +283,6 @@ #define CONFIG_SYS_GRLIB_DDR2_CFG1 0x00000000 #define CONFIG_SYS_GRLIB_DDR2_CFG3 0x00000000
-/* Calculate scaler register value from default baudrate */ -#define CONFIG_SYS_GRLIB_APBUART_SCALER \ - ((((CONFIG_SYS_CLK_FREQ*10)/(CONFIG_BAUDRATE*8))-5)/10) - /* Identification string */ #define CONFIG_IDENT_STRING " Gaisler LEON3 GR-XC3S-1500"
diff --git a/include/configs/grsim.h b/include/configs/grsim.h index 3b70983..a7b9dae 100644 --- a/include/configs/grsim.h +++ b/include/configs/grsim.h @@ -310,9 +310,6 @@ #define CONFIG_SYS_GRLIB_DDR2_CFG1 0x00000000 #define CONFIG_SYS_GRLIB_DDR2_CFG3 0x00000000
-#define CONFIG_SYS_GRLIB_APBUART_SCALER \ - ((((CONFIG_SYS_CLK_FREQ*10)/(CONFIG_BAUDRATE*8))-5)/10) - /* default kernel command line */ #define CONFIG_DEFAULT_KERNEL_COMMAND_LINE "console=ttyS0,38400\0\0"
-- 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/