root/arch/arm/include/debug/tegra.S

/* [<][>][^][v][top][bottom][index][help] */
   1 /* SPDX-License-Identifier: GPL-2.0-only */
   2 /*
   3  * Copyright (C) 2010,2011 Google, Inc.
   4  * Copyright (C) 2011-2012 NVIDIA CORPORATION. All Rights Reserved.
   5  *
   6  * Author:
   7  *      Colin Cross <ccross@google.com>
   8  *      Erik Gilling <konkers@google.com>
   9  *      Doug Anderson <dianders@chromium.org>
  10  *      Stephen Warren <swarren@nvidia.com>
  11  *
  12  * Portions based on mach-omap2's debug-macro.S
  13  * Copyright (C) 1994-1999 Russell King
  14  */
  15 
  16 #include <linux/serial_reg.h>
  17 
  18 #define UART_SHIFT 2
  19 
  20 /* Physical addresses */
  21 #define TEGRA_CLK_RESET_BASE            0x60006000
  22 #define TEGRA_APB_MISC_BASE             0x70000000
  23 #define TEGRA_UARTA_BASE                0x70006000
  24 #define TEGRA_UARTB_BASE                0x70006040
  25 #define TEGRA_UARTC_BASE                0x70006200
  26 #define TEGRA_UARTD_BASE                0x70006300
  27 #define TEGRA_UARTE_BASE                0x70006400
  28 #define TEGRA_PMC_BASE                  0x7000e400
  29 
  30 #define TEGRA_CLK_RST_DEVICES_L         (TEGRA_CLK_RESET_BASE + 0x04)
  31 #define TEGRA_CLK_RST_DEVICES_H         (TEGRA_CLK_RESET_BASE + 0x08)
  32 #define TEGRA_CLK_RST_DEVICES_U         (TEGRA_CLK_RESET_BASE + 0x0c)
  33 #define TEGRA_CLK_OUT_ENB_L             (TEGRA_CLK_RESET_BASE + 0x10)
  34 #define TEGRA_CLK_OUT_ENB_H             (TEGRA_CLK_RESET_BASE + 0x14)
  35 #define TEGRA_CLK_OUT_ENB_U             (TEGRA_CLK_RESET_BASE + 0x18)
  36 #define TEGRA_PMC_SCRATCH20             (TEGRA_PMC_BASE + 0xa0)
  37 #define TEGRA_APB_MISC_GP_HIDREV        (TEGRA_APB_MISC_BASE + 0x804)
  38 
  39 /*
  40  * Must be section-aligned since a section mapping is used early on.
  41  * Must not overlap with regions in mach-tegra/io.c:tegra_io_desc[].
  42  */
  43 #define UART_VIRTUAL_BASE               0xfe800000
  44 
  45 #define checkuart(rp, rv, lhu, bit, uart) \
  46                 /* Load address of CLK_RST register */ \
  47                 ldr     rp, =TEGRA_CLK_RST_DEVICES_##lhu ; \
  48                 /* Load value from CLK_RST register */ \
  49                 ldr     rp, [rp, #0] ; \
  50                 /* Test UART's reset bit */ \
  51                 tst     rp, #(1 << bit) ; \
  52                 /* If set, can't use UART; jump to save no UART */ \
  53                 bne     90f ; \
  54                 /* Load address of CLK_OUT_ENB register */ \
  55                 ldr     rp, =TEGRA_CLK_OUT_ENB_##lhu ; \
  56                 /* Load value from CLK_OUT_ENB register */ \
  57                 ldr     rp, [rp, #0] ; \
  58                 /* Test UART's clock enable bit */ \
  59                 tst     rp, #(1 << bit) ; \
  60                 /* If clear, can't use UART; jump to save no UART */ \
  61                 beq     90f ; \
  62                 /* Passed all tests, load address of UART registers */ \
  63                 ldr     rp, =TEGRA_UART##uart##_BASE ; \
  64                 /* Jump to save UART address */ \
  65                 b 91f
  66 
  67                 .macro  addruart, rp, rv, tmp
  68                 adr     \rp, 99f                @ actual addr of 99f
  69                 ldr     \rv, [\rp]              @ linked addr is stored there
  70                 sub     \rv, \rv, \rp           @ offset between the two
  71                 ldr     \rp, [\rp, #4]          @ linked tegra_uart_config
  72                 sub     \tmp, \rp, \rv          @ actual tegra_uart_config
  73                 ldr     \rp, [\tmp]             @ Load tegra_uart_config
  74                 cmp     \rp, #1                 @ needs initialization?
  75                 bne     100f                    @ no; go load the addresses
  76                 mov     \rv, #0                 @ yes; record init is done
  77                 str     \rv, [\tmp]
  78 
  79 #ifdef CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA
  80                 /* Check ODMDATA */
  81 10:             ldr     \rp, =TEGRA_PMC_SCRATCH20
  82                 ldr     \rp, [\rp, #0]          @ Load PMC_SCRATCH20
  83                 lsr     \rv, \rp, #18           @ 19:18 are console type
  84                 and     \rv, \rv, #3
  85                 cmp     \rv, #2                 @ 2 and 3 mean DCC, UART
  86                 beq     11f                     @ some boards swap the meaning
  87                 cmp     \rv, #3                 @ so accept either
  88                 bne     90f
  89 11:             lsr     \rv, \rp, #15           @ 17:15 are UART ID
  90                 and     \rv, #7 
  91                 cmp     \rv, #0                 @ UART 0?
  92                 beq     20f
  93                 cmp     \rv, #1                 @ UART 1?
  94                 beq     21f
  95                 cmp     \rv, #2                 @ UART 2?
  96                 beq     22f
  97                 cmp     \rv, #3                 @ UART 3?
  98                 beq     23f
  99                 cmp     \rv, #4                 @ UART 4?
 100                 beq     24f
 101                 b       90f                     @ invalid
 102 #endif
 103 
 104 #if defined(CONFIG_TEGRA_DEBUG_UARTA) || \
 105     defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
 106                 /* Check UART A validity */
 107 20:             checkuart(\rp, \rv, L, 6, A)
 108 #endif
 109 
 110 #if defined(CONFIG_TEGRA_DEBUG_UARTB) || \
 111     defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
 112                 /* Check UART B validity */
 113 21:             checkuart(\rp, \rv, L, 7, B)
 114 #endif
 115 
 116 #if defined(CONFIG_TEGRA_DEBUG_UARTC) || \
 117     defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
 118                 /* Check UART C validity */
 119 22:             checkuart(\rp, \rv, H, 23, C)
 120 #endif
 121 
 122 #if defined(CONFIG_TEGRA_DEBUG_UARTD) || \
 123     defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
 124                 /* Check UART D validity */
 125 23:             checkuart(\rp, \rv, U, 1, D)
 126 #endif
 127 
 128 #if defined(CONFIG_TEGRA_DEBUG_UARTE) || \
 129     defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
 130                 /* Check UART E validity */
 131 24:
 132                 checkuart(\rp, \rv, U, 2, E)
 133 #endif
 134 
 135                 /* No valid UART found */
 136 90:             mov     \rp, #0
 137                 /* fall through */
 138 
 139                 /* Record whichever UART we chose */
 140 91:             str     \rp, [\tmp, #4]         @ Store in tegra_uart_phys
 141                 cmp     \rp, #0                 @ Valid UART address?
 142                 bne     92f                     @ Yes, go process it
 143                 str     \rp, [\tmp, #8]         @ Store 0 in tegra_uart_virt
 144                 b       100f                    @ Done
 145 92:             and     \rv, \rp, #0xffffff     @ offset within 1MB section
 146                 add     \rv, \rv, #UART_VIRTUAL_BASE
 147                 str     \rv, [\tmp, #8]         @ Store in tegra_uart_virt
 148                 b       100f
 149 
 150                 .align
 151 99:             .word   .
 152                 .word   tegra_uart_config
 153                 .ltorg
 154 
 155                 /* Load previously selected UART address */
 156 100:            ldr     \rp, [\tmp, #4]         @ Load tegra_uart_phys
 157                 ldr     \rv, [\tmp, #8]         @ Load tegra_uart_virt
 158                 .endm
 159 
 160 /*
 161  * Code below is swiped from <asm/hardware/debug-8250.S>, but add an extra
 162  * check to make sure that the UART address is actually valid.
 163  */
 164 
 165                 .macro  senduart, rd, rx
 166                 cmp     \rx, #0
 167                 strbne  \rd, [\rx, #UART_TX << UART_SHIFT]
 168 1001:
 169                 .endm
 170 
 171                 .macro  busyuart, rd, rx
 172                 cmp     \rx, #0
 173                 beq     1002f
 174 1001:           ldrb    \rd, [\rx, #UART_LSR << UART_SHIFT]
 175                 and     \rd, \rd, #UART_LSR_THRE
 176                 teq     \rd, #UART_LSR_THRE
 177                 bne     1001b
 178 1002:
 179                 .endm
 180 
 181                 .macro  waituart, rd, rx
 182 #ifdef FLOW_CONTROL
 183                 cmp     \rx, #0
 184                 beq     1002f
 185 1001:           ldrb    \rd, [\rx, #UART_MSR << UART_SHIFT]
 186                 tst     \rd, #UART_MSR_CTS
 187                 beq     1001b
 188 1002:
 189 #endif
 190                 .endm
 191 
 192 /*
 193  * Storage for the state maintained by the macros above.
 194  *
 195  * In the kernel proper, this data is located in arch/arm/mach-tegra/tegra.c.
 196  * That's because this header is included from multiple files, and we only
 197  * want a single copy of the data. In particular, the UART probing code above
 198  * assumes it's running using physical addresses. This is true when this file
 199  * is included from head.o, but not when included from debug.o. So we need
 200  * to share the probe results between the two copies, rather than having
 201  * to re-run the probing again later.
 202  *
 203  * In the decompressor, we put the symbol/storage right here, since common.c
 204  * isn't included in the decompressor build. This symbol gets put in .text
 205  * even though it's really data, since .data is discarded from the
 206  * decompressor. Luckily, .text is writeable in the decompressor, unless
 207  * CONFIG_ZBOOT_ROM. That dependency is handled in arch/arm/Kconfig.debug.
 208  */
 209 #if defined(ZIMAGE)
 210 tegra_uart_config:
 211         /* Debug UART initialization required */
 212         .word 1
 213         /* Debug UART physical address */
 214         .word 0
 215         /* Debug UART virtual address */
 216         .word 0
 217 #endif

/* [<][>][^][v][top][bottom][index][help] */