132 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			132 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C
		
	
	
	
| /*
 | |
|  * 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
 |