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