diff options
Diffstat (limited to 'arch/arm/mach-tegra/include/mach/debug-macro.S')
-rw-r--r-- | arch/arm/mach-tegra/include/mach/debug-macro.S | 151 |
1 files changed, 131 insertions, 20 deletions
diff --git a/arch/arm/mach-tegra/include/mach/debug-macro.S b/arch/arm/mach-tegra/include/mach/debug-macro.S index 44ca7b1d8b8a..d4c23d60d448 100644 --- a/arch/arm/mach-tegra/include/mach/debug-macro.S +++ b/arch/arm/mach-tegra/include/mach/debug-macro.S | |||
@@ -27,7 +27,42 @@ | |||
27 | #include <linux/serial_reg.h> | 27 | #include <linux/serial_reg.h> |
28 | 28 | ||
29 | #include "../../iomap.h" | 29 | #include "../../iomap.h" |
30 | #include "../../irammap.h" | 30 | |
31 | #define UART_SHIFT 2 | ||
32 | |||
33 | #define TEGRA_CLK_RST_DEVICES_L (TEGRA_CLK_RESET_BASE + 0x04) | ||
34 | #define TEGRA_CLK_RST_DEVICES_H (TEGRA_CLK_RESET_BASE + 0x08) | ||
35 | #define TEGRA_CLK_RST_DEVICES_U (TEGRA_CLK_RESET_BASE + 0x0c) | ||
36 | #define TEGRA_CLK_OUT_ENB_L (TEGRA_CLK_RESET_BASE + 0x10) | ||
37 | #define TEGRA_CLK_OUT_ENB_H (TEGRA_CLK_RESET_BASE + 0x14) | ||
38 | #define TEGRA_CLK_OUT_ENB_U (TEGRA_CLK_RESET_BASE + 0x18) | ||
39 | #define TEGRA_PMC_SCRATCH20 (TEGRA_PMC_BASE + 0xa0) | ||
40 | #define TEGRA_APB_MISC_GP_HIDREV (TEGRA_APB_MISC_BASE + 0x804) | ||
41 | |||
42 | #define checkuart(rp, rv, lhu, bit, uart) \ | ||
43 | /* Load address of CLK_RST register */ \ | ||
44 | movw rp, #TEGRA_CLK_RST_DEVICES_##lhu & 0xffff ; \ | ||
45 | movt rp, #TEGRA_CLK_RST_DEVICES_##lhu >> 16 ; \ | ||
46 | /* Load value from CLK_RST register */ \ | ||
47 | ldr rp, [rp, #0] ; \ | ||
48 | /* Test UART's reset bit */ \ | ||
49 | tst rp, #(1 << bit) ; \ | ||
50 | /* If set, can't use UART; jump to save no UART */ \ | ||
51 | bne 90f ; \ | ||
52 | /* Load address of CLK_OUT_ENB register */ \ | ||
53 | movw rp, #TEGRA_CLK_OUT_ENB_##lhu & 0xffff ; \ | ||
54 | movt rp, #TEGRA_CLK_OUT_ENB_##lhu >> 16 ; \ | ||
55 | /* Load value from CLK_OUT_ENB register */ \ | ||
56 | ldr rp, [rp, #0] ; \ | ||
57 | /* Test UART's clock enable bit */ \ | ||
58 | tst rp, #(1 << bit) ; \ | ||
59 | /* If clear, can't use UART; jump to save no UART */ \ | ||
60 | beq 90f ; \ | ||
61 | /* Passed all tests, load address of UART registers */ \ | ||
62 | movw rp, #TEGRA_UART##uart##_BASE & 0xffff ; \ | ||
63 | movt rp, #TEGRA_UART##uart##_BASE >> 16 ; \ | ||
64 | /* Jump to save UART address */ \ | ||
65 | b 91f | ||
31 | 66 | ||
32 | .macro addruart, rp, rv, tmp | 67 | .macro addruart, rp, rv, tmp |
33 | adr \rp, 99f @ actual addr of 99f | 68 | adr \rp, 99f @ actual addr of 99f |
@@ -36,22 +71,101 @@ | |||
36 | ldr \rp, [\rp, #4] @ linked tegra_uart_config | 71 | ldr \rp, [\rp, #4] @ linked tegra_uart_config |
37 | sub \tmp, \rp, \rv @ actual tegra_uart_config | 72 | sub \tmp, \rp, \rv @ actual tegra_uart_config |
38 | ldr \rp, [\tmp] @ Load tegra_uart_config | 73 | ldr \rp, [\tmp] @ Load tegra_uart_config |
39 | cmp \rp, #1 @ needs intitialization? | 74 | cmp \rp, #1 @ needs initialization? |
40 | bne 100f @ no; go load the addresses | 75 | bne 100f @ no; go load the addresses |
41 | mov \rv, #0 @ yes; record init is done | 76 | mov \rv, #0 @ yes; record init is done |
42 | str \rv, [\tmp] | 77 | str \rv, [\tmp] |
43 | mov \rp, #TEGRA_IRAM_BASE @ See if cookie is in IRAM | 78 | |
44 | ldr \rv, [\rp, #TEGRA_IRAM_DEBUG_UART_OFFSET] | 79 | #ifdef CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA |
45 | movw \rp, #TEGRA_IRAM_DEBUG_UART_COOKIE & 0xffff | 80 | /* Check ODMDATA */ |
46 | movt \rp, #TEGRA_IRAM_DEBUG_UART_COOKIE >> 16 | 81 | 10: movw \rp, #TEGRA_PMC_SCRATCH20 & 0xffff |
47 | cmp \rv, \rp @ Cookie present? | 82 | movt \rp, #TEGRA_PMC_SCRATCH20 >> 16 |
48 | bne 100f @ No, use default UART | 83 | ldr \rp, [\rp, #0] @ Load PMC_SCRATCH20 |
49 | mov \rp, #TEGRA_IRAM_BASE @ Load UART address from IRAM | 84 | ubfx \rv, \rp, #18, #2 @ 19:18 are console type |
50 | ldr \rv, [\rp, #TEGRA_IRAM_DEBUG_UART_OFFSET + 4] | 85 | cmp \rv, #2 @ 2 and 3 mean DCC, UART |
51 | str \rv, [\tmp, #4] @ Store in tegra_uart_phys | 86 | beq 11f @ some boards swap the meaning |
52 | sub \rv, \rv, #IO_APB_PHYS @ Calculate virt address | 87 | cmp \rv, #3 @ so accept either |
88 | bne 90f | ||
89 | 11: ubfx \rv, \rp, #15, #3 @ 17:15 are UART ID | ||
90 | cmp \rv, #0 @ UART 0? | ||
91 | beq 20f | ||
92 | cmp \rv, #1 @ UART 1? | ||
93 | beq 21f | ||
94 | cmp \rv, #2 @ UART 2? | ||
95 | beq 22f | ||
96 | cmp \rv, #3 @ UART 3? | ||
97 | beq 23f | ||
98 | cmp \rv, #4 @ UART 4? | ||
99 | beq 24f | ||
100 | b 90f @ invalid | ||
101 | #endif | ||
102 | |||
103 | #if defined(CONFIG_TEGRA_DEBUG_UARTA) || \ | ||
104 | defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA) | ||
105 | /* Check UART A validity */ | ||
106 | 20: checkuart(\rp, \rv, L, 6, A) | ||
107 | #endif | ||
108 | |||
109 | #if defined(CONFIG_TEGRA_DEBUG_UARTB) || \ | ||
110 | defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA) | ||
111 | /* Check UART B validity */ | ||
112 | 21: checkuart(\rp, \rv, L, 7, B) | ||
113 | #endif | ||
114 | |||
115 | #if defined(CONFIG_TEGRA_DEBUG_UARTC) || \ | ||
116 | defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA) | ||
117 | /* Check UART C validity */ | ||
118 | 22: checkuart(\rp, \rv, H, 23, C) | ||
119 | #endif | ||
120 | |||
121 | #if defined(CONFIG_TEGRA_DEBUG_UARTD) || \ | ||
122 | defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA) | ||
123 | /* Check UART D validity */ | ||
124 | 23: checkuart(\rp, \rv, U, 1, D) | ||
125 | #endif | ||
126 | |||
127 | #if defined(CONFIG_TEGRA_DEBUG_UARTE) || \ | ||
128 | defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA) | ||
129 | /* Check UART E validity */ | ||
130 | 24: | ||
131 | checkuart(\rp, \rv, U, 2, E) | ||
132 | #endif | ||
133 | |||
134 | /* No valid UART found */ | ||
135 | 90: mov \rp, #0 | ||
136 | /* fall through */ | ||
137 | |||
138 | /* Record whichever UART we chose */ | ||
139 | 91: str \rp, [\tmp, #4] @ Store in tegra_uart_phys | ||
140 | cmp \rp, #0 @ Valid UART address? | ||
141 | bne 92f @ Yes, go process it | ||
142 | str \rp, [\tmp, #8] @ Store 0 in tegra_uart_phys | ||
143 | b 100f @ Done | ||
144 | 92: sub \rv, \rp, #IO_APB_PHYS @ Calculate virt address | ||
53 | add \rv, \rv, #IO_APB_VIRT | 145 | add \rv, \rv, #IO_APB_VIRT |
54 | str \rv, [\tmp, #8] @ Store in tegra_uart_virt | 146 | str \rv, [\tmp, #8] @ Store in tegra_uart_virt |
147 | movw \rv, #TEGRA_APB_MISC_GP_HIDREV & 0xffff | ||
148 | movt \rv, #TEGRA_APB_MISC_GP_HIDREV >> 16 | ||
149 | ldr \rv, [\rv, #0] @ Load HIDREV | ||
150 | ubfx \rv, \rv, #8, #8 @ 15:8 are SoC version | ||
151 | cmp \rv, #0x20 @ Tegra20? | ||
152 | moveq \rv, #0x75 @ Tegra20 divisor | ||
153 | movne \rv, #0xdd @ Tegra30 divisor | ||
154 | str \rv, [\tmp, #12] @ Save divisor to scratch | ||
155 | /* uart[UART_LCR] = UART_LCR_WLEN8 | UART_LCR_DLAB; */ | ||
156 | mov \rv, #UART_LCR_WLEN8 | UART_LCR_DLAB | ||
157 | str \rv, [\rp, #UART_LCR << UART_SHIFT] | ||
158 | /* uart[UART_DLL] = div & 0xff; */ | ||
159 | ldr \rv, [\tmp, #12] | ||
160 | and \rv, \rv, #0xff | ||
161 | str \rv, [\rp, #UART_DLL << UART_SHIFT] | ||
162 | /* uart[UART_DLM] = div >> 8; */ | ||
163 | ldr \rv, [\tmp, #12] | ||
164 | lsr \rv, \rv, #8 | ||
165 | str \rv, [\rp, #UART_DLM << UART_SHIFT] | ||
166 | /* uart[UART_LCR] = UART_LCR_WLEN8; */ | ||
167 | mov \rv, #UART_LCR_WLEN8 | ||
168 | str \rv, [\rp, #UART_LCR << UART_SHIFT] | ||
55 | b 100f | 169 | b 100f |
56 | 170 | ||
57 | .align | 171 | .align |
@@ -59,27 +173,24 @@ | |||
59 | .word tegra_uart_config | 173 | .word tegra_uart_config |
60 | .ltorg | 174 | .ltorg |
61 | 175 | ||
176 | /* Load previously selected UART address */ | ||
62 | 100: ldr \rp, [\tmp, #4] @ Load tegra_uart_phys | 177 | 100: ldr \rp, [\tmp, #4] @ Load tegra_uart_phys |
63 | ldr \rv, [\tmp, #8] @ Load tegra_uart_virt | 178 | ldr \rv, [\tmp, #8] @ Load tegra_uart_virt |
64 | .endm | 179 | .endm |
65 | 180 | ||
66 | #define UART_SHIFT 2 | ||
67 | |||
68 | /* | 181 | /* |
69 | * Code below is swiped from <asm/hardware/debug-8250.S>, but add an extra | 182 | * Code below is swiped from <asm/hardware/debug-8250.S>, but add an extra |
70 | * check to make sure that we aren't in the CONFIG_TEGRA_DEBUG_UART_NONE case. | 183 | * check to make sure that the UART address is actually valid. |
71 | * We use the fact that all 5 valid UART addresses all have something in the | ||
72 | * 2nd-to-lowest byte. | ||
73 | */ | 184 | */ |
74 | 185 | ||
75 | .macro senduart, rd, rx | 186 | .macro senduart, rd, rx |
76 | tst \rx, #0x0000ff00 | 187 | cmp \rx, #0 |
77 | strneb \rd, [\rx, #UART_TX << UART_SHIFT] | 188 | strneb \rd, [\rx, #UART_TX << UART_SHIFT] |
78 | 1001: | 189 | 1001: |
79 | .endm | 190 | .endm |
80 | 191 | ||
81 | .macro busyuart, rd, rx | 192 | .macro busyuart, rd, rx |
82 | tst \rx, #0x0000ff00 | 193 | cmp \rx, #0 |
83 | beq 1002f | 194 | beq 1002f |
84 | 1001: ldrb \rd, [\rx, #UART_LSR << UART_SHIFT] | 195 | 1001: ldrb \rd, [\rx, #UART_LSR << UART_SHIFT] |
85 | and \rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE | 196 | and \rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE |
@@ -90,7 +201,7 @@ | |||
90 | 201 | ||
91 | .macro waituart, rd, rx | 202 | .macro waituart, rd, rx |
92 | #ifdef FLOW_CONTROL | 203 | #ifdef FLOW_CONTROL |
93 | tst \rx, #0x0000ff00 | 204 | cmp \rx, #0 |
94 | beq 1002f | 205 | beq 1002f |
95 | 1001: ldrb \rd, [\rx, #UART_MSR << UART_SHIFT] | 206 | 1001: ldrb \rd, [\rx, #UART_MSR << UART_SHIFT] |
96 | tst \rd, #UART_MSR_CTS | 207 | tst \rd, #UART_MSR_CTS |