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