1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | /* |
3 | * Hardware-specific External Interface I/O core definitions |
4 | * for the BCM47xx family of SiliconBackplane-based chips. |
5 | * |
6 | * The External Interface core supports a total of three external chip selects |
7 | * supporting external interfaces. One of the external chip selects is |
8 | * used for Flash, one is used for PCMCIA, and the other may be |
9 | * programmed to support either a synchronous interface or an |
10 | * asynchronous interface. The asynchronous interface can be used to |
11 | * support external devices such as UARTs and the BCM2019 Bluetooth |
12 | * baseband processor. |
13 | * The external interface core also contains 2 on-chip 16550 UARTs, clock |
14 | * frequency control, a watchdog interrupt timer, and a GPIO interface. |
15 | * |
16 | * Copyright 2005, Broadcom Corporation |
17 | * Copyright 2006, Michael Buesch |
18 | */ |
19 | #ifndef LINUX_SSB_EXTIFCORE_H_ |
20 | #define LINUX_SSB_EXTIFCORE_H_ |
21 | |
22 | /* external interface address space */ |
23 | #define SSB_EXTIF_PCMCIA_MEMBASE(x) (x) |
24 | #define SSB_EXTIF_PCMCIA_IOBASE(x) ((x) + 0x100000) |
25 | #define SSB_EXTIF_PCMCIA_CFGBASE(x) ((x) + 0x200000) |
26 | #define SSB_EXTIF_CFGIF_BASE(x) ((x) + 0x800000) |
27 | #define SSB_EXTIF_FLASH_BASE(x) ((x) + 0xc00000) |
28 | |
29 | #define SSB_EXTIF_NR_GPIOOUT 5 |
30 | /* GPIO NOTE: |
31 | * The multiple instances of output and output enable registers |
32 | * are present to allow driver software for multiple cores to control |
33 | * gpio outputs without needing to share a single register pair. |
34 | * Use the following helper macro to get a register offset value. |
35 | */ |
36 | #define SSB_EXTIF_GPIO_OUT(index) ({ \ |
37 | BUILD_BUG_ON(index >= SSB_EXTIF_NR_GPIOOUT); \ |
38 | SSB_EXTIF_GPIO_OUT_BASE + ((index) * 8); \ |
39 | }) |
40 | #define SSB_EXTIF_GPIO_OUTEN(index) ({ \ |
41 | BUILD_BUG_ON(index >= SSB_EXTIF_NR_GPIOOUT); \ |
42 | SSB_EXTIF_GPIO_OUTEN_BASE + ((index) * 8); \ |
43 | }) |
44 | |
45 | /** EXTIF core registers **/ |
46 | |
47 | #define SSB_EXTIF_CTL 0x0000 |
48 | #define SSB_EXTIF_CTL_UARTEN (1 << 0) /* UART enable */ |
49 | #define SSB_EXTIF_EXTSTAT 0x0004 |
50 | #define SSB_EXTIF_EXTSTAT_EMODE (1 << 0) /* Endian mode (ro) */ |
51 | #define SSB_EXTIF_EXTSTAT_EIRQPIN (1 << 1) /* External interrupt pin (ro) */ |
52 | #define SSB_EXTIF_EXTSTAT_GPIOIRQPIN (1 << 2) /* GPIO interrupt pin (ro) */ |
53 | #define SSB_EXTIF_PCMCIA_CFG 0x0010 |
54 | #define SSB_EXTIF_PCMCIA_MEMWAIT 0x0014 |
55 | #define SSB_EXTIF_PCMCIA_ATTRWAIT 0x0018 |
56 | #define SSB_EXTIF_PCMCIA_IOWAIT 0x001C |
57 | #define SSB_EXTIF_PROG_CFG 0x0020 |
58 | #define SSB_EXTIF_PROG_WAITCNT 0x0024 |
59 | #define SSB_EXTIF_FLASH_CFG 0x0028 |
60 | #define SSB_EXTIF_FLASH_WAITCNT 0x002C |
61 | #define SSB_EXTIF_WATCHDOG 0x0040 |
62 | #define SSB_EXTIF_CLOCK_N 0x0044 |
63 | #define SSB_EXTIF_CLOCK_SB 0x0048 |
64 | #define SSB_EXTIF_CLOCK_PCI 0x004C |
65 | #define SSB_EXTIF_CLOCK_MII 0x0050 |
66 | #define SSB_EXTIF_GPIO_IN 0x0060 |
67 | #define SSB_EXTIF_GPIO_OUT_BASE 0x0064 |
68 | #define SSB_EXTIF_GPIO_OUTEN_BASE 0x0068 |
69 | #define SSB_EXTIF_EJTAG_OUTEN 0x0090 |
70 | #define SSB_EXTIF_GPIO_INTPOL 0x0094 |
71 | #define SSB_EXTIF_GPIO_INTMASK 0x0098 |
72 | #define SSB_EXTIF_UART_DATA 0x0300 |
73 | #define SSB_EXTIF_UART_TIMER 0x0310 |
74 | #define SSB_EXTIF_UART_FCR 0x0320 |
75 | #define SSB_EXTIF_UART_LCR 0x0330 |
76 | #define SSB_EXTIF_UART_MCR 0x0340 |
77 | #define SSB_EXTIF_UART_LSR 0x0350 |
78 | #define SSB_EXTIF_UART_MSR 0x0360 |
79 | #define SSB_EXTIF_UART_SCRATCH 0x0370 |
80 | |
81 | |
82 | |
83 | |
84 | /* pcmcia/prog/flash_config */ |
85 | #define SSB_EXTCFG_EN (1 << 0) /* enable */ |
86 | #define SSB_EXTCFG_MODE 0xE /* mode */ |
87 | #define SSB_EXTCFG_MODE_SHIFT 1 |
88 | #define SSB_EXTCFG_MODE_FLASH 0x0 /* flash/asynchronous mode */ |
89 | #define SSB_EXTCFG_MODE_SYNC 0x2 /* synchronous mode */ |
90 | #define SSB_EXTCFG_MODE_PCMCIA 0x4 /* pcmcia mode */ |
91 | #define SSB_EXTCFG_DS16 (1 << 4) /* destsize: 0=8bit, 1=16bit */ |
92 | #define SSB_EXTCFG_BSWAP (1 << 5) /* byteswap */ |
93 | #define SSB_EXTCFG_CLKDIV 0xC0 /* clock divider */ |
94 | #define SSB_EXTCFG_CLKDIV_SHIFT 6 |
95 | #define SSB_EXTCFG_CLKDIV_2 0x0 /* backplane/2 */ |
96 | #define SSB_EXTCFG_CLKDIV_3 0x40 /* backplane/3 */ |
97 | #define SSB_EXTCFG_CLKDIV_4 0x80 /* backplane/4 */ |
98 | #define SSB_EXTCFG_CLKEN (1 << 8) /* clock enable */ |
99 | #define SSB_EXTCFG_STROBE (1 << 9) /* size/bytestrobe (synch only) */ |
100 | |
101 | /* pcmcia_memwait */ |
102 | #define SSB_PCMCIA_MEMW_0 0x0000003F /* waitcount0 */ |
103 | #define SSB_PCMCIA_MEMW_1 0x00001F00 /* waitcount1 */ |
104 | #define SSB_PCMCIA_MEMW_1_SHIFT 8 |
105 | #define SSB_PCMCIA_MEMW_2 0x001F0000 /* waitcount2 */ |
106 | #define SSB_PCMCIA_MEMW_2_SHIFT 16 |
107 | #define SSB_PCMCIA_MEMW_3 0x1F000000 /* waitcount3 */ |
108 | #define SSB_PCMCIA_MEMW_3_SHIFT 24 |
109 | |
110 | /* pcmcia_attrwait */ |
111 | #define SSB_PCMCIA_ATTW_0 0x0000003F /* waitcount0 */ |
112 | #define SSB_PCMCIA_ATTW_1 0x00001F00 /* waitcount1 */ |
113 | #define SSB_PCMCIA_ATTW_1_SHIFT 8 |
114 | #define SSB_PCMCIA_ATTW_2 0x001F0000 /* waitcount2 */ |
115 | #define SSB_PCMCIA_ATTW_2_SHIFT 16 |
116 | #define SSB_PCMCIA_ATTW_3 0x1F000000 /* waitcount3 */ |
117 | #define SSB_PCMCIA_ATTW_3_SHIFT 24 |
118 | |
119 | /* pcmcia_iowait */ |
120 | #define SSB_PCMCIA_IOW_0 0x0000003F /* waitcount0 */ |
121 | #define SSB_PCMCIA_IOW_1 0x00001F00 /* waitcount1 */ |
122 | #define SSB_PCMCIA_IOW_1_SHIFT 8 |
123 | #define SSB_PCMCIA_IOW_2 0x001F0000 /* waitcount2 */ |
124 | #define SSB_PCMCIA_IOW_2_SHIFT 16 |
125 | #define SSB_PCMCIA_IOW_3 0x1F000000 /* waitcount3 */ |
126 | #define SSB_PCMCIA_IOW_3_SHIFT 24 |
127 | |
128 | /* prog_waitcount */ |
129 | #define SSB_PROG_WCNT_0 0x0000001F /* waitcount0 */ |
130 | #define SSB_PROG_WCNT_1 0x00001F00 /* waitcount1 */ |
131 | #define SSB_PROG_WCNT_1_SHIFT 8 |
132 | #define SSB_PROG_WCNT_2 0x001F0000 /* waitcount2 */ |
133 | #define SSB_PROG_WCNT_2_SHIFT 16 |
134 | #define SSB_PROG_WCNT_3 0x1F000000 /* waitcount3 */ |
135 | #define SSB_PROG_WCNT_3_SHIFT 24 |
136 | |
137 | #define SSB_PROG_W0 0x0000000C |
138 | #define SSB_PROG_W1 0x00000A00 |
139 | #define SSB_PROG_W2 0x00020000 |
140 | #define SSB_PROG_W3 0x01000000 |
141 | |
142 | /* flash_waitcount */ |
143 | #define SSB_FLASH_WCNT_0 0x0000001F /* waitcount0 */ |
144 | #define SSB_FLASH_WCNT_1 0x00001F00 /* waitcount1 */ |
145 | #define SSB_FLASH_WCNT_1_SHIFT 8 |
146 | #define SSB_FLASH_WCNT_2 0x001F0000 /* waitcount2 */ |
147 | #define SSB_FLASH_WCNT_2_SHIFT 16 |
148 | #define SSB_FLASH_WCNT_3 0x1F000000 /* waitcount3 */ |
149 | #define SSB_FLASH_WCNT_3_SHIFT 24 |
150 | |
151 | /* watchdog */ |
152 | #define SSB_EXTIF_WATCHDOG_CLK 48000000 /* Hz */ |
153 | |
154 | #define SSB_EXTIF_WATCHDOG_MAX_TIMER ((1 << 28) - 1) |
155 | #define SSB_EXTIF_WATCHDOG_MAX_TIMER_MS (SSB_EXTIF_WATCHDOG_MAX_TIMER \ |
156 | / (SSB_EXTIF_WATCHDOG_CLK / 1000)) |
157 | |
158 | |
159 | #ifdef CONFIG_SSB_DRIVER_EXTIF |
160 | |
161 | struct ssb_extif { |
162 | struct ssb_device *dev; |
163 | spinlock_t gpio_lock; |
164 | }; |
165 | |
166 | static inline bool ssb_extif_available(struct ssb_extif *extif) |
167 | { |
168 | return (extif->dev != NULL); |
169 | } |
170 | |
171 | extern void ssb_extif_get_clockcontrol(struct ssb_extif *extif, |
172 | u32 *plltype, u32 *n, u32 *m); |
173 | |
174 | extern void ssb_extif_timing_init(struct ssb_extif *extif, |
175 | unsigned long ns); |
176 | |
177 | extern u32 ssb_extif_watchdog_timer_set(struct ssb_extif *extif, u32 ticks); |
178 | |
179 | /* Extif GPIO pin access */ |
180 | u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask); |
181 | u32 ssb_extif_gpio_out(struct ssb_extif *extif, u32 mask, u32 value); |
182 | u32 ssb_extif_gpio_outen(struct ssb_extif *extif, u32 mask, u32 value); |
183 | u32 ssb_extif_gpio_polarity(struct ssb_extif *extif, u32 mask, u32 value); |
184 | u32 ssb_extif_gpio_intmask(struct ssb_extif *extif, u32 mask, u32 value); |
185 | |
186 | #ifdef CONFIG_SSB_SERIAL |
187 | extern int ssb_extif_serial_init(struct ssb_extif *extif, |
188 | struct ssb_serial_port *ports); |
189 | #endif /* CONFIG_SSB_SERIAL */ |
190 | |
191 | |
192 | #else /* CONFIG_SSB_DRIVER_EXTIF */ |
193 | /* extif disabled */ |
194 | |
195 | struct ssb_extif { |
196 | }; |
197 | |
198 | static inline bool ssb_extif_available(struct ssb_extif *extif) |
199 | { |
200 | return false; |
201 | } |
202 | |
203 | static inline |
204 | void ssb_extif_get_clockcontrol(struct ssb_extif *extif, |
205 | u32 *plltype, u32 *n, u32 *m) |
206 | { |
207 | } |
208 | |
209 | static inline |
210 | void ssb_extif_timing_init(struct ssb_extif *extif, unsigned long ns) |
211 | { |
212 | } |
213 | |
214 | static inline |
215 | u32 ssb_extif_watchdog_timer_set(struct ssb_extif *extif, u32 ticks) |
216 | { |
217 | return 0; |
218 | } |
219 | |
220 | static inline u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask) |
221 | { |
222 | return 0; |
223 | } |
224 | |
225 | static inline u32 ssb_extif_gpio_out(struct ssb_extif *extif, u32 mask, |
226 | u32 value) |
227 | { |
228 | return 0; |
229 | } |
230 | |
231 | static inline u32 ssb_extif_gpio_outen(struct ssb_extif *extif, u32 mask, |
232 | u32 value) |
233 | { |
234 | return 0; |
235 | } |
236 | |
237 | static inline u32 ssb_extif_gpio_polarity(struct ssb_extif *extif, u32 mask, |
238 | u32 value) |
239 | { |
240 | return 0; |
241 | } |
242 | |
243 | static inline u32 ssb_extif_gpio_intmask(struct ssb_extif *extif, u32 mask, |
244 | u32 value) |
245 | { |
246 | return 0; |
247 | } |
248 | |
249 | #ifdef CONFIG_SSB_SERIAL |
250 | static inline int ssb_extif_serial_init(struct ssb_extif *extif, |
251 | struct ssb_serial_port *ports) |
252 | { |
253 | return 0; |
254 | } |
255 | #endif /* CONFIG_SSB_SERIAL */ |
256 | |
257 | #endif /* CONFIG_SSB_DRIVER_EXTIF */ |
258 | #endif /* LINUX_SSB_EXTIFCORE_H_ */ |
259 | |