xref: /openbmc/linux/arch/arm/include/debug/tegra.S (revision b7f8f259896f669f131713b0c74ba4d008daa71d)
19c92ab61SThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-only */
246067803SStephen Warren/*
346067803SStephen Warren * Copyright (C) 2010,2011 Google, Inc.
446067803SStephen Warren * Copyright (C) 2011-2012 NVIDIA CORPORATION. All Rights Reserved.
546067803SStephen Warren *
646067803SStephen Warren * Author:
746067803SStephen Warren *	Colin Cross <ccross@google.com>
846067803SStephen Warren *	Erik Gilling <konkers@google.com>
946067803SStephen Warren *	Doug Anderson <dianders@chromium.org>
1046067803SStephen Warren *	Stephen Warren <swarren@nvidia.com>
1146067803SStephen Warren *
1246067803SStephen Warren * Portions based on mach-omap2's debug-macro.S
1346067803SStephen Warren * Copyright (C) 1994-1999 Russell King
1446067803SStephen Warren */
1546067803SStephen Warren
1646067803SStephen Warren#include <linux/serial_reg.h>
1746067803SStephen Warren
1846067803SStephen Warren#define UART_SHIFT 2
1946067803SStephen Warren
2046067803SStephen Warren/* Physical addresses */
2146067803SStephen Warren#define TEGRA_CLK_RESET_BASE		0x60006000
2246067803SStephen Warren#define TEGRA_APB_MISC_BASE		0x70000000
2346067803SStephen Warren#define TEGRA_UARTA_BASE		0x70006000
2446067803SStephen Warren#define TEGRA_UARTB_BASE		0x70006040
2546067803SStephen Warren#define TEGRA_UARTC_BASE		0x70006200
2646067803SStephen Warren#define TEGRA_UARTD_BASE		0x70006300
2746067803SStephen Warren#define TEGRA_UARTE_BASE		0x70006400
2846067803SStephen Warren#define TEGRA_PMC_BASE			0x7000e400
2946067803SStephen Warren
3046067803SStephen Warren#define TEGRA_CLK_RST_DEVICES_L		(TEGRA_CLK_RESET_BASE + 0x04)
3146067803SStephen Warren#define TEGRA_CLK_RST_DEVICES_H		(TEGRA_CLK_RESET_BASE + 0x08)
3246067803SStephen Warren#define TEGRA_CLK_RST_DEVICES_U		(TEGRA_CLK_RESET_BASE + 0x0c)
3346067803SStephen Warren#define TEGRA_CLK_OUT_ENB_L		(TEGRA_CLK_RESET_BASE + 0x10)
3446067803SStephen Warren#define TEGRA_CLK_OUT_ENB_H		(TEGRA_CLK_RESET_BASE + 0x14)
3546067803SStephen Warren#define TEGRA_CLK_OUT_ENB_U		(TEGRA_CLK_RESET_BASE + 0x18)
3646067803SStephen Warren#define TEGRA_PMC_SCRATCH20		(TEGRA_PMC_BASE + 0xa0)
3746067803SStephen Warren#define TEGRA_APB_MISC_GP_HIDREV	(TEGRA_APB_MISC_BASE + 0x804)
3846067803SStephen Warren
3946067803SStephen Warren/*
40354935a9SStephen Warren * Must be section-aligned since a section mapping is used early on.
4146067803SStephen Warren * Must not overlap with regions in mach-tegra/io.c:tegra_io_desc[].
4246067803SStephen Warren */
43354935a9SStephen Warren#define UART_VIRTUAL_BASE		0xfe800000
4446067803SStephen Warren
4546067803SStephen Warren#define checkuart(rp, rv, lhu, bit, uart) \
4646067803SStephen Warren		/* Load address of CLK_RST register */ \
479f3ba456SArnd Bergmann		ldr	rp, =TEGRA_CLK_RST_DEVICES_##lhu ; \
4846067803SStephen Warren		/* Load value from CLK_RST register */ \
4946067803SStephen Warren		ldr	rp, [rp, #0] ; \
5046067803SStephen Warren		/* Test UART's reset bit */ \
5146067803SStephen Warren		tst	rp, #(1 << bit) ; \
5246067803SStephen Warren		/* If set, can't use UART; jump to save no UART */ \
5346067803SStephen Warren		bne	90f ; \
5446067803SStephen Warren		/* Load address of CLK_OUT_ENB register */ \
559f3ba456SArnd Bergmann		ldr	rp, =TEGRA_CLK_OUT_ENB_##lhu ; \
5646067803SStephen Warren		/* Load value from CLK_OUT_ENB register */ \
5746067803SStephen Warren		ldr	rp, [rp, #0] ; \
5846067803SStephen Warren		/* Test UART's clock enable bit */ \
5946067803SStephen Warren		tst	rp, #(1 << bit) ; \
6046067803SStephen Warren		/* If clear, can't use UART; jump to save no UART */ \
6146067803SStephen Warren		beq	90f ; \
6246067803SStephen Warren		/* Passed all tests, load address of UART registers */ \
639f3ba456SArnd Bergmann		ldr	rp, =TEGRA_UART##uart##_BASE ; \
6446067803SStephen Warren		/* Jump to save UART address */ \
6546067803SStephen Warren		b 91f
6646067803SStephen Warren
6746067803SStephen Warren		.macro  addruart, rp, rv, tmp
6846067803SStephen Warren		adr	\rp, 99f		@ actual addr of 99f
6946067803SStephen Warren		ldr	\rv, [\rp]		@ linked addr is stored there
7046067803SStephen Warren		sub	\rv, \rv, \rp		@ offset between the two
7146067803SStephen Warren		ldr	\rp, [\rp, #4]		@ linked tegra_uart_config
7246067803SStephen Warren		sub	\tmp, \rp, \rv		@ actual tegra_uart_config
7346067803SStephen Warren		ldr	\rp, [\tmp]		@ Load tegra_uart_config
7446067803SStephen Warren		cmp	\rp, #1			@ needs initialization?
7546067803SStephen Warren		bne	100f			@ no; go load the addresses
7646067803SStephen Warren		mov	\rv, #0			@ yes; record init is done
7746067803SStephen Warren		str	\rv, [\tmp]
7846067803SStephen Warren
7946067803SStephen Warren#ifdef CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA
8046067803SStephen Warren		/* Check ODMDATA */
819f3ba456SArnd Bergmann10:		ldr	\rp, =TEGRA_PMC_SCRATCH20
8246067803SStephen Warren		ldr	\rp, [\rp, #0]		@ Load PMC_SCRATCH20
839f3ba456SArnd Bergmann		lsr	\rv, \rp, #18		@ 19:18 are console type
849f3ba456SArnd Bergmann		and	\rv, \rv, #3
8546067803SStephen Warren		cmp	\rv, #2			@ 2 and 3 mean DCC, UART
8646067803SStephen Warren		beq	11f			@ some boards swap the meaning
8746067803SStephen Warren		cmp	\rv, #3			@ so accept either
8846067803SStephen Warren		bne	90f
899f3ba456SArnd Bergmann11:		lsr	\rv, \rp, #15		@ 17:15 are UART ID
909f3ba456SArnd Bergmann		and	\rv, #7
9146067803SStephen Warren		cmp	\rv, #0			@ UART 0?
9246067803SStephen Warren		beq	20f
9346067803SStephen Warren		cmp	\rv, #1			@ UART 1?
9446067803SStephen Warren		beq	21f
9546067803SStephen Warren		cmp	\rv, #2			@ UART 2?
9646067803SStephen Warren		beq	22f
9746067803SStephen Warren		cmp	\rv, #3			@ UART 3?
9846067803SStephen Warren		beq	23f
9946067803SStephen Warren		cmp	\rv, #4			@ UART 4?
10046067803SStephen Warren		beq	24f
10146067803SStephen Warren		b	90f			@ invalid
10246067803SStephen Warren#endif
10346067803SStephen Warren
10446067803SStephen Warren#if defined(CONFIG_TEGRA_DEBUG_UARTA) || \
10546067803SStephen Warren    defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
10646067803SStephen Warren		/* Check UART A validity */
10746067803SStephen Warren20:		checkuart(\rp, \rv, L, 6, A)
10846067803SStephen Warren#endif
10946067803SStephen Warren
11046067803SStephen Warren#if defined(CONFIG_TEGRA_DEBUG_UARTB) || \
11146067803SStephen Warren    defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
11246067803SStephen Warren		/* Check UART B validity */
11346067803SStephen Warren21:		checkuart(\rp, \rv, L, 7, B)
11446067803SStephen Warren#endif
11546067803SStephen Warren
11646067803SStephen Warren#if defined(CONFIG_TEGRA_DEBUG_UARTC) || \
11746067803SStephen Warren    defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
11846067803SStephen Warren		/* Check UART C validity */
11946067803SStephen Warren22:		checkuart(\rp, \rv, H, 23, C)
12046067803SStephen Warren#endif
12146067803SStephen Warren
12246067803SStephen Warren#if defined(CONFIG_TEGRA_DEBUG_UARTD) || \
12346067803SStephen Warren    defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
12446067803SStephen Warren		/* Check UART D validity */
12546067803SStephen Warren23:		checkuart(\rp, \rv, U, 1, D)
12646067803SStephen Warren#endif
12746067803SStephen Warren
12846067803SStephen Warren#if defined(CONFIG_TEGRA_DEBUG_UARTE) || \
12946067803SStephen Warren    defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
13046067803SStephen Warren		/* Check UART E validity */
13146067803SStephen Warren24:
13246067803SStephen Warren		checkuart(\rp, \rv, U, 2, E)
13346067803SStephen Warren#endif
13446067803SStephen Warren
13546067803SStephen Warren		/* No valid UART found */
13646067803SStephen Warren90:		mov	\rp, #0
13746067803SStephen Warren		/* fall through */
13846067803SStephen Warren
13946067803SStephen Warren		/* Record whichever UART we chose */
14046067803SStephen Warren91:		str	\rp, [\tmp, #4]		@ Store in tegra_uart_phys
14146067803SStephen Warren		cmp	\rp, #0			@ Valid UART address?
14246067803SStephen Warren		bne	92f			@ Yes, go process it
14346067803SStephen Warren		str	\rp, [\tmp, #8]		@ Store 0 in tegra_uart_virt
14446067803SStephen Warren		b	100f			@ Done
14546067803SStephen Warren92:		and	\rv, \rp, #0xffffff	@ offset within 1MB section
14646067803SStephen Warren		add	\rv, \rv, #UART_VIRTUAL_BASE
14746067803SStephen Warren		str	\rv, [\tmp, #8]		@ Store in tegra_uart_virt
14846067803SStephen Warren		b	100f
14946067803SStephen Warren
15046067803SStephen Warren		.align
15146067803SStephen Warren99:		.word	.
152*538eea53SDmitry Osipenko#if defined(ZIMAGE)
153*538eea53SDmitry Osipenko		.word	. + 4
154*538eea53SDmitry Osipenko/*
155*538eea53SDmitry Osipenko * Storage for the state maintained by the macro.
156*538eea53SDmitry Osipenko *
157*538eea53SDmitry Osipenko * In the kernel proper, this data is located in arch/arm/mach-tegra/tegra.c.
158*538eea53SDmitry Osipenko * That's because this header is included from multiple files, and we only
159*538eea53SDmitry Osipenko * want a single copy of the data. In particular, the UART probing code above
160*538eea53SDmitry Osipenko * assumes it's running using physical addresses. This is true when this file
161*538eea53SDmitry Osipenko * is included from head.o, but not when included from debug.o. So we need
162*538eea53SDmitry Osipenko * to share the probe results between the two copies, rather than having
163*538eea53SDmitry Osipenko * to re-run the probing again later.
164*538eea53SDmitry Osipenko *
165*538eea53SDmitry Osipenko * In the decompressor, we put the storage right here, since common.c
166*538eea53SDmitry Osipenko * isn't included in the decompressor build. This storage data gets put in
167*538eea53SDmitry Osipenko * .text even though it's really data, since .data is discarded from the
168*538eea53SDmitry Osipenko * decompressor. Luckily, .text is writeable in the decompressor, unless
169*538eea53SDmitry Osipenko * CONFIG_ZBOOT_ROM. That dependency is handled in arch/arm/Kconfig.debug.
170*538eea53SDmitry Osipenko */
171*538eea53SDmitry Osipenko		/* Debug UART initialization required */
172*538eea53SDmitry Osipenko		.word	1
173*538eea53SDmitry Osipenko		/* Debug UART physical address */
174*538eea53SDmitry Osipenko		.word	0
175*538eea53SDmitry Osipenko		/* Debug UART virtual address */
176*538eea53SDmitry Osipenko		.word	0
177*538eea53SDmitry Osipenko#else
17846067803SStephen Warren		.word	tegra_uart_config
179*538eea53SDmitry Osipenko#endif
18046067803SStephen Warren		.ltorg
18146067803SStephen Warren
18246067803SStephen Warren		/* Load previously selected UART address */
18346067803SStephen Warren100:		ldr	\rp, [\tmp, #4]		@ Load tegra_uart_phys
18446067803SStephen Warren		ldr	\rv, [\tmp, #8]		@ Load tegra_uart_virt
18546067803SStephen Warren		.endm
18646067803SStephen Warren
18746067803SStephen Warren/*
18846067803SStephen Warren * Code below is swiped from <asm/hardware/debug-8250.S>, but add an extra
18946067803SStephen Warren * check to make sure that the UART address is actually valid.
19046067803SStephen Warren */
19146067803SStephen Warren
19246067803SStephen Warren		.macro	senduart, rd, rx
19346067803SStephen Warren		cmp	\rx, #0
194e44fc388SStefan Agner		strbne	\rd, [\rx, #UART_TX << UART_SHIFT]
19546067803SStephen Warren1001:
19646067803SStephen Warren		.endm
19746067803SStephen Warren
19846067803SStephen Warren		.macro	busyuart, rd, rx
19946067803SStephen Warren		cmp	\rx, #0
20046067803SStephen Warren		beq	1002f
20146067803SStephen Warren1001:		ldrb	\rd, [\rx, #UART_LSR << UART_SHIFT]
2022f1d70afSStephen Warren		and	\rd, \rd, #UART_LSR_THRE
2032f1d70afSStephen Warren		teq	\rd, #UART_LSR_THRE
20446067803SStephen Warren		bne	1001b
20546067803SStephen Warren1002:
20646067803SStephen Warren		.endm
20746067803SStephen Warren
2082c50a570SLinus Walleij		.macro	waituartcts, rd, rx
20946067803SStephen Warren		cmp	\rx, #0
21046067803SStephen Warren		beq	1002f
21146067803SStephen Warren1001:		ldrb	\rd, [\rx, #UART_MSR << UART_SHIFT]
21246067803SStephen Warren		tst	\rd, #UART_MSR_CTS
21346067803SStephen Warren		beq	1001b
21446067803SStephen Warren1002:
21546067803SStephen Warren		.endm
216ae3c99a2SStephen Warren
2172c50a570SLinus Walleij		.macro	waituarttxrdy,rd,rx
2182c50a570SLinus Walleij		.endm
219