diff options
Diffstat (limited to 'arch/blackfin/include/asm/serial.h')
-rw-r--r-- | arch/blackfin/include/asm/serial.h | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/arch/blackfin/include/asm/serial.h b/arch/blackfin/include/asm/serial.h new file mode 100644 index 0000000000..87a337d1b4 --- /dev/null +++ b/arch/blackfin/include/asm/serial.h @@ -0,0 +1,131 @@ +/* + * serial.h - common serial defines for early debug and serial driver. + * any functions defined here must be always_inline since + * initcode cannot have function calls. + * + * Copyright (c) 2004-2011 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#ifndef __BFIN_CPU_SERIAL_H__ +#define __BFIN_CPU_SERIAL_H__ + +#include <asm/blackfin.h> +#include <asm/portmux.h> + +#ifndef CONFIG_UART_CONSOLE +# define CONFIG_UART_CONSOLE 0 +#endif + +#ifdef CONFIG_DEBUG_EARLY_SERIAL +# define BFIN_DEBUG_EARLY_SERIAL 1 +#else +# define BFIN_DEBUG_EARLY_SERIAL 0 +#endif + +#if defined(__ADSPBF60x__) +# define BFIN_UART_HW_VER 4 +#elif defined(__ADSPBF50x__) || defined(__ADSPBF54x__) +# define BFIN_UART_HW_VER 2 +#else +# define BFIN_UART_HW_VER 1 +#endif + +#define __PASTE_UART(num, pfx, sfx) pfx##num##_##sfx +#define _PASTE_UART(num, pfx, sfx) __PASTE_UART(num, pfx, sfx) +#define _P_UART(n, pin) _PASTE_UART(n, P_UART, pin) +#define P_UART(pin) _P_UART(CONFIG_UART_CONSOLE, pin) + +#define pUART ((volatile struct bfin_mmr_serial *)uart_base) + +#ifndef __ASSEMBLY__ +__attribute__((always_inline)) +static inline void serial_do_portmux(void); +#endif + +#if BFIN_UART_HW_VER < 4 +# include "serial1.h" +#else +# include "serial4.h" +#endif + +#ifndef __ASSEMBLY__ + +__attribute__((always_inline)) +static inline void serial_do_portmux(void) +{ + if (!BFIN_DEBUG_EARLY_SERIAL) { + const unsigned short pins[] = { P_UART(RX), P_UART(TX), 0, }; + peripheral_request_list(pins, "bfin-uart"); + return; + } + + serial_early_do_portmux(); +} + +#ifndef BFIN_IN_INITCODE +__attribute__((always_inline)) +static inline void serial_early_puts(const char *s) +{ + if (BFIN_DEBUG_EARLY_SERIAL) { + serial_puts("Early: "); + serial_puts(s); + } +} +#endif + +#else + +.macro serial_early_init +#if defined(CONFIG_DEBUG_EARLY_SERIAL) && !defined(CONFIG_UART_MEM) + call __serial_early_init; +#endif +.endm + +.macro serial_early_set_baud +#if defined(CONFIG_DEBUG_EARLY_SERIAL) && !defined(CONFIG_UART_MEM) + R0.L = LO(CONFIG_BAUDRATE); + R0.H = HI(CONFIG_BAUDRATE); + call __serial_early_set_baud; +#endif +.endm + +#if CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_BYPASS +#define update_serial_early_string_addr \ + R1.L = _start; \ + R1.H = _start; \ + R0 = R0 - R1; \ + R1.L = 0; \ + R1.H = 0x2000; \ + R0 = R0 + R1; +#else +#define update_serial_early_string_addr +#endif + +/* Since we embed the string right into our .text section, we need + * to find its address. We do this by getting our PC and adding 2 + * bytes (which is the length of the jump instruction). Then we + * pass this address to serial_puts(). + */ +#ifdef CONFIG_DEBUG_EARLY_SERIAL +# define serial_early_puts(str) \ + .section .rodata; \ + 7: \ + .ascii "Early:"; \ + .ascii __FILE__; \ + .ascii ": "; \ + .ascii str; \ + .asciz "\n"; \ + .previous; \ + R0.L = 7b; \ + R0.H = 7b; \ + update_serial_early_string_addr \ + call _uart_early_puts; +#else +# define serial_early_puts(str) +#endif + +#endif + +#endif |