xref: /linux/arch/arm/include/debug/tegra.S (revision bb9707077b4ee5f77bc9939b057ff8a0d410296f)
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		ldr	rp, =TEGRA_CLK_RST_DEVICES_##lhu ; \
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 */ \
64		ldr	rp, =TEGRA_CLK_OUT_ENB_##lhu ; \
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 */ \
72		ldr	rp, =TEGRA_UART##uart##_BASE ; \
73		/* Jump to save UART address */ \
74		b 91f
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
83		cmp	\rp, #1			@ needs initialization?
84		bne	100f			@ no; go load the addresses
85		mov	\rv, #0			@ yes; record init is done
86		str	\rv, [\tmp]
87
88#ifdef CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA
89		/* Check ODMDATA */
9010:		ldr	\rp, =TEGRA_PMC_SCRATCH20
91		ldr	\rp, [\rp, #0]		@ Load PMC_SCRATCH20
92		lsr	\rv, \rp, #18		@ 19:18 are console type
93		and	\rv, \rv, #3
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
9811:		lsr	\rv, \rp, #15		@ 17:15 are UART ID
99		and	\rv, #7
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 */
11620:		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 */
12221:		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 */
12822:		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 */
13423:		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 */
14024:
141		checkuart(\rp, \rv, U, 2, E)
142#endif
143
144		/* No valid UART found */
14590:		mov	\rp, #0
146		/* fall through */
147
148		/* Record whichever UART we chose */
14991:		str	\rp, [\tmp, #4]		@ Store in tegra_uart_phys
150		cmp	\rp, #0			@ Valid UART address?
151		bne	92f			@ Yes, go process it
152		str	\rp, [\tmp, #8]		@ Store 0 in tegra_uart_virt
153		b	100f			@ Done
15492:		and	\rv, \rp, #0xffffff	@ offset within 1MB section
155		add	\rv, \rv, #UART_VIRTUAL_BASE
156		str	\rv, [\tmp, #8]		@ Store in tegra_uart_virt
157		b	100f
158
159		.align
16099:		.word	.
161		.word	tegra_uart_config
162		.ltorg
163
164		/* Load previously selected UART address */
165100:		ldr	\rp, [\tmp, #4]		@ Load tegra_uart_phys
166		ldr	\rv, [\tmp, #8]		@ Load tegra_uart_virt
167		.endm
168
169/*
170 * Code below is swiped from <asm/hardware/debug-8250.S>, but add an extra
171 * check to make sure that the UART address is actually valid.
172 */
173
174		.macro	senduart, rd, rx
175		cmp	\rx, #0
176		strneb	\rd, [\rx, #UART_TX << UART_SHIFT]
1771001:
178		.endm
179
180		.macro	busyuart, rd, rx
181		cmp	\rx, #0
182		beq	1002f
1831001:		ldrb	\rd, [\rx, #UART_LSR << UART_SHIFT]
184		and	\rd, \rd, #UART_LSR_THRE
185		teq	\rd, #UART_LSR_THRE
186		bne	1001b
1871002:
188		.endm
189
190		.macro	waituart, rd, rx
191#ifdef FLOW_CONTROL
192		cmp	\rx, #0
193		beq	1002f
1941001:		ldrb	\rd, [\rx, #UART_MSR << UART_SHIFT]
195		tst	\rd, #UART_MSR_CTS
196		beq	1001b
1971002:
198#endif
199		.endm
200
201/*
202 * Storage for the state maintained by the macros above.
203 *
204 * In the kernel proper, this data is located in arch/arm/mach-tegra/tegra.c.
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)
219tegra_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
226#endif
227