Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[linux.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 section-aligned since a section 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               0xfe800000
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                 b       100f
160
161                 .align
162 99:             .word   .
163                 .word   tegra_uart_config
164                 .ltorg
165
166                 /* Load previously selected UART address */
167 100:            ldr     \rp, [\tmp, #4]         @ Load tegra_uart_phys
168                 ldr     \rv, [\tmp, #8]         @ Load tegra_uart_virt
169                 .endm
170
171 /*
172  * Code below is swiped from <asm/hardware/debug-8250.S>, but add an extra
173  * check to make sure that the UART address is actually valid.
174  */
175
176                 .macro  senduart, rd, rx
177                 cmp     \rx, #0
178                 strneb  \rd, [\rx, #UART_TX << UART_SHIFT]
179 1001:
180                 .endm
181
182                 .macro  busyuart, rd, rx
183                 cmp     \rx, #0
184                 beq     1002f
185 1001:           ldrb    \rd, [\rx, #UART_LSR << UART_SHIFT]
186                 and     \rd, \rd, #UART_LSR_THRE
187                 teq     \rd, #UART_LSR_THRE
188                 bne     1001b
189 1002:
190                 .endm
191
192                 .macro  waituart, rd, rx
193 #ifdef FLOW_CONTROL
194                 cmp     \rx, #0
195                 beq     1002f
196 1001:           ldrb    \rd, [\rx, #UART_MSR << UART_SHIFT]
197                 tst     \rd, #UART_MSR_CTS
198                 beq     1001b
199 1002:
200 #endif
201                 .endm
202
203 /*
204  * Storage for the state maintained by the macros above.
205  *
206  * In the kernel proper, this data is located in arch/arm/mach-tegra/tegra.c.
207  * That's because this header is included from multiple files, and we only
208  * want a single copy of the data. In particular, the UART probing code above
209  * assumes it's running using physical addresses. This is true when this file
210  * is included from head.o, but not when included from debug.o. So we need
211  * to share the probe results between the two copies, rather than having
212  * to re-run the probing again later.
213  *
214  * In the decompressor, we put the symbol/storage right here, since common.c
215  * isn't included in the decompressor build. This symbol gets put in .text
216  * even though it's really data, since .data is discarded from the
217  * decompressor. Luckily, .text is writeable in the decompressor, unless
218  * CONFIG_ZBOOT_ROM. That dependency is handled in arch/arm/Kconfig.debug.
219  */
220 #if defined(ZIMAGE)
221 tegra_uart_config:
222         /* Debug UART initialization required */
223         .word 1
224         /* Debug UART physical address */
225         .word 0
226         /* Debug UART virtual address */
227         .word 0
228 #endif