ralink_com.c revision 1.4.8.1 1 /* $NetBSD: ralink_com.c,v 1.4.8.1 2016/11/04 14:49:02 pgoyette 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.4.8.1 2016/11/04 14:49:02 pgoyette 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_initmap(struct com_regs *regsp);
166
167 CFATTACH_DECL_NEW(ralink_com, sizeof(struct ralink_com_softc),
168 ralink_com_match, ralink_com_attach, NULL, NULL);
169
170 #define CONMODE \
171 ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
172
173 #ifndef COM_REGMAP
174 #error COM_REGMAP not defined!
175 #endif
176
177 #ifndef RALINK_CONADDR
178 #define RALINK_CONADDR RA_UART_LITE_BASE /* default console is UART_LITE */
179 #endif
180
181 /* address/irq/rst/gpiomode mappings */
182 static struct {
183 bus_addr_t addr;
184 int irq;
185 uint32_t rst;
186 uint32_t gpiomode;
187 } ralink_uart_maps[] = {
188 #ifdef MT7628
189 { RA_UART_LITE_BASE, RA_IRQ_UARTL, RST_UART0_7628, GPIO1MODE_UART0 },
190 { RA_UART1_BASE, RA_IRQ_UART1, RST_UART1_7628, GPIO1MODE_UART1 },
191 { RA_UART2_BASE, RA_IRQ_UART2, RST_UART2_7628, GPIO1MODE_UART2 },
192 #else
193 { RA_UART_BASE, RA_IRQ_UARTF, RST_UART, GPIOMODE_UARTF0 },
194 { RA_UART_LITE_BASE, RA_IRQ_UARTL, RST_UARTL, GPIOMODE_UARTL }
195 #endif
196 };
197
198 static inline int
199 ra_uart2irq(bus_addr_t addr)
200 {
201 int i;
202 for (i = 0; __arraycount(ralink_uart_maps); i++)
203 if (ralink_uart_maps[i].addr == addr)
204 return ralink_uart_maps[i].irq;
205 return -1;
206 }
207
208 static inline uint32_t
209 ra_uart2rst(bus_addr_t addr)
210 {
211 int i;
212 for (i = 0; __arraycount(ralink_uart_maps); i++)
213 if (ralink_uart_maps[i].addr == addr)
214 return ralink_uart_maps[i].rst;
215 return 0;
216 }
217
218 static inline uint32_t
219 ra_uart2gpiomode(bus_addr_t addr)
220 {
221 int i;
222 for (i = 0; __arraycount(ralink_uart_maps); i++)
223 if (ralink_uart_maps[i].addr == addr)
224 return ralink_uart_maps[i].gpiomode;
225 return 0;
226 }
227
228 static inline uint32_t
229 sysctl_read(const u_int offset)
230 {
231 return *RA_IOREG_VADDR(RA_SYSCTL_BASE, offset);
232 }
233
234 static inline void
235 sysctl_write(const u_int offset, uint32_t val)
236 {
237 *RA_IOREG_VADDR(RA_SYSCTL_BASE, offset) = val;
238 }
239
240 static inline uint32_t
241 uart_read(const u_int offset)
242 {
243 return *RA_IOREG_VADDR(RALINK_CONADDR, offset);
244 }
245
246 static inline void
247 uart_write(const u_int offset, const uint32_t val)
248 {
249 *RA_IOREG_VADDR(RALINK_CONADDR, offset) = val;
250 }
251
252 #ifdef RALINK_CONSOLE_EARLY
253 static int
254 ralink_cngetc(dev_t dv)
255 {
256 if ((uart_read(RA_UART_LSR) & LSR_RXRDY) == 0)
257 return -1;
258
259 return uart_read(RA_UART_RBR) & 0xff;
260 }
261
262 static void
263 ralink_cnputc(dev_t dv, int c)
264 {
265 int timo = 150000;
266
267 while ((uart_read(RA_UART_LSR) & LSR_TXRDY) == 0 && --timo > 0)
268 ;
269
270 uart_write(RA_UART_TBR, c);
271 __asm __volatile("sync");
272
273 timo = 150000;
274 while ((uart_read(RA_UART_LSR) & LSR_TSRE) == 0 && --timo > 0)
275 ;
276 }
277
278 static struct consdev ralink_earlycons = {
279 .cn_putc = ralink_cnputc,
280 .cn_getc = ralink_cngetc,
281 .cn_pollc = nullcnpollc,
282 };
283
284 void
285 ralink_console_early(void)
286 {
287 cn_tab = &ralink_earlycons;
288 }
289 #endif /* RALINK_CONSOLE_EARLY */
290
291
292 int
293 ralink_com_match(device_t parent, cfdata_t cf, void *aux)
294 {
295 const struct mainbus_attach_args *ma;
296 bus_addr_t addr;
297
298 ma = aux;
299 addr = ma->ma_addr;
300 if (addr == MAINBUSCF_ADDR_DEFAULT)
301 addr = RA_UART_LITE_BASE;
302
303 if (ra_uart2irq(addr) < 0)
304 return 0;
305
306 if (cn_tab == NULL || cn_tab->cn_pri < CN_NORMAL) {
307 printf("NULL console set, don't install ourselves "
308 "(of course this shouldn't print)");
309 return 0;
310 }
311
312 /*
313 * If we got this far, assume we want to install it as the console.
314 * No need to probe. Future possibilities include checking to see if it
315 * is console or KGDB but now it is our only console method if we aren't
316 * forcing a null console
317 */
318 return 1;
319 }
320
321 void
322 ralink_com_attach(device_t parent, device_t self, void *aux)
323 {
324 const struct mainbus_attach_args *ma = aux;
325 struct ralink_com_softc * const rtsc = device_private(self);
326 struct com_softc * const sc = &rtsc->sc_com;
327 bus_space_handle_t ioh;
328 int error;
329
330 /* opt addr and irq */
331 rtsc->sc_addr = ma->ma_addr;
332 if (rtsc->sc_addr == MAINBUSCF_ADDR_DEFAULT)
333 rtsc->sc_addr = RA_UART_LITE_BASE;
334 rtsc->sc_irq = ra_uart2irq(rtsc->sc_addr);
335
336 if ((error = bus_space_map(ma->ma_memt, rtsc->sc_addr,
337 RA_UART_SIZE, 0, &ioh)) != 0) {
338 aprint_error(": can't map registers, error=%d\n", error);
339 return;
340 }
341
342 sc->sc_dev = self;
343 sc->sc_frequency = RA_UART_FREQ;
344 sc->sc_regs.cr_nports = 32;
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 COM_INIT_REGS(sc->sc_regs, ma->ma_memt, ioh, rtsc->sc_addr);
371 ralink_com_initmap(&sc->sc_regs);
372
373 rtsc->sc_ih = ra_intr_establish(rtsc->sc_irq, comintr, sc, 1);
374 com_attach_subr(sc);
375 }
376
377 static void
378 ralink_com_initmap(struct com_regs *regsp)
379 {
380 regsp->cr_map[COM_REG_RXDATA] = RA_UART_RBR;
381 regsp->cr_map[COM_REG_TXDATA] = RA_UART_TBR;
382 regsp->cr_map[COM_REG_DLBL] = RA_UART_DLL;
383 #if defined(MT7628)
384 regsp->cr_map[COM_REG_DLBH] = RA_UART_DLM;
385 #endif
386 regsp->cr_map[COM_REG_IER] = RA_UART_IER;
387 regsp->cr_map[COM_REG_IIR] = RA_UART_IIR;
388 regsp->cr_map[COM_REG_FIFO] = RA_UART_FCR;
389 regsp->cr_map[COM_REG_LCR] = RA_UART_LCR;
390 regsp->cr_map[COM_REG_MCR] = RA_UART_MCR;
391 regsp->cr_map[COM_REG_LSR] = RA_UART_LSR;
392 regsp->cr_map[COM_REG_MSR] = RA_UART_MSR;
393 }
394
395 void
396 ralink_com_early(int silent)
397 {
398 struct com_regs regs;
399 uint32_t r;
400 int error;
401
402 /* reset */
403 r = sysctl_read(RA_SYSCTL_RST);
404 r |= ra_uart2rst(RALINK_CONADDR);
405 sysctl_write(RA_SYSCTL_RST, r);
406 r ^= ra_uart2rst(RALINK_CONADDR);
407 sysctl_write(RA_SYSCTL_RST, r);
408
409 if (silent) {
410 /*
411 * put us in PIO mode,
412 * effectively tri-stating the UARTL block
413 */
414 r = sysctl_read(RA_SYSCTL_GPIOMODE);
415 r &= ra_uart2gpiomode(RALINK_CONADDR);
416 r |= __SHIFTIN(1, ra_uart2gpiomode(RALINK_CONADDR));
417 sysctl_write(RA_SYSCTL_GPIOMODE, r);
418 } else {
419 /* make sure we are in UART mode */
420 r = sysctl_read(RA_SYSCTL_GPIOMODE);
421 r &= ra_uart2gpiomode(RALINK_CONADDR);
422 r |= __SHIFTIN(0, ra_uart2gpiomode(RALINK_CONADDR));
423 sysctl_write(RA_SYSCTL_GPIOMODE, r);
424 }
425
426 uart_write(RA_UART_IER, 0); /* disable interrupts */
427 uart_write(RA_UART_FCR, 0); /* disable fifos */
428
429 /* set baud rate */
430 uart_write(RA_UART_LCR,
431 UART_LCR_WLS0 | UART_LCR_WLS1 | UART_LCR_DLAB);
432 uart_write(RA_UART_DLL,
433 (RA_UART_FREQ / RA_SERIAL_CLKDIV / RA_BAUDRATE) & 0xffff);
434 #if defined(MT7628)
435 uart_write(RA_UART_DLM,
436 ((RA_UART_FREQ / RA_SERIAL_CLKDIV / RA_BAUDRATE) & 0xffff) >> 8);
437 #endif
438 uart_write(RA_UART_LCR, UART_LCR_WLS0 | UART_LCR_WLS1);
439
440 regs.cr_iot = &ra_bus_memt;
441 regs.cr_iobase = RALINK_CONADDR;
442 regs.cr_nports = 32;
443 ralink_com_initmap(®s);
444
445 if ((error = bus_space_map(regs.cr_iot, regs.cr_iobase, regs.cr_nports,
446 0, ®s.cr_ioh)) != 0) {
447 return;
448 }
449
450 #if defined(MT7628)
451 comcnattach1(®s, RA_BAUDRATE, RA_UART_FREQ,
452 COM_TYPE_NORMAL, CONMODE);
453 #else
454 /* Ralink UART has a 16-bit rate latch (like the AU1x00) */
455 comcnattach1(®s, RA_BAUDRATE, RA_UART_FREQ,
456 COM_TYPE_AU1x00, CONMODE);
457 #endif
458 }
459