blob: 87a337d1b4e8b862e3a6cab8ff819a5794958ed7 [file] [log] [blame]
Mike Frysinger94bae5c2008-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 Zhang7a91b9b2012-08-16 11:16:02 +08006 * Copyright (c) 2004-2011 Analog Devices Inc.
Mike Frysinger94bae5c2008-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 Zhang7a91b9b2012-08-16 11:16:02 +080015#include <asm/portmux.h>
Mike Frysinger94bae5c2008-03-30 15:46:13 -040016
Mike Frysinger500f2bb2008-10-11 21:52:17 -040017#ifndef CONFIG_UART_CONSOLE
18# define CONFIG_UART_CONSOLE 0
19#endif
20
Mike Frysinger94bae5c2008-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 Zhang7a91b9b2012-08-16 11:16:02 +080027#if defined(__ADSPBF60x__)
28# define BFIN_UART_HW_VER 4
29#elif defined(__ADSPBF50x__) || defined(__ADSPBF54x__)
Mike Frysinger134db0d2010-12-17 15:25:09 -050030# define BFIN_UART_HW_VER 2
31#else
32# define BFIN_UART_HW_VER 1
33#endif
Mike Frysinger3b7ed5a2009-11-12 18:42:53 -050034
Mike Frysingerfbd8ae42010-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 Frysinger53ba3222011-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 Frysingerfbd8ae42010-12-17 16:23:59 -050039
Mike Frysinger53ba3222011-04-29 23:23:28 -040040#define pUART ((volatile struct bfin_mmr_serial *)uart_base)
Mike Frysinger94bae5c2008-03-30 15:46:13 -040041
Sonic Zhang7a91b9b2012-08-16 11:16:02 +080042#ifndef __ASSEMBLY__
43__attribute__((always_inline))
44static inline void serial_do_portmux(void);
45#endif
46
47#if BFIN_UART_HW_VER < 4
48# include "serial1.h"
Mike Frysinger94bae5c2008-03-30 15:46:13 -040049#else
Sonic Zhang7a91b9b2012-08-16 11:16:02 +080050# include "serial4.h"
Mike Frysinger94bae5c2008-03-30 15:46:13 -040051#endif
52
Sonic Zhang7a91b9b2012-08-16 11:16:02 +080053#ifndef __ASSEMBLY__
54
Mike Frysinger94bae5c2008-03-30 15:46:13 -040055__attribute__((always_inline))
56static inline void serial_do_portmux(void)
57{
Mike Frysinger946550d2010-06-02 06:00:27 -040058 if (!BFIN_DEBUG_EARLY_SERIAL) {
Mike Frysingerfbd8ae42010-12-17 16:23:59 -050059 const unsigned short pins[] = { P_UART(RX), P_UART(TX), 0, };
Mike Frysinger946550d2010-06-02 06:00:27 -040060 peripheral_request_list(pins, "bfin-uart");
61 return;
62 }
Mike Frysinger94bae5c2008-03-30 15:46:13 -040063
Sonic Zhang7a91b9b2012-08-16 11:16:02 +080064 serial_early_do_portmux();
Mike Frysinger94bae5c2008-03-30 15:46:13 -040065}
66
67#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 Zhang57a32462013-03-13 19:06:16 +080081#if defined(CONFIG_DEBUG_EARLY_SERIAL) && !defined(CONFIG_UART_MEM)
82 call __serial_early_init;
Mike Frysinger94bae5c2008-03-30 15:46:13 -040083#endif
84.endm
85
86.macro serial_early_set_baud
Sonic Zhang57a32462013-03-13 19:06:16 +080087#if defined(CONFIG_DEBUG_EARLY_SERIAL) && !defined(CONFIG_UART_MEM)
Mike Frysinger94bae5c2008-03-30 15:46:13 -040088 R0.L = LO(CONFIG_BAUDRATE);
89 R0.H = HI(CONFIG_BAUDRATE);
Sonic Zhang57a32462013-03-13 19:06:16 +080090 call __serial_early_set_baud;
Mike Frysinger94bae5c2008-03-30 15:46:13 -040091#endif
92.endm
93
Sonic Zhangdbfad022012-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 Frysinger94bae5c2008-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 Frysinger24260992011-06-29 16:21:28 -0400113 .section .rodata; \
114 7: \
Mike Frysinger94bae5c2008-03-30 15:46:13 -0400115 .ascii "Early:"; \
116 .ascii __FILE__; \
117 .ascii ": "; \
118 .ascii str; \
119 .asciz "\n"; \
Mike Frysinger24260992011-06-29 16:21:28 -0400120 .previous; \
121 R0.L = 7b; \
122 R0.H = 7b; \
Sonic Zhangdbfad022012-11-30 17:39:32 +0800123 update_serial_early_string_addr \
Sonic Zhang57a32462013-03-13 19:06:16 +0800124 call _uart_early_puts;
Mike Frysinger94bae5c2008-03-30 15:46:13 -0400125#else
126# define serial_early_puts(str)
127#endif
128
129#endif
130
131#endif