ralink_com.c revision 1.6 1 /* $NetBSD: ralink_com.c,v 1.6 2018/12/08 17:46:12 thorpej Exp $ */
2 /*-
3 * Copyright (c) 2011 CradlePoint Technology, Inc.
4 * All rights reserved.
5 *
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY CRADLEPOINT TECHNOLOGY, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 /*-
30 * Copyright (c) 2006 Urbana-Champaign Independent Media Center.
31 * Copyright (c) 2006 Garrett D'Amore.
32 * All rights reserved.
33 *
34 * Portions of this code were written by Garrett D'Amore for the
35 * Champaign-Urbana Community Wireless Network Project.
36 *
37 * Redistribution and use in source and binary forms, with or
38 * without modification, are permitted provided that the following
39 * conditions are met:
40 * 1. Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above
43 * copyright notice, this list of conditions and the following
44 * disclaimer in the documentation and/or other materials provided
45 * with the distribution.
46 * 3. All advertising materials mentioning features or use of this
47 * software must display the following acknowledgements:
48 * This product includes software developed by the Urbana-Champaign
49 * Independent Media Center.
50 * This product includes software developed by Garrett D'Amore.
51 * 4. Urbana-Champaign Independent Media Center's name and Garrett
52 * D'Amore's name may not be used to endorse or promote products
53 * derived from this software without specific prior written permission.
54 *
55 * THIS SOFTWARE IS PROVIDED BY THE URBANA-CHAMPAIGN INDEPENDENT
56 * MEDIA CENTER AND GARRETT D'AMORE ``AS IS'' AND ANY EXPRESS OR
57 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
58 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
59 * ARE DISCLAIMED. IN NO EVENT SHALL THE URBANA-CHAMPAIGN INDEPENDENT
60 * MEDIA CENTER OR GARRETT D'AMORE BE LIABLE FOR ANY DIRECT, INDIRECT,
61 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
62 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
63 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
64 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
65 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
66 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
67 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
68 */
69
70 /*-
71 * Copyright (c) 1998 The NetBSD Foundation, Inc.
72 * All rights reserved.
73 *
74 * This code is derived from software contributed to The NetBSD Foundation
75 * by Charles M. Hannum.
76 *
77 * Redistribution and use in source and binary forms, with or without
78 * modification, are permitted provided that the following conditions
79 * are met:
80 * 1. Redistributions of source code must retain the above copyright
81 * notice, this list of conditions and the following disclaimer.
82 * 2. Redistributions in binary form must reproduce the above copyright
83 * notice, this list of conditions and the following disclaimer in the
84 * documentation and/or other materials provided with the distribution.
85 *
86 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
87 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
88 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
89 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
90 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
91 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
92 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
93 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
94 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
95 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
96 * POSSIBILITY OF SUCH DAMAGE.
97 */
98
99 /*-
100 * Copyright (c) 1991 The Regents of the University of California.
101 * All rights reserved.
102 *
103 * Redistribution and use in source and binary forms, with or without
104 * modification, are permitted provided that the following conditions
105 * are met:
106 * 1. Redistributions of source code must retain the above copyright
107 * notice, this list of conditions and the following disclaimer.
108 * 2. Redistributions in binary form must reproduce the above copyright
109 * notice, this list of conditions and the following disclaimer in the
110 * documentation and/or other materials provided with the distribution.
111 * 3. Neither the name of the University nor the names of its contributors
112 * may be used to endorse or promote products derived from this software
113 * without specific prior written permission.
114 *
115 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
116 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
117 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
118 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
119 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
120 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
121 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
122 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
123 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
124 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
125 * SUCH DAMAGE.
126 *
127 * @(#)com.c 7.5 (Berkeley) 5/16/91
128 */
129
130 /* ralink_com.c -- Ralink 3052 uart console driver */
131
132 #include <sys/cdefs.h>
133 __KERNEL_RCSID(0, "$NetBSD: ralink_com.c,v 1.6 2018/12/08 17:46:12 thorpej Exp $");
134
135 #include "locators.h"
136 #include <sys/param.h>
137 #include <sys/bus.h>
138 #include <sys/device.h>
139 #include <sys/kernel.h>
140 #include <sys/systm.h>
141 #include <sys/tty.h>
142 #include <sys/termios.h>
143 #include <sys/ttydefaults.h>
144
145 #include <dev/cons.h>
146 #include <dev/ic/comreg.h>
147 #include <dev/ic/comvar.h>
148
149 #include <mips/cpuregs.h>
150
151 #include <mips/ralink/ralink_reg.h>
152 #include <mips/ralink/ralink_var.h>
153
154 #include "opt_com.h"
155
156 struct ralink_com_softc {
157 struct com_softc sc_com;
158 void *sc_ih;
159 bus_addr_t sc_addr;
160 int sc_irq;
161 };
162
163 static int ralink_com_match(device_t, cfdata_t , void *);
164 static void ralink_com_attach(device_t, device_t, void *);
165 static void ralink_com_init_regs(struct com_regs *regsp, bus_space_tag_t,
166 bus_space_handle_t, bus_addr_t);
167
168 CFATTACH_DECL_NEW(ralink_com, sizeof(struct ralink_com_softc),
169 ralink_com_match, ralink_com_attach, NULL, NULL);
170
171 #define CONMODE \
172 ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
173
174 #ifndef COM_REGMAP
175 #error COM_REGMAP not defined!
176 #endif
177
178 #ifndef RALINK_CONADDR
179 #define RALINK_CONADDR RA_UART_LITE_BASE /* default console is UART_LITE */
180 #endif
181
182 /* address/irq/rst/gpiomode mappings */
183 static struct {
184 bus_addr_t addr;
185 int irq;
186 uint32_t rst;
187 uint32_t gpiomode;
188 } ralink_uart_maps[] = {
189 #ifdef MT7628
190 { RA_UART_LITE_BASE, RA_IRQ_UARTL, RST_UART0_7628, GPIO1MODE_UART0 },
191 { RA_UART1_BASE, RA_IRQ_UART1, RST_UART1_7628, GPIO1MODE_UART1 },
192 { RA_UART2_BASE, RA_IRQ_UART2, RST_UART2_7628, GPIO1MODE_UART2 },
193 #else
194 { RA_UART_BASE, RA_IRQ_UARTF, RST_UART, GPIOMODE_UARTF0 },
195 { RA_UART_LITE_BASE, RA_IRQ_UARTL, RST_UARTL, GPIOMODE_UARTL }
196 #endif
197 };
198
199 static inline int
200 ra_uart2irq(bus_addr_t addr)
201 {
202 int i;
203 for (i = 0; __arraycount(ralink_uart_maps); i++)
204 if (ralink_uart_maps[i].addr == addr)
205 return ralink_uart_maps[i].irq;
206 return -1;
207 }
208
209 static inline uint32_t
210 ra_uart2rst(bus_addr_t addr)
211 {
212 int i;
213 for (i = 0; __arraycount(ralink_uart_maps); i++)
214 if (ralink_uart_maps[i].addr == addr)
215 return ralink_uart_maps[i].rst;
216 return 0;
217 }
218
219 static inline uint32_t
220 ra_uart2gpiomode(bus_addr_t addr)
221 {
222 int i;
223 for (i = 0; __arraycount(ralink_uart_maps); i++)
224 if (ralink_uart_maps[i].addr == addr)
225 return ralink_uart_maps[i].gpiomode;
226 return 0;
227 }
228
229 static inline uint32_t
230 sysctl_read(const u_int offset)
231 {
232 return *RA_IOREG_VADDR(RA_SYSCTL_BASE, offset);
233 }
234
235 static inline void
236 sysctl_write(const u_int offset, uint32_t val)
237 {
238 *RA_IOREG_VADDR(RA_SYSCTL_BASE, offset) = val;
239 }
240
241 static inline uint32_t
242 uart_read(const u_int offset)
243 {
244 return *RA_IOREG_VADDR(RALINK_CONADDR, offset);
245 }
246
247 static inline void
248 uart_write(const u_int offset, const uint32_t val)
249 {
250 *RA_IOREG_VADDR(RALINK_CONADDR, offset) = val;
251 }
252
253 #ifdef RALINK_CONSOLE_EARLY
254 static int
255 ralink_cngetc(dev_t dv)
256 {
257 if ((uart_read(RA_UART_LSR) & LSR_RXRDY) == 0)
258 return -1;
259
260 return uart_read(RA_UART_RBR) & 0xff;
261 }
262
263 static void
264 ralink_cnputc(dev_t dv, int c)
265 {
266 int timo = 150000;
267
268 while ((uart_read(RA_UART_LSR) & LSR_TXRDY) == 0 && --timo > 0)
269 ;
270
271 uart_write(RA_UART_TBR, c);
272 __asm __volatile("sync");
273
274 timo = 150000;
275 while ((uart_read(RA_UART_LSR) & LSR_TSRE) == 0 && --timo > 0)
276 ;
277 }
278
279 static struct consdev ralink_earlycons = {
280 .cn_putc = ralink_cnputc,
281 .cn_getc = ralink_cngetc,
282 .cn_pollc = nullcnpollc,
283 };
284
285 void
286 ralink_console_early(void)
287 {
288 cn_tab = &ralink_earlycons;
289 }
290 #endif /* RALINK_CONSOLE_EARLY */
291
292
293 int
294 ralink_com_match(device_t parent, cfdata_t cf, void *aux)
295 {
296 const struct mainbus_attach_args *ma;
297 bus_addr_t addr;
298
299 ma = aux;
300 addr = ma->ma_addr;
301 if (addr == MAINBUSCF_ADDR_DEFAULT)
302 addr = RA_UART_LITE_BASE;
303
304 if (ra_uart2irq(addr) < 0)
305 return 0;
306
307 if (cn_tab == NULL || cn_tab->cn_pri < CN_NORMAL) {
308 printf("NULL console set, don't install ourselves "
309 "(of course this shouldn't print)");
310 return 0;
311 }
312
313 /*
314 * If we got this far, assume we want to install it as the console.
315 * No need to probe. Future possibilities include checking to see if it
316 * is console or KGDB but now it is our only console method if we aren't
317 * forcing a null console
318 */
319 return 1;
320 }
321
322 void
323 ralink_com_attach(device_t parent, device_t self, void *aux)
324 {
325 const struct mainbus_attach_args *ma = aux;
326 struct ralink_com_softc * const rtsc = device_private(self);
327 struct com_softc * const sc = &rtsc->sc_com;
328 bus_space_handle_t ioh;
329 int error;
330
331 /* opt addr and irq */
332 rtsc->sc_addr = ma->ma_addr;
333 if (rtsc->sc_addr == MAINBUSCF_ADDR_DEFAULT)
334 rtsc->sc_addr = RA_UART_LITE_BASE;
335 rtsc->sc_irq = ra_uart2irq(rtsc->sc_addr);
336
337 if ((error = bus_space_map(ma->ma_memt, rtsc->sc_addr,
338 RA_UART_SIZE, 0, &ioh)) != 0) {
339 aprint_error(": can't map registers, error=%d\n", error);
340 return;
341 }
342
343 sc->sc_dev = self;
344 sc->sc_frequency = RA_UART_FREQ;
345 #if defined(MT7628)
346 sc->sc_type = COM_TYPE_NORMAL;
347 #else
348 sc->sc_type = COM_TYPE_AU1x00;
349 #endif
350 sc->enabled = 1;
351
352 /* reset hardware if not a console */
353 if (rtsc->sc_addr != RALINK_CONADDR) {
354 uint32_t r;
355
356 /* reset */
357 r = sysctl_read(RA_SYSCTL_RST);
358 r |= ra_uart2rst(rtsc->sc_addr);
359 sysctl_write(RA_SYSCTL_RST, r);
360 r ^= ra_uart2rst(rtsc->sc_addr);
361 sysctl_write(RA_SYSCTL_RST, r);
362
363 /* make sure we are in UART mode */
364 r = sysctl_read(RA_SYSCTL_GPIOMODE);
365 r &= ra_uart2gpiomode(rtsc->sc_addr);
366 r |= __SHIFTIN(0, ra_uart2gpiomode(rtsc->sc_addr));
367 sysctl_write(RA_SYSCTL_GPIOMODE, r);
368 }
369
370 ralink_com_init_regs(&sc->sc_regs, ma->ma_memt, ioh, rtsc->sc_addr);
371
372 rtsc->sc_ih = ra_intr_establish(rtsc->sc_irq, comintr, sc, 1);
373 com_attach_subr(sc);
374 }
375
376 static void
377 ralink_com_init_regs(struct com_regs *regsp, bus_space_tag_t st,
378 bus_space_handle_t sh, bus_addr_t addr)
379 {
380
381 com_init_regs(regsp, st, sh, addr);
382
383 regsp->cr_map[COM_REG_RXDATA] = RA_UART_RBR;
384 regsp->cr_map[COM_REG_TXDATA] = RA_UART_TBR;
385 regsp->cr_map[COM_REG_DLBL] = RA_UART_DLL;
386 #if defined(MT7628)
387 regsp->cr_map[COM_REG_DLBH] = RA_UART_DLM;
388 #endif
389 regsp->cr_map[COM_REG_IER] = RA_UART_IER;
390 regsp->cr_map[COM_REG_IIR] = RA_UART_IIR;
391 regsp->cr_map[COM_REG_FIFO] = RA_UART_FCR;
392 regsp->cr_map[COM_REG_LCR] = RA_UART_LCR;
393 regsp->cr_map[COM_REG_MCR] = RA_UART_MCR;
394 regsp->cr_map[COM_REG_LSR] = RA_UART_LSR;
395 regsp->cr_map[COM_REG_MSR] = RA_UART_MSR;
396
397 regsp->cr_nports = 32;
398 }
399
400 void
401 ralink_com_early(int silent)
402 {
403 struct com_regs regs;
404 bus_space_handle_t bsh;
405 uint32_t r;
406 int error;
407
408 /* reset */
409 r = sysctl_read(RA_SYSCTL_RST);
410 r |= ra_uart2rst(RALINK_CONADDR);
411 sysctl_write(RA_SYSCTL_RST, r);
412 r ^= ra_uart2rst(RALINK_CONADDR);
413 sysctl_write(RA_SYSCTL_RST, r);
414
415 if (silent) {
416 /*
417 * put us in PIO mode,
418 * effectively tri-stating the UARTL block
419 */
420 r = sysctl_read(RA_SYSCTL_GPIOMODE);
421 r &= ra_uart2gpiomode(RALINK_CONADDR);
422 r |= __SHIFTIN(1, ra_uart2gpiomode(RALINK_CONADDR));
423 sysctl_write(RA_SYSCTL_GPIOMODE, r);
424 } else {
425 /* make sure we are in UART mode */
426 r = sysctl_read(RA_SYSCTL_GPIOMODE);
427 r &= ra_uart2gpiomode(RALINK_CONADDR);
428 r |= __SHIFTIN(0, ra_uart2gpiomode(RALINK_CONADDR));
429 sysctl_write(RA_SYSCTL_GPIOMODE, r);
430 }
431
432 uart_write(RA_UART_IER, 0); /* disable interrupts */
433 uart_write(RA_UART_FCR, 0); /* disable fifos */
434
435 /* set baud rate */
436 uart_write(RA_UART_LCR,
437 UART_LCR_WLS0 | UART_LCR_WLS1 | UART_LCR_DLAB);
438 uart_write(RA_UART_DLL,
439 (RA_UART_FREQ / RA_SERIAL_CLKDIV / RA_BAUDRATE) & 0xffff);
440 #if defined(MT7628)
441 uart_write(RA_UART_DLM,
442 ((RA_UART_FREQ / RA_SERIAL_CLKDIV / RA_BAUDRATE) & 0xffff) >> 8);
443 #endif
444 uart_write(RA_UART_LCR, UART_LCR_WLS0 | UART_LCR_WLS1);
445
446 if ((error = bus_space_map(&ra_bus_memt, RALINK_CONADDR,
447 32, 0, &bsh)) != 0) {
448 return;
449 }
450 ralink_com_init_regs(®s, &ra_bus_memt, bsh, RALINK_CONADDR);
451
452 #if defined(MT7628)
453 comcnattach1(®s, RA_BAUDRATE, RA_UART_FREQ,
454 COM_TYPE_NORMAL, CONMODE);
455 #else
456 /* Ralink UART has a 16-bit rate latch (like the AU1x00) */
457 comcnattach1(®s, RA_BAUDRATE, RA_UART_FREQ,
458 COM_TYPE_AU1x00, CONMODE);
459 #endif
460 }
461