xref: /netbsd-src/sys/arch/evbmips/rasoc/console.c (revision 4613293a54ab51541a7e30a70edd08bfd3649cac)
1*4613293aSryo /*	$NetBSD: console.c,v 1.3 2016/10/05 15:54:58 ryo Exp $	*/
29c6e0201Smatt /*-
39c6e0201Smatt  * Copyright (c) 2011 CradlePoint Technology, Inc.
49c6e0201Smatt  * All rights reserved.
59c6e0201Smatt  *
69c6e0201Smatt  *
79c6e0201Smatt  * Redistribution and use in source and binary forms, with or without
89c6e0201Smatt  * modification, are permitted provided that the following conditions
99c6e0201Smatt  * are met:
109c6e0201Smatt  * 1. Redistributions of source code must retain the above copyright
119c6e0201Smatt  *    notice, this list of conditions and the following disclaimer.
129c6e0201Smatt  * 2. Redistributions in binary form must reproduce the above copyright
139c6e0201Smatt  *    notice, this list of conditions and the following disclaimer in the
149c6e0201Smatt  *    documentation and/or other materials provided with the distribution.
159c6e0201Smatt  *
169c6e0201Smatt  * THIS SOFTWARE IS PROVIDED BY CRADLEPOINT TECHNOLOGY, INC. AND CONTRIBUTORS
179c6e0201Smatt  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
189c6e0201Smatt  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
199c6e0201Smatt  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
209c6e0201Smatt  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
219c6e0201Smatt  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
229c6e0201Smatt  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
239c6e0201Smatt  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
249c6e0201Smatt  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
259c6e0201Smatt  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
269c6e0201Smatt  * POSSIBILITY OF SUCH DAMAGE.
279c6e0201Smatt  */
289c6e0201Smatt 
299c6e0201Smatt #include <sys/cdefs.h>
30*4613293aSryo __KERNEL_RCSID(0, "$NetBSD: console.c,v 1.3 2016/10/05 15:54:58 ryo Exp $");
319c6e0201Smatt 
329c6e0201Smatt #include <sys/param.h>
339c6e0201Smatt #include <sys/systm.h>
349c6e0201Smatt #include <sys/types.h>
359c6e0201Smatt 
369c6e0201Smatt #include <dev/cons.h>
379c6e0201Smatt 
389c6e0201Smatt #include <mips/ralink/ralink_reg.h>
399c6e0201Smatt #include <mips/ralink/ralink_var.h>
409c6e0201Smatt 
41*4613293aSryo #ifndef RALINK_CONADDR
42*4613293aSryo #define RALINK_CONADDR	RA_UART_LITE_BASE	/* default console is UART_LITE */
43*4613293aSryo #endif
449c6e0201Smatt 
459c6e0201Smatt static inline uint32_t
sysctl_read(const u_int offset)469c6e0201Smatt sysctl_read(const u_int offset)
479c6e0201Smatt {
489c6e0201Smatt 	return *RA_IOREG_VADDR(RA_SYSCTL_BASE, offset);
499c6e0201Smatt }
509c6e0201Smatt 
519c6e0201Smatt static inline void
sysctl_write(const u_int offset,uint32_t val)529c6e0201Smatt sysctl_write(const u_int offset, uint32_t val)
539c6e0201Smatt {
549c6e0201Smatt 	*RA_IOREG_VADDR(RA_SYSCTL_BASE, offset) = val;
559c6e0201Smatt }
569c6e0201Smatt 
579c6e0201Smatt static inline uint32_t
uart_read(const u_int offset)589c6e0201Smatt uart_read(const u_int offset)
599c6e0201Smatt {
60*4613293aSryo 	return *RA_IOREG_VADDR(RALINK_CONADDR, offset);
619c6e0201Smatt }
629c6e0201Smatt 
639c6e0201Smatt static inline void
uart_write(const u_int offset,const uint32_t val)649c6e0201Smatt uart_write(const u_int offset, const uint32_t val)
659c6e0201Smatt {
66*4613293aSryo 	*RA_IOREG_VADDR(RALINK_CONADDR, offset) = val;
679c6e0201Smatt }
689c6e0201Smatt 
699c6e0201Smatt #ifdef RA_CONSOLE_EARLY
709c6e0201Smatt static void
ra_console_putc(dev_t dev,int c)719c6e0201Smatt ra_console_putc(dev_t dev, int c)
729c6e0201Smatt {
739c6e0201Smatt 	u_int timo;
749c6e0201Smatt 
759c6e0201Smatt 	timo = 150000;
769c6e0201Smatt 	do {
779c6e0201Smatt 		if ((uart_read(RA_UART_LSR) & UART_LSR_TDRQ) != 0)
789c6e0201Smatt 			break;
799c6e0201Smatt 	} while(--timo != 0);
809c6e0201Smatt 
819c6e0201Smatt 	uart_write(RA_UART_TBR, c);
829c6e0201Smatt 	if (c == '\n')
839c6e0201Smatt 		ra_console_putc (dev, '\r');
849c6e0201Smatt #if 1
859c6e0201Smatt 	timo = 150000;
869c6e0201Smatt 	do {
879c6e0201Smatt 		if ((uart_read(RA_UART_LSR) & UART_LSR_TEMT) != 0)
889c6e0201Smatt 			break;
899c6e0201Smatt 	} while(--timo != 0);
909c6e0201Smatt #endif
919c6e0201Smatt }
929c6e0201Smatt 
939c6e0201Smatt static int
ra_console_getc(dev_t dev)949c6e0201Smatt ra_console_getc(dev_t dev)
959c6e0201Smatt {
969c6e0201Smatt 	while ((uart_read(RA_UART_LSR) & UART_LSR_DR) == 0)
979c6e0201Smatt 		;
989c6e0201Smatt 	return (char)(uart_read(RA_UART_RBR) & 0xff);
999c6e0201Smatt }
1009c6e0201Smatt 
1019c6e0201Smatt static void
ra_console_flush(dev_t dev)1029c6e0201Smatt ra_console_flush(dev_t dev)
1039c6e0201Smatt {
1049c6e0201Smatt 	while ((uart_read(RA_UART_LSR) & UART_LSR_TEMT) == 0)
1059c6e0201Smatt 		;
1069c6e0201Smatt }
1079c6e0201Smatt 
1089c6e0201Smatt void
ra_console_early(void)1099c6e0201Smatt ra_console_early(void)
1109c6e0201Smatt {
1119c6e0201Smatt 	uint32_t r;
1129c6e0201Smatt 
1139c6e0201Smatt 	/* reset */
1149c6e0201Smatt 	r = sysctl_read(RA_SYSCTL_RST);
1159c6e0201Smatt 	r |= RST_UARTL;
1169c6e0201Smatt 	sysctl_write(RA_SYSCTL_RST, r);
1179c6e0201Smatt 	r ^= RST_UARTL;
1189c6e0201Smatt 	sysctl_write(RA_SYSCTL_RST, r);
1199c6e0201Smatt 
1209c6e0201Smatt 	/* make sure we are in UART mode */
1219c6e0201Smatt 	r = sysctl_read(RA_SYSCTL_GPIOMODE);
1229c6e0201Smatt 	r &= ~GPIOMODE_UARTL;
1239c6e0201Smatt 	sysctl_write(RA_SYSCTL_GPIOMODE, r);
1249c6e0201Smatt 
1259c6e0201Smatt 	uart_write(RA_UART_IER, 0);		/* disable interrupts */
1269c6e0201Smatt 	uart_write(RA_UART_FCR, 0);		/* disable fifos */
1279c6e0201Smatt 
1289c6e0201Smatt 	/* set baud rate */
1299c6e0201Smatt 	uart_write(RA_UART_LCR,
1309c6e0201Smatt 		UART_LCR_WLS0 | UART_LCR_WLS1 | UART_LCR_DLAB);
1319c6e0201Smatt 	uart_write(RA_UART_DLL,
1329c6e0201Smatt 		(RA_UART_FREQ / RA_SERIAL_CLKDIV / RA_BAUDRATE)
1339c6e0201Smatt 			& 0xffff);
1349c6e0201Smatt 	uart_write(RA_UART_LCR,
1359c6e0201Smatt 		UART_LCR_WLS0 | UART_LCR_WLS1);
1369c6e0201Smatt 
1379c6e0201Smatt 	static struct consdev lite_cn = {
1389c6e0201Smatt 	    .cn_probe = NULL,
1399c6e0201Smatt 	    .cn_init = NULL,
1409c6e0201Smatt 	    .cn_getc = ra_console_getc,
1419c6e0201Smatt 	    .cn_putc = ra_console_putc,
1429c6e0201Smatt 	    .cn_pollc = nullcnpollc,
1439c6e0201Smatt 	    .cn_bell = NULL,
1449c6e0201Smatt 	    .cn_halt = NULL,
1459c6e0201Smatt 	    .cn_flush = ra_console_flush,
1469c6e0201Smatt 	    .cn_dev = makedev(0, 0),
1479c6e0201Smatt 	    .cn_pri = CN_DEAD,
1489c6e0201Smatt 	};
1499c6e0201Smatt 
1509c6e0201Smatt 	cn_tab = &lite_cn;
1519c6e0201Smatt 
1529c6e0201Smatt }
1539c6e0201Smatt #endif	/* RA_CONSOLE_EARLY */
1549c6e0201Smatt 
1559c6e0201Smatt void
consinit(void)1569c6e0201Smatt consinit(void)
1579c6e0201Smatt {
1589c6e0201Smatt 	if (ra_check_memo_reg(SERIAL_CONSOLE)) {
1599c6e0201Smatt 		ralink_com_early(0);
1609c6e0201Smatt 		printf("Enabled early console\n");
1619c6e0201Smatt 	} else {
1629c6e0201Smatt 		/*
1639c6e0201Smatt 		 * this should be OK, but our shell configuration doesn't seem
1649c6e0201Smatt 		 * to be working, so create a silent console
1659c6e0201Smatt 		 */
1669c6e0201Smatt 		cn_tab = NULL;
1679c6e0201Smatt 		ralink_com_early(1);
1689c6e0201Smatt 		printf("Enabled silent console\n");
1699c6e0201Smatt 	}
1709c6e0201Smatt 
1719c6e0201Smatt #if 0
1729c6e0201Smatt 	/* update ddb escape sequence to '~~' to avoid the undocking issue */
1739c6e0201Smatt 	cn_set_magic("\x7E\x7E");
1749c6e0201Smatt #endif
1759c6e0201Smatt }
176