Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * Copyright (C) 2010,2011 Google, Inc.
0004  * Copyright (C) 2011-2012 NVIDIA CORPORATION. All Rights Reserved.
0005  *
0006  * Author:
0007  *  Colin Cross <ccross@google.com>
0008  *  Erik Gilling <konkers@google.com>
0009  *  Doug Anderson <dianders@chromium.org>
0010  *  Stephen Warren <swarren@nvidia.com>
0011  *
0012  * Portions based on mach-omap2's debug-macro.S
0013  * Copyright (C) 1994-1999 Russell King
0014  */
0015 
0016 #include <linux/serial_reg.h>
0017 
0018 #define UART_SHIFT 2
0019 
0020 /* Physical addresses */
0021 #define TEGRA_CLK_RESET_BASE        0x60006000
0022 #define TEGRA_APB_MISC_BASE     0x70000000
0023 #define TEGRA_UARTA_BASE        0x70006000
0024 #define TEGRA_UARTB_BASE        0x70006040
0025 #define TEGRA_UARTC_BASE        0x70006200
0026 #define TEGRA_UARTD_BASE        0x70006300
0027 #define TEGRA_UARTE_BASE        0x70006400
0028 #define TEGRA_PMC_BASE          0x7000e400
0029 
0030 #define TEGRA_CLK_RST_DEVICES_L     (TEGRA_CLK_RESET_BASE + 0x04)
0031 #define TEGRA_CLK_RST_DEVICES_H     (TEGRA_CLK_RESET_BASE + 0x08)
0032 #define TEGRA_CLK_RST_DEVICES_U     (TEGRA_CLK_RESET_BASE + 0x0c)
0033 #define TEGRA_CLK_OUT_ENB_L     (TEGRA_CLK_RESET_BASE + 0x10)
0034 #define TEGRA_CLK_OUT_ENB_H     (TEGRA_CLK_RESET_BASE + 0x14)
0035 #define TEGRA_CLK_OUT_ENB_U     (TEGRA_CLK_RESET_BASE + 0x18)
0036 #define TEGRA_PMC_SCRATCH20     (TEGRA_PMC_BASE + 0xa0)
0037 #define TEGRA_APB_MISC_GP_HIDREV    (TEGRA_APB_MISC_BASE + 0x804)
0038 
0039 /*
0040  * Must be section-aligned since a section mapping is used early on.
0041  * Must not overlap with regions in mach-tegra/io.c:tegra_io_desc[].
0042  */
0043 #define UART_VIRTUAL_BASE       0xfe800000
0044 
0045 #define checkuart(rp, rv, lhu, bit, uart) \
0046         /* Load address of CLK_RST register */ \
0047         ldr rp, =TEGRA_CLK_RST_DEVICES_##lhu ; \
0048         /* Load value from CLK_RST register */ \
0049         ldr rp, [rp, #0] ; \
0050         /* Test UART's reset bit */ \
0051         tst rp, #(1 << bit) ; \
0052         /* If set, can't use UART; jump to save no UART */ \
0053         bne 90f ; \
0054         /* Load address of CLK_OUT_ENB register */ \
0055         ldr rp, =TEGRA_CLK_OUT_ENB_##lhu ; \
0056         /* Load value from CLK_OUT_ENB register */ \
0057         ldr rp, [rp, #0] ; \
0058         /* Test UART's clock enable bit */ \
0059         tst rp, #(1 << bit) ; \
0060         /* If clear, can't use UART; jump to save no UART */ \
0061         beq 90f ; \
0062         /* Passed all tests, load address of UART registers */ \
0063         ldr rp, =TEGRA_UART##uart##_BASE ; \
0064         /* Jump to save UART address */ \
0065         b 91f
0066 
0067         .macro  addruart, rp, rv, tmp
0068         adr \rp, 99f        @ actual addr of 99f
0069         ldr \rv, [\rp]      @ linked addr is stored there
0070         sub \rv, \rv, \rp       @ offset between the two
0071         ldr \rp, [\rp, #4]      @ linked tegra_uart_config
0072         sub \tmp, \rp, \rv      @ actual tegra_uart_config
0073         ldr \rp, [\tmp]     @ Load tegra_uart_config
0074         cmp \rp, #1         @ needs initialization?
0075         bne 100f            @ no; go load the addresses
0076         mov \rv, #0         @ yes; record init is done
0077         str \rv, [\tmp]
0078 
0079 #ifdef CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA
0080         /* Check ODMDATA */
0081 10:     ldr \rp, =TEGRA_PMC_SCRATCH20
0082         ldr \rp, [\rp, #0]      @ Load PMC_SCRATCH20
0083         lsr \rv, \rp, #18       @ 19:18 are console type
0084         and \rv, \rv, #3
0085         cmp \rv, #2         @ 2 and 3 mean DCC, UART
0086         beq 11f         @ some boards swap the meaning
0087         cmp \rv, #3         @ so accept either
0088         bne 90f
0089 11:     lsr \rv, \rp, #15       @ 17:15 are UART ID
0090         and \rv, #7 
0091         cmp \rv, #0         @ UART 0?
0092         beq 20f
0093         cmp \rv, #1         @ UART 1?
0094         beq 21f
0095         cmp \rv, #2         @ UART 2?
0096         beq 22f
0097         cmp \rv, #3         @ UART 3?
0098         beq 23f
0099         cmp \rv, #4         @ UART 4?
0100         beq 24f
0101         b   90f         @ invalid
0102 #endif
0103 
0104 #if defined(CONFIG_TEGRA_DEBUG_UARTA) || \
0105     defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
0106         /* Check UART A validity */
0107 20:     checkuart(\rp, \rv, L, 6, A)
0108 #endif
0109 
0110 #if defined(CONFIG_TEGRA_DEBUG_UARTB) || \
0111     defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
0112         /* Check UART B validity */
0113 21:     checkuart(\rp, \rv, L, 7, B)
0114 #endif
0115 
0116 #if defined(CONFIG_TEGRA_DEBUG_UARTC) || \
0117     defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
0118         /* Check UART C validity */
0119 22:     checkuart(\rp, \rv, H, 23, C)
0120 #endif
0121 
0122 #if defined(CONFIG_TEGRA_DEBUG_UARTD) || \
0123     defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
0124         /* Check UART D validity */
0125 23:     checkuart(\rp, \rv, U, 1, D)
0126 #endif
0127 
0128 #if defined(CONFIG_TEGRA_DEBUG_UARTE) || \
0129     defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
0130         /* Check UART E validity */
0131 24:
0132         checkuart(\rp, \rv, U, 2, E)
0133 #endif
0134 
0135         /* No valid UART found */
0136 90:     mov \rp, #0
0137         /* fall through */
0138 
0139         /* Record whichever UART we chose */
0140 91:     str \rp, [\tmp, #4]     @ Store in tegra_uart_phys
0141         cmp \rp, #0         @ Valid UART address?
0142         bne 92f         @ Yes, go process it
0143         str \rp, [\tmp, #8]     @ Store 0 in tegra_uart_virt
0144         b   100f            @ Done
0145 92:     and \rv, \rp, #0xffffff @ offset within 1MB section
0146         add \rv, \rv, #UART_VIRTUAL_BASE
0147         str \rv, [\tmp, #8]     @ Store in tegra_uart_virt
0148         b   100f
0149 
0150         .align
0151 99:     .word   .
0152 #if defined(ZIMAGE)
0153         .word   . + 4
0154 /*
0155  * Storage for the state maintained by the macro.
0156  *
0157  * In the kernel proper, this data is located in arch/arm/mach-tegra/tegra.c.
0158  * That's because this header is included from multiple files, and we only
0159  * want a single copy of the data. In particular, the UART probing code above
0160  * assumes it's running using physical addresses. This is true when this file
0161  * is included from head.o, but not when included from debug.o. So we need
0162  * to share the probe results between the two copies, rather than having
0163  * to re-run the probing again later.
0164  *
0165  * In the decompressor, we put the storage right here, since common.c
0166  * isn't included in the decompressor build. This storage data gets put in
0167  * .text even though it's really data, since .data is discarded from the
0168  * decompressor. Luckily, .text is writeable in the decompressor, unless
0169  * CONFIG_ZBOOT_ROM. That dependency is handled in arch/arm/Kconfig.debug.
0170  */
0171         /* Debug UART initialization required */
0172         .word   1
0173         /* Debug UART physical address */
0174         .word   0
0175         /* Debug UART virtual address */
0176         .word   0
0177 #else
0178         .word   tegra_uart_config
0179 #endif
0180         .ltorg
0181 
0182         /* Load previously selected UART address */
0183 100:        ldr \rp, [\tmp, #4]     @ Load tegra_uart_phys
0184         ldr \rv, [\tmp, #8]     @ Load tegra_uart_virt
0185         .endm
0186 
0187 /*
0188  * Code below is swiped from <asm/hardware/debug-8250.S>, but add an extra
0189  * check to make sure that the UART address is actually valid.
0190  */
0191 
0192         .macro  senduart, rd, rx
0193         cmp \rx, #0
0194         strbne  \rd, [\rx, #UART_TX << UART_SHIFT]
0195 1001:
0196         .endm
0197 
0198         .macro  busyuart, rd, rx
0199         cmp \rx, #0
0200         beq 1002f
0201 1001:       ldrb    \rd, [\rx, #UART_LSR << UART_SHIFT]
0202         and \rd, \rd, #UART_LSR_THRE
0203         teq \rd, #UART_LSR_THRE
0204         bne 1001b
0205 1002:
0206         .endm
0207 
0208         .macro  waituartcts, rd, rx
0209         cmp \rx, #0
0210         beq 1002f
0211 1001:       ldrb    \rd, [\rx, #UART_MSR << UART_SHIFT]
0212         tst \rd, #UART_MSR_CTS
0213         beq 1001b
0214 1002:
0215         .endm
0216 
0217         .macro  waituarttxrdy,rd,rx
0218         .endm