Commit | Line | Data |
---|---|---|
c5f80065 | 1 | /* |
6d7d7b3e SW |
2 | * Copyright (C) 2010,2011 Google, Inc. |
3 | * Copyright (C) 2011-2012 NVIDIA CORPORATION. All Rights Reserved. | |
c5f80065 EG |
4 | * |
5 | * Author: | |
6 | * Colin Cross <ccross@google.com> | |
7 | * Erik Gilling <konkers@google.com> | |
6d7d7b3e SW |
8 | * Doug Anderson <dianders@chromium.org> |
9 | * Stephen Warren <swarren@nvidia.com> | |
10 | * | |
11 | * Portions based on mach-omap2's debug-macro.S | |
12 | * Copyright (C) 1994-1999 Russell King | |
c5f80065 EG |
13 | * |
14 | * This software is licensed under the terms of the GNU General Public | |
15 | * License version 2, as published by the Free Software Foundation, and | |
16 | * may be copied, distributed, and modified under those terms. | |
17 | * | |
18 | * This program is distributed in the hope that it will be useful, | |
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
21 | * GNU General Public License for more details. | |
22 | * | |
23 | */ | |
24 | ||
6d7d7b3e SW |
25 | #include <linux/serial_reg.h> |
26 | ||
1a6d3da8 SW |
27 | #define UART_SHIFT 2 |
28 | ||
7a281065 SW |
29 | /* Physical addresses */ |
30 | #define TEGRA_CLK_RESET_BASE 0x60006000 | |
31 | #define TEGRA_APB_MISC_BASE 0x70000000 | |
32 | #define TEGRA_UARTA_BASE 0x70006000 | |
33 | #define TEGRA_UARTB_BASE 0x70006040 | |
34 | #define TEGRA_UARTC_BASE 0x70006200 | |
35 | #define TEGRA_UARTD_BASE 0x70006300 | |
36 | #define TEGRA_UARTE_BASE 0x70006400 | |
37 | #define TEGRA_PMC_BASE 0x7000e400 | |
38 | ||
1a6d3da8 SW |
39 | #define TEGRA_CLK_RST_DEVICES_L (TEGRA_CLK_RESET_BASE + 0x04) |
40 | #define TEGRA_CLK_RST_DEVICES_H (TEGRA_CLK_RESET_BASE + 0x08) | |
41 | #define TEGRA_CLK_RST_DEVICES_U (TEGRA_CLK_RESET_BASE + 0x0c) | |
42 | #define TEGRA_CLK_OUT_ENB_L (TEGRA_CLK_RESET_BASE + 0x10) | |
43 | #define TEGRA_CLK_OUT_ENB_H (TEGRA_CLK_RESET_BASE + 0x14) | |
44 | #define TEGRA_CLK_OUT_ENB_U (TEGRA_CLK_RESET_BASE + 0x18) | |
45 | #define TEGRA_PMC_SCRATCH20 (TEGRA_PMC_BASE + 0xa0) | |
46 | #define TEGRA_APB_MISC_GP_HIDREV (TEGRA_APB_MISC_BASE + 0x804) | |
47 | ||
7a281065 | 48 | /* |
354935a9 | 49 | * Must be section-aligned since a section mapping is used early on. |
7a281065 SW |
50 | * Must not overlap with regions in mach-tegra/io.c:tegra_io_desc[]. |
51 | */ | |
354935a9 | 52 | #define UART_VIRTUAL_BASE 0xfe800000 |
7a281065 | 53 | |
1a6d3da8 SW |
54 | #define checkuart(rp, rv, lhu, bit, uart) \ |
55 | /* Load address of CLK_RST register */ \ | |
9f3ba456 | 56 | ldr rp, =TEGRA_CLK_RST_DEVICES_##lhu ; \ |
1a6d3da8 SW |
57 | /* Load value from CLK_RST register */ \ |
58 | ldr rp, [rp, #0] ; \ | |
59 | /* Test UART's reset bit */ \ | |
60 | tst rp, #(1 << bit) ; \ | |
61 | /* If set, can't use UART; jump to save no UART */ \ | |
62 | bne 90f ; \ | |
63 | /* Load address of CLK_OUT_ENB register */ \ | |
9f3ba456 | 64 | ldr rp, =TEGRA_CLK_OUT_ENB_##lhu ; \ |
1a6d3da8 SW |
65 | /* Load value from CLK_OUT_ENB register */ \ |
66 | ldr rp, [rp, #0] ; \ | |
67 | /* Test UART's clock enable bit */ \ | |
68 | tst rp, #(1 << bit) ; \ | |
69 | /* If clear, can't use UART; jump to save no UART */ \ | |
70 | beq 90f ; \ | |
71 | /* Passed all tests, load address of UART registers */ \ | |
9f3ba456 | 72 | ldr rp, =TEGRA_UART##uart##_BASE ; \ |
1a6d3da8 SW |
73 | /* Jump to save UART address */ \ |
74 | b 91f | |
6d7d7b3e SW |
75 | |
76 | .macro addruart, rp, rv, tmp | |
77 | adr \rp, 99f @ actual addr of 99f | |
78 | ldr \rv, [\rp] @ linked addr is stored there | |
79 | sub \rv, \rv, \rp @ offset between the two | |
80 | ldr \rp, [\rp, #4] @ linked tegra_uart_config | |
81 | sub \tmp, \rp, \rv @ actual tegra_uart_config | |
82 | ldr \rp, [\tmp] @ Load tegra_uart_config | |
1a6d3da8 | 83 | cmp \rp, #1 @ needs initialization? |
6d7d7b3e SW |
84 | bne 100f @ no; go load the addresses |
85 | mov \rv, #0 @ yes; record init is done | |
86 | str \rv, [\tmp] | |
1a6d3da8 SW |
87 | |
88 | #ifdef CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA | |
89 | /* Check ODMDATA */ | |
9f3ba456 | 90 | 10: ldr \rp, =TEGRA_PMC_SCRATCH20 |
1a6d3da8 | 91 | ldr \rp, [\rp, #0] @ Load PMC_SCRATCH20 |
9f3ba456 AB |
92 | lsr \rv, \rp, #18 @ 19:18 are console type |
93 | and \rv, \rv, #3 | |
1a6d3da8 SW |
94 | cmp \rv, #2 @ 2 and 3 mean DCC, UART |
95 | beq 11f @ some boards swap the meaning | |
96 | cmp \rv, #3 @ so accept either | |
97 | bne 90f | |
9f3ba456 AB |
98 | 11: lsr \rv, \rp, #15 @ 17:15 are UART ID |
99 | and \rv, #7 | |
1a6d3da8 SW |
100 | cmp \rv, #0 @ UART 0? |
101 | beq 20f | |
102 | cmp \rv, #1 @ UART 1? | |
103 | beq 21f | |
104 | cmp \rv, #2 @ UART 2? | |
105 | beq 22f | |
106 | cmp \rv, #3 @ UART 3? | |
107 | beq 23f | |
108 | cmp \rv, #4 @ UART 4? | |
109 | beq 24f | |
110 | b 90f @ invalid | |
111 | #endif | |
112 | ||
113 | #if defined(CONFIG_TEGRA_DEBUG_UARTA) || \ | |
114 | defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA) | |
115 | /* Check UART A validity */ | |
116 | 20: checkuart(\rp, \rv, L, 6, A) | |
117 | #endif | |
118 | ||
119 | #if defined(CONFIG_TEGRA_DEBUG_UARTB) || \ | |
120 | defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA) | |
121 | /* Check UART B validity */ | |
122 | 21: checkuart(\rp, \rv, L, 7, B) | |
123 | #endif | |
124 | ||
125 | #if defined(CONFIG_TEGRA_DEBUG_UARTC) || \ | |
126 | defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA) | |
127 | /* Check UART C validity */ | |
128 | 22: checkuart(\rp, \rv, H, 23, C) | |
129 | #endif | |
130 | ||
131 | #if defined(CONFIG_TEGRA_DEBUG_UARTD) || \ | |
132 | defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA) | |
133 | /* Check UART D validity */ | |
134 | 23: checkuart(\rp, \rv, U, 1, D) | |
135 | #endif | |
136 | ||
137 | #if defined(CONFIG_TEGRA_DEBUG_UARTE) || \ | |
138 | defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA) | |
139 | /* Check UART E validity */ | |
140 | 24: | |
141 | checkuart(\rp, \rv, U, 2, E) | |
142 | #endif | |
143 | ||
144 | /* No valid UART found */ | |
145 | 90: mov \rp, #0 | |
146 | /* fall through */ | |
147 | ||
148 | /* Record whichever UART we chose */ | |
149 | 91: str \rp, [\tmp, #4] @ Store in tegra_uart_phys | |
150 | cmp \rp, #0 @ Valid UART address? | |
151 | bne 92f @ Yes, go process it | |
7a281065 | 152 | str \rp, [\tmp, #8] @ Store 0 in tegra_uart_virt |
1a6d3da8 | 153 | b 100f @ Done |
7a281065 SW |
154 | 92: and \rv, \rp, #0xffffff @ offset within 1MB section |
155 | add \rv, \rv, #UART_VIRTUAL_BASE | |
6d7d7b3e SW |
156 | str \rv, [\tmp, #8] @ Store in tegra_uart_virt |
157 | b 100f | |
158 | ||
159 | .align | |
160 | 99: .word . | |
161 | .word tegra_uart_config | |
162 | .ltorg | |
163 | ||
1a6d3da8 | 164 | /* Load previously selected UART address */ |
6d7d7b3e SW |
165 | 100: ldr \rp, [\tmp, #4] @ Load tegra_uart_phys |
166 | ldr \rv, [\tmp, #8] @ Load tegra_uart_virt | |
167 | .endm | |
168 | ||
6d7d7b3e SW |
169 | /* |
170 | * Code below is swiped from <asm/hardware/debug-8250.S>, but add an extra | |
1a6d3da8 | 171 | * check to make sure that the UART address is actually valid. |
6d7d7b3e | 172 | */ |
c5f80065 | 173 | |
6d7d7b3e | 174 | .macro senduart, rd, rx |
1a6d3da8 | 175 | cmp \rx, #0 |
6d7d7b3e SW |
176 | strneb \rd, [\rx, #UART_TX << UART_SHIFT] |
177 | 1001: | |
178 | .endm | |
c5f80065 | 179 | |
6d7d7b3e | 180 | .macro busyuart, rd, rx |
1a6d3da8 | 181 | cmp \rx, #0 |
6d7d7b3e SW |
182 | beq 1002f |
183 | 1001: ldrb \rd, [\rx, #UART_LSR << UART_SHIFT] | |
2f1d70af SW |
184 | and \rd, \rd, #UART_LSR_THRE |
185 | teq \rd, #UART_LSR_THRE | |
6d7d7b3e SW |
186 | bne 1001b |
187 | 1002: | |
188 | .endm | |
c5f80065 | 189 | |
6d7d7b3e SW |
190 | .macro waituart, rd, rx |
191 | #ifdef FLOW_CONTROL | |
1a6d3da8 | 192 | cmp \rx, #0 |
6d7d7b3e SW |
193 | beq 1002f |
194 | 1001: ldrb \rd, [\rx, #UART_MSR << UART_SHIFT] | |
195 | tst \rd, #UART_MSR_CTS | |
196 | beq 1001b | |
197 | 1002: | |
198 | #endif | |
199 | .endm | |
ae3c99a2 SW |
200 | |
201 | /* | |
202 | * Storage for the state maintained by the macros above. | |
203 | * | |
2f1d70af | 204 | * In the kernel proper, this data is located in arch/arm/mach-tegra/tegra.c. |
ae3c99a2 SW |
205 | * That's because this header is included from multiple files, and we only |
206 | * want a single copy of the data. In particular, the UART probing code above | |
207 | * assumes it's running using physical addresses. This is true when this file | |
208 | * is included from head.o, but not when included from debug.o. So we need | |
209 | * to share the probe results between the two copies, rather than having | |
210 | * to re-run the probing again later. | |
211 | * | |
212 | * In the decompressor, we put the symbol/storage right here, since common.c | |
213 | * isn't included in the decompressor build. This symbol gets put in .text | |
214 | * even though it's really data, since .data is discarded from the | |
215 | * decompressor. Luckily, .text is writeable in the decompressor, unless | |
216 | * CONFIG_ZBOOT_ROM. That dependency is handled in arch/arm/Kconfig.debug. | |
217 | */ | |
218 | #if defined(ZIMAGE) | |
219 | tegra_uart_config: | |
220 | /* Debug UART initialization required */ | |
221 | .word 1 | |
222 | /* Debug UART physical address */ | |
223 | .word 0 | |
224 | /* Debug UART virtual address */ | |
225 | .word 0 | |
ae3c99a2 | 226 | #endif |