ARM: 7806/1: allow DEBUG_UNCOMPRESS for Tegra
[firefly-linux-kernel-4.4.55.git] / arch / arm / include / debug / tegra.S
1 /*
2  * Copyright (C) 2010,2011 Google, Inc.
3  * Copyright (C) 2011-2012 NVIDIA CORPORATION. All Rights Reserved.
4  *
5  * Author:
6  *      Colin Cross <ccross@google.com>
7  *      Erik Gilling <konkers@google.com>
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
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
25 #include <linux/serial_reg.h>
26
27 #define UART_SHIFT 2
28
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
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
48 /*
49  * Must be 1MB-aligned since a 1MB mapping is used early on.
50  * Must not overlap with regions in mach-tegra/io.c:tegra_io_desc[].
51  */
52 #define UART_VIRTUAL_BASE               0xfe100000
53
54 #define checkuart(rp, rv, lhu, bit, uart) \
55                 /* Load address of CLK_RST register */ \
56                 movw    rp, #TEGRA_CLK_RST_DEVICES_##lhu & 0xffff ; \
57                 movt    rp, #TEGRA_CLK_RST_DEVICES_##lhu >> 16 ; \
58                 /* Load value from CLK_RST register */ \
59                 ldr     rp, [rp, #0] ; \
60                 /* Test UART's reset bit */ \
61                 tst     rp, #(1 << bit) ; \
62                 /* If set, can't use UART; jump to save no UART */ \
63                 bne     90f ; \
64                 /* Load address of CLK_OUT_ENB register */ \
65                 movw    rp, #TEGRA_CLK_OUT_ENB_##lhu & 0xffff ; \
66                 movt    rp, #TEGRA_CLK_OUT_ENB_##lhu >> 16 ; \
67                 /* Load value from CLK_OUT_ENB register */ \
68                 ldr     rp, [rp, #0] ; \
69                 /* Test UART's clock enable bit */ \
70                 tst     rp, #(1 << bit) ; \
71                 /* If clear, can't use UART; jump to save no UART */ \
72                 beq     90f ; \
73                 /* Passed all tests, load address of UART registers */ \
74                 movw    rp, #TEGRA_UART##uart##_BASE & 0xffff ; \
75                 movt    rp, #TEGRA_UART##uart##_BASE >> 16 ; \
76                 /* Jump to save UART address */ \
77                 b 91f
78
79                 .macro  addruart, rp, rv, tmp
80                 adr     \rp, 99f                @ actual addr of 99f
81                 ldr     \rv, [\rp]              @ linked addr is stored there
82                 sub     \rv, \rv, \rp           @ offset between the two
83                 ldr     \rp, [\rp, #4]          @ linked tegra_uart_config
84                 sub     \tmp, \rp, \rv          @ actual tegra_uart_config
85                 ldr     \rp, [\tmp]             @ Load tegra_uart_config
86                 cmp     \rp, #1                 @ needs initialization?
87                 bne     100f                    @ no; go load the addresses
88                 mov     \rv, #0                 @ yes; record init is done
89                 str     \rv, [\tmp]
90
91 #ifdef CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA
92                 /* Check ODMDATA */
93 10:             movw    \rp, #TEGRA_PMC_SCRATCH20 & 0xffff
94                 movt    \rp, #TEGRA_PMC_SCRATCH20 >> 16
95                 ldr     \rp, [\rp, #0]          @ Load PMC_SCRATCH20
96                 ubfx    \rv, \rp, #18, #2       @ 19:18 are console type
97                 cmp     \rv, #2                 @ 2 and 3 mean DCC, UART
98                 beq     11f                     @ some boards swap the meaning
99                 cmp     \rv, #3                 @ so accept either
100                 bne     90f
101 11:             ubfx    \rv, \rp, #15, #3       @ 17:15 are UART ID
102                 cmp     \rv, #0                 @ UART 0?
103                 beq     20f
104                 cmp     \rv, #1                 @ UART 1?
105                 beq     21f
106                 cmp     \rv, #2                 @ UART 2?
107                 beq     22f
108                 cmp     \rv, #3                 @ UART 3?
109                 beq     23f
110                 cmp     \rv, #4                 @ UART 4?
111                 beq     24f
112                 b       90f                     @ invalid
113 #endif
114
115 #if defined(CONFIG_TEGRA_DEBUG_UARTA) || \
116     defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
117                 /* Check UART A validity */
118 20:             checkuart(\rp, \rv, L, 6, A)
119 #endif
120
121 #if defined(CONFIG_TEGRA_DEBUG_UARTB) || \
122     defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
123                 /* Check UART B validity */
124 21:             checkuart(\rp, \rv, L, 7, B)
125 #endif
126
127 #if defined(CONFIG_TEGRA_DEBUG_UARTC) || \
128     defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
129                 /* Check UART C validity */
130 22:             checkuart(\rp, \rv, H, 23, C)
131 #endif
132
133 #if defined(CONFIG_TEGRA_DEBUG_UARTD) || \
134     defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
135                 /* Check UART D validity */
136 23:             checkuart(\rp, \rv, U, 1, D)
137 #endif
138
139 #if defined(CONFIG_TEGRA_DEBUG_UARTE) || \
140     defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
141                 /* Check UART E validity */
142 24:
143                 checkuart(\rp, \rv, U, 2, E)
144 #endif
145
146                 /* No valid UART found */
147 90:             mov     \rp, #0
148                 /* fall through */
149
150                 /* Record whichever UART we chose */
151 91:             str     \rp, [\tmp, #4]         @ Store in tegra_uart_phys
152                 cmp     \rp, #0                 @ Valid UART address?
153                 bne     92f                     @ Yes, go process it
154                 str     \rp, [\tmp, #8]         @ Store 0 in tegra_uart_virt
155                 b       100f                    @ Done
156 92:             and     \rv, \rp, #0xffffff     @ offset within 1MB section
157                 add     \rv, \rv, #UART_VIRTUAL_BASE
158                 str     \rv, [\tmp, #8]         @ Store in tegra_uart_virt
159                 movw    \rv, #TEGRA_APB_MISC_GP_HIDREV & 0xffff
160                 movt    \rv, #TEGRA_APB_MISC_GP_HIDREV >> 16
161                 ldr     \rv, [\rv, #0]          @ Load HIDREV
162                 ubfx    \rv, \rv, #8, #8        @ 15:8 are SoC version
163                 cmp     \rv, #0x20              @ Tegra20?
164                 moveq   \rv, #0x75              @ Tegra20 divisor
165                 movne   \rv, #0xdd              @ Tegra30 divisor
166                 str     \rv, [\tmp, #12]        @ Save divisor to scratch
167                 /* uart[UART_LCR] = UART_LCR_WLEN8 | UART_LCR_DLAB; */
168                 mov     \rv, #UART_LCR_WLEN8 | UART_LCR_DLAB
169                 str     \rv, [\rp, #UART_LCR << UART_SHIFT]
170                 /* uart[UART_DLL] = div & 0xff; */
171                 ldr     \rv, [\tmp, #12]
172                 and     \rv, \rv, #0xff
173                 str     \rv, [\rp, #UART_DLL << UART_SHIFT]
174                 /* uart[UART_DLM] = div >> 8; */
175                 ldr     \rv, [\tmp, #12]
176                 lsr     \rv, \rv, #8
177                 str     \rv, [\rp, #UART_DLM << UART_SHIFT]
178                 /* uart[UART_LCR] = UART_LCR_WLEN8; */
179                 mov     \rv, #UART_LCR_WLEN8
180                 str     \rv, [\rp, #UART_LCR << UART_SHIFT]
181                 b       100f
182
183                 .align
184 99:             .word   .
185                 .word   tegra_uart_config
186                 .ltorg
187
188                 /* Load previously selected UART address */
189 100:            ldr     \rp, [\tmp, #4]         @ Load tegra_uart_phys
190                 ldr     \rv, [\tmp, #8]         @ Load tegra_uart_virt
191                 .endm
192
193 /*
194  * Code below is swiped from <asm/hardware/debug-8250.S>, but add an extra
195  * check to make sure that the UART address is actually valid.
196  */
197
198                 .macro  senduart, rd, rx
199                 cmp     \rx, #0
200                 strneb  \rd, [\rx, #UART_TX << UART_SHIFT]
201 1001:
202                 .endm
203
204                 .macro  busyuart, rd, rx
205                 cmp     \rx, #0
206                 beq     1002f
207 1001:           ldrb    \rd, [\rx, #UART_LSR << UART_SHIFT]
208                 and     \rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE
209                 teq     \rd, #UART_LSR_TEMT | UART_LSR_THRE
210                 bne     1001b
211 1002:
212                 .endm
213
214                 .macro  waituart, rd, rx
215 #ifdef FLOW_CONTROL
216                 cmp     \rx, #0
217                 beq     1002f
218 1001:           ldrb    \rd, [\rx, #UART_MSR << UART_SHIFT]
219                 tst     \rd, #UART_MSR_CTS
220                 beq     1001b
221 1002:
222 #endif
223                 .endm
224
225 /*
226  * Storage for the state maintained by the macros above.
227  *
228  * In the kernel proper, this data is located in arch/arm/mach-tegra/common.c.
229  * That's because this header is included from multiple files, and we only
230  * want a single copy of the data. In particular, the UART probing code above
231  * assumes it's running using physical addresses. This is true when this file
232  * is included from head.o, but not when included from debug.o. So we need
233  * to share the probe results between the two copies, rather than having
234  * to re-run the probing again later.
235  *
236  * In the decompressor, we put the symbol/storage right here, since common.c
237  * isn't included in the decompressor build. This symbol gets put in .text
238  * even though it's really data, since .data is discarded from the
239  * decompressor. Luckily, .text is writeable in the decompressor, unless
240  * CONFIG_ZBOOT_ROM. That dependency is handled in arch/arm/Kconfig.debug.
241  */
242 #if defined(ZIMAGE)
243 tegra_uart_config:
244         /* Debug UART initialization required */
245         .word 1
246         /* Debug UART physical address */
247         .word 0
248         /* Debug UART virtual address */
249         .word 0
250         /* Scratch space for debug macro */
251         .word 0
252 #endif