xref: /netbsd-src/sys/arch/mips/ralink/ralink_com.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /*	$NetBSD: ralink_com.c,v 1.5 2016/10/05 15:54:58 ryo 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.5 2016/10/05 15:54:58 ryo 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(&regs);
444 
445 	if ((error = bus_space_map(regs.cr_iot, regs.cr_iobase, regs.cr_nports,
446 	    0, &regs.cr_ioh)) != 0) {
447 		return;
448 	}
449 
450 #if defined(MT7628)
451 	comcnattach1(&regs, 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(&regs, RA_BAUDRATE, RA_UART_FREQ,
456 	    COM_TYPE_AU1x00, CONMODE);
457 #endif
458 }
459