blob: 87a337d1b4e8b862e3a6cab8ff819a5794958ed7 [file] [log] [blame]
Mike Frysinger9171fc82008-03-30 15:46:13 -04001/*
2 * serial.h - common serial defines for early debug and serial driver.
3 * any functions defined here must be always_inline since
4 * initcode cannot have function calls.
5 *
Sonic Zhanga12c51f2012-08-16 11:16:02 +08006 * Copyright (c) 2004-2011 Analog Devices Inc.
Mike Frysinger9171fc82008-03-30 15:46:13 -04007 *
8 * Licensed under the GPL-2 or later.
9 */
10
11#ifndef __BFIN_CPU_SERIAL_H__
12#define __BFIN_CPU_SERIAL_H__
13
14#include <asm/blackfin.h>
Sonic Zhanga12c51f2012-08-16 11:16:02 +080015#include <asm/portmux.h>
Mike Frysinger9171fc82008-03-30 15:46:13 -040016
Mike Frysinger76339032008-10-11 21:52:17 -040017#ifndef CONFIG_UART_CONSOLE
18# define CONFIG_UART_CONSOLE 0
19#endif
20
Mike Frysinger9171fc82008-03-30 15:46:13 -040021#ifdef CONFIG_DEBUG_EARLY_SERIAL
22# define BFIN_DEBUG_EARLY_SERIAL 1
23#else
24# define BFIN_DEBUG_EARLY_SERIAL 0
25#endif
26
Sonic Zhanga12c51f2012-08-16 11:16:02 +080027#if defined(__ADSPBF60x__)
28# define BFIN_UART_HW_VER 4
29#elif defined(__ADSPBF50x__) || defined(__ADSPBF54x__)
Mike Frysingercca07412010-12-17 15:25:09 -050030# define BFIN_UART_HW_VER 2
31#else
32# define BFIN_UART_HW_VER 1
33#endif
34
Mike Frysingerbaaa4f92010-12-17 16:23:59 -050035#define __PASTE_UART(num, pfx, sfx) pfx##num##_##sfx
36#define _PASTE_UART(num, pfx, sfx) __PASTE_UART(num, pfx, sfx)
Mike Frysinger635f3302011-04-29 23:23:28 -040037#define _P_UART(n, pin) _PASTE_UART(n, P_UART, pin)
38#define P_UART(pin) _P_UART(CONFIG_UART_CONSOLE, pin)
Mike Frysingerbaaa4f92010-12-17 16:23:59 -050039
Mike Frysinger635f3302011-04-29 23:23:28 -040040#define pUART ((volatile struct bfin_mmr_serial *)uart_base)
Mike Frysinger9171fc82008-03-30 15:46:13 -040041
Sonic Zhanga12c51f2012-08-16 11:16:02 +080042#ifndef __ASSEMBLY__
43__attribute__((always_inline))
44static inline void serial_do_portmux(void);
Mike Frysinger9171fc82008-03-30 15:46:13 -040045#endif
46
Sonic Zhanga12c51f2012-08-16 11:16:02 +080047#if BFIN_UART_HW_VER < 4
48# include "serial1.h"
49#else
50# include "serial4.h"
51#endif
52
53#ifndef __ASSEMBLY__
54
Mike Frysinger9171fc82008-03-30 15:46:13 -040055__attribute__((always_inline))
56static inline void serial_do_portmux(void)
57{
Mike Frysingera409fdd2010-06-02 06:00:27 -040058 if (!BFIN_DEBUG_EARLY_SERIAL) {
Mike Frysingerbaaa4f92010-12-17 16:23:59 -050059 const unsigned short pins[] = { P_UART(RX), P_UART(TX), 0, };
Mike Frysingera409fdd2010-06-02 06:00:27 -040060 peripheral_request_list(pins, "bfin-uart");
61 return;
62 }
63
Sonic Zhanga12c51f2012-08-16 11:16:02 +080064 serial_early_do_portmux();
Mike Frysingerf790ef62008-12-10 12:33:54 -050065}
66
Mike Frysinger9171fc82008-03-30 15:46:13 -040067#ifndef BFIN_IN_INITCODE
68__attribute__((always_inline))
69static inline void serial_early_puts(const char *s)
70{
71 if (BFIN_DEBUG_EARLY_SERIAL) {
72 serial_puts("Early: ");
73 serial_puts(s);
74 }
75}
76#endif
77
78#else
79
80.macro serial_early_init
Sonic Zhang50aadcc2013-03-13 19:06:16 +080081#if defined(CONFIG_DEBUG_EARLY_SERIAL) && !defined(CONFIG_UART_MEM)
82 call __serial_early_init;
Mike Frysinger9171fc82008-03-30 15:46:13 -040083#endif
84.endm
85
86.macro serial_early_set_baud
Sonic Zhang50aadcc2013-03-13 19:06:16 +080087#if defined(CONFIG_DEBUG_EARLY_SERIAL) && !defined(CONFIG_UART_MEM)
Mike Frysinger9171fc82008-03-30 15:46:13 -040088 R0.L = LO(CONFIG_BAUDRATE);
89 R0.H = HI(CONFIG_BAUDRATE);
Sonic Zhang50aadcc2013-03-13 19:06:16 +080090 call __serial_early_set_baud;
Mike Frysinger9171fc82008-03-30 15:46:13 -040091#endif
92.endm
93
Sonic Zhangab80b652012-11-30 17:39:32 +080094#if CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_BYPASS
95#define update_serial_early_string_addr \
96 R1.L = _start; \
97 R1.H = _start; \
98 R0 = R0 - R1; \
99 R1.L = 0; \
100 R1.H = 0x2000; \
101 R0 = R0 + R1;
102#else
103#define update_serial_early_string_addr
104#endif
105
Mike Frysinger9171fc82008-03-30 15:46:13 -0400106/* Since we embed the string right into our .text section, we need
107 * to find its address. We do this by getting our PC and adding 2
108 * bytes (which is the length of the jump instruction). Then we
109 * pass this address to serial_puts().
110 */
111#ifdef CONFIG_DEBUG_EARLY_SERIAL
112# define serial_early_puts(str) \
Mike Frysingere8e35ef2011-06-29 16:21:28 -0400113 .section .rodata; \
114 7: \
Mike Frysinger9171fc82008-03-30 15:46:13 -0400115 .ascii "Early:"; \
116 .ascii __FILE__; \
117 .ascii ": "; \
118 .ascii str; \
119 .asciz "\n"; \
Mike Frysingere8e35ef2011-06-29 16:21:28 -0400120 .previous; \
121 R0.L = 7b; \
122 R0.H = 7b; \
Sonic Zhangab80b652012-11-30 17:39:32 +0800123 update_serial_early_string_addr \
Sonic Zhang50aadcc2013-03-13 19:06:16 +0800124 call _uart_early_puts;
Mike Frysinger9171fc82008-03-30 15:46:13 -0400125#else
126# define serial_early_puts(str)
127#endif
128
129#endif
130
131#endif