diff options
author | Arnd Bergmann <arnd@arndb.de> | 2016-09-14 18:22:55 -0400 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2016-09-14 18:22:55 -0400 |
commit | ea58e97d66d624c037cef5bc2889a0b7a10c6a96 (patch) | |
tree | d07e1abe41e60a4a8ba123dadf603ffdf5348a71 /arch/arm/include | |
parent | 2c8cebd26266d5a7f44b7afbdb85e71b474358ee (diff) | |
parent | 4ebd50472899eb07d5dfc24f2015dce6fe3c5cb8 (diff) |
Merge tag 'arm-soc/for-4.9/soc' of http://github.com/Broadcom/stblinux into next/soc
Pull "Broadcom soc changes for 4.9" from Florian Fainelli:
This pull request contains Broadcom ARM-based SoC changes for 4.9, please pull
the following:
- Rafal adds preliminary support for the new BCM53573 Wi-Fi SoC based on a
single core Cortex A7 and re-using a bunch of iProc peripherals
- Florian adds support for earlyprintk on Broadcom STB/CM ARM-based chips by
reading the chip family_id value from a known location and deriving the UART
based address
* tag 'arm-soc/for-4.9/soc' of http://github.com/Broadcom/stblinux:
ARM: BCM53573: Initial support for Broadcom BCM53573 SoCs
ARM: brcmstb: Add earlyprintk support using run-time checks
Diffstat (limited to 'arch/arm/include')
-rw-r--r-- | arch/arm/include/debug/brcmstb.S | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/arch/arm/include/debug/brcmstb.S b/arch/arm/include/debug/brcmstb.S new file mode 100644 index 000000000000..9113d7b33ae0 --- /dev/null +++ b/arch/arm/include/debug/brcmstb.S | |||
@@ -0,0 +1,145 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2016 Broadcom | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License as | ||
6 | * published by the Free Software Foundation version 2. | ||
7 | * | ||
8 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
9 | * kind, whether express or implied; without even the implied warranty | ||
10 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | */ | ||
13 | #include <linux/serial_reg.h> | ||
14 | |||
15 | /* Physical register offset and virtual register offset */ | ||
16 | #define REG_PHYS_BASE 0xf0000000 | ||
17 | #define REG_VIRT_BASE 0xfc000000 | ||
18 | #define REG_PHYS_ADDR(x) ((x) + REG_PHYS_BASE) | ||
19 | |||
20 | /* Product id can be read from here */ | ||
21 | #define SUN_TOP_CTRL_BASE REG_PHYS_ADDR(0x404000) | ||
22 | |||
23 | #define UARTA_3390 REG_PHYS_ADDR(0x40a900) | ||
24 | #define UARTA_7250 REG_PHYS_ADDR(0x40b400) | ||
25 | #define UARTA_7268 REG_PHYS_ADDR(0x40c000) | ||
26 | #define UARTA_7271 UARTA_7268 | ||
27 | #define UARTA_7364 REG_PHYS_ADDR(0x40b000) | ||
28 | #define UARTA_7366 UARTA_7364 | ||
29 | #define UARTA_74371 REG_PHYS_ADDR(0x406b00) | ||
30 | #define UARTA_7439 REG_PHYS_ADDR(0x40a900) | ||
31 | #define UARTA_7445 REG_PHYS_ADDR(0x40ab00) | ||
32 | |||
33 | #define UART_SHIFT 2 | ||
34 | |||
35 | #define checkuart(rp, rv, family_id, family) \ | ||
36 | /* Load family id */ \ | ||
37 | ldr rp, =family_id ; \ | ||
38 | /* Compare SUN_TOP_CTRL value against it */ \ | ||
39 | cmp rp, rv ; \ | ||
40 | /* Passed test, load address */ \ | ||
41 | ldreq rp, =UARTA_##family ; \ | ||
42 | /* Jump to save UART address */ \ | ||
43 | beq 91f | ||
44 | |||
45 | .macro addruart, rp, rv, tmp | ||
46 | adr \rp, 99f @ actual addr of 99f | ||
47 | ldr \rv, [\rp] @ linked addr is stored there | ||
48 | sub \rv, \rv, \rp @ offset between the two | ||
49 | ldr \rp, [\rp, #4] @ linked brcmstb_uart_config | ||
50 | sub \tmp, \rp, \rv @ actual brcmstb_uart_config | ||
51 | ldr \rp, [\tmp] @ Load brcmstb_uart_config | ||
52 | cmp \rp, #1 @ needs initialization? | ||
53 | bne 100f @ no; go load the addresses | ||
54 | mov \rv, #0 @ yes; record init is done | ||
55 | str \rv, [\tmp] | ||
56 | |||
57 | /* Check SUN_TOP_CTRL base */ | ||
58 | ldr \rp, =SUN_TOP_CTRL_BASE @ load SUN_TOP_CTRL PA | ||
59 | ldr \rv, [\rp, #0] @ get register contents | ||
60 | and \rv, \rv, #0xffffff00 @ strip revision bits [7:0] | ||
61 | |||
62 | /* Chip specific detection starts here */ | ||
63 | 20: checkuart(\rp, \rv, 0x33900000, 3390) | ||
64 | 21: checkuart(\rp, \rv, 0x72500000, 7250) | ||
65 | 22: checkuart(\rp, \rv, 0x72680000, 7268) | ||
66 | 23: checkuart(\rp, \rv, 0x72710000, 7271) | ||
67 | 24: checkuart(\rp, \rv, 0x73640000, 7364) | ||
68 | 25: checkuart(\rp, \rv, 0x73660000, 7366) | ||
69 | 26: checkuart(\rp, \rv, 0x07437100, 74371) | ||
70 | 27: checkuart(\rp, \rv, 0x74390000, 7439) | ||
71 | 28: checkuart(\rp, \rv, 0x74450000, 7445) | ||
72 | |||
73 | /* No valid UART found */ | ||
74 | 90: mov \rp, #0 | ||
75 | /* fall through */ | ||
76 | |||
77 | /* Record whichever UART we chose */ | ||
78 | 91: str \rp, [\tmp, #4] @ Store in brcmstb_uart_phys | ||
79 | cmp \rp, #0 @ Valid UART address? | ||
80 | bne 92f @ Yes, go process it | ||
81 | str \rp, [\tmp, #8] @ Store 0 in brcmstb_uart_virt | ||
82 | b 100f @ Done | ||
83 | 92: and \rv, \rp, #0xffffff @ offset within 16MB section | ||
84 | add \rv, \rv, #REG_VIRT_BASE | ||
85 | str \rv, [\tmp, #8] @ Store in brcmstb_uart_virt | ||
86 | b 100f | ||
87 | |||
88 | .align | ||
89 | 99: .word . | ||
90 | .word brcmstb_uart_config | ||
91 | .ltorg | ||
92 | |||
93 | /* Load previously selected UART address */ | ||
94 | 100: ldr \rp, [\tmp, #4] @ Load brcmstb_uart_phys | ||
95 | ldr \rv, [\tmp, #8] @ Load brcmstb_uart_virt | ||
96 | .endm | ||
97 | |||
98 | .macro store, rd, rx:vararg | ||
99 | str \rd, \rx | ||
100 | .endm | ||
101 | |||
102 | .macro load, rd, rx:vararg | ||
103 | ldr \rd, \rx | ||
104 | .endm | ||
105 | |||
106 | .macro senduart,rd,rx | ||
107 | store \rd, [\rx, #UART_TX << UART_SHIFT] | ||
108 | .endm | ||
109 | |||
110 | .macro busyuart,rd,rx | ||
111 | 1002: load \rd, [\rx, #UART_LSR << UART_SHIFT] | ||
112 | and \rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE | ||
113 | teq \rd, #UART_LSR_TEMT | UART_LSR_THRE | ||
114 | bne 1002b | ||
115 | .endm | ||
116 | |||
117 | .macro waituart,rd,rx | ||
118 | .endm | ||
119 | |||
120 | /* | ||
121 | * Storage for the state maintained by the macros above. | ||
122 | * | ||
123 | * In the kernel proper, this data is located in arch/arm/mach-bcm/brcmstb.c. | ||
124 | * That's because this header is included from multiple files, and we only | ||
125 | * want a single copy of the data. In particular, the UART probing code above | ||
126 | * assumes it's running using physical addresses. This is true when this file | ||
127 | * is included from head.o, but not when included from debug.o. So we need | ||
128 | * to share the probe results between the two copies, rather than having | ||
129 | * to re-run the probing again later. | ||
130 | * | ||
131 | * In the decompressor, we put the symbol/storage right here, since common.c | ||
132 | * isn't included in the decompressor build. This symbol gets put in .text | ||
133 | * even though it's really data, since .data is discarded from the | ||
134 | * decompressor. Luckily, .text is writeable in the decompressor, unless | ||
135 | * CONFIG_ZBOOT_ROM. That dependency is handled in arch/arm/Kconfig.debug. | ||
136 | */ | ||
137 | #if defined(ZIMAGE) | ||
138 | brcmstb_uart_config: | ||
139 | /* Debug UART initialization required */ | ||
140 | .word 1 | ||
141 | /* Debug UART physical address */ | ||
142 | .word 0 | ||
143 | /* Debug UART virtual address */ | ||
144 | .word 0 | ||
145 | #endif | ||