xref: /netbsd-src/sys/arch/evbmips/rasoc/console.c (revision 946379e7b37692fc43f68eb0d1c10daa0a7f3b6c)
1 /*	$NetBSD: console.c,v 1.2 2011/07/28 15:50:13 matt 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 #include <sys/cdefs.h>
30 __KERNEL_RCSID(0, "$NetBSD: console.c,v 1.2 2011/07/28 15:50:13 matt Exp $");
31 
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/types.h>
35 
36 #include <dev/cons.h>
37 
38 #include <mips/ralink/ralink_reg.h>
39 #include <mips/ralink/ralink_var.h>
40 
41 
42 static inline uint32_t
43 sysctl_read(const u_int offset)
44 {
45 	return *RA_IOREG_VADDR(RA_SYSCTL_BASE, offset);
46 }
47 
48 static inline void
49 sysctl_write(const u_int offset, uint32_t val)
50 {
51 	*RA_IOREG_VADDR(RA_SYSCTL_BASE, offset) = val;
52 }
53 
54 static inline uint32_t
55 uart_read(const u_int offset)
56 {
57 	return *RA_IOREG_VADDR(RA_UART_LITE_BASE, offset);
58 }
59 
60 static inline void
61 uart_write(const u_int offset, const uint32_t val)
62 {
63 	*RA_IOREG_VADDR(RA_UART_LITE_BASE, offset) = val;
64 }
65 
66 #ifdef RA_CONSOLE_EARLY
67 static void
68 ra_console_putc(dev_t dev, int c)
69 {
70 	u_int timo;
71 
72 	timo = 150000;
73 	do {
74 		if ((uart_read(RA_UART_LSR) & UART_LSR_TDRQ) != 0)
75 			break;
76 	} while(--timo != 0);
77 
78 	uart_write(RA_UART_TBR, c);
79 	if (c == '\n')
80 		ra_console_putc (dev, '\r');
81 #if 1
82 	timo = 150000;
83 	do {
84 		if ((uart_read(RA_UART_LSR) & UART_LSR_TEMT) != 0)
85 			break;
86 	} while(--timo != 0);
87 #endif
88 }
89 
90 static int
91 ra_console_getc(dev_t dev)
92 {
93 	while ((uart_read(RA_UART_LSR) & UART_LSR_DR) == 0)
94 		;
95 	return (char)(uart_read(RA_UART_RBR) & 0xff);
96 }
97 
98 static void
99 ra_console_flush(dev_t dev)
100 {
101 	while ((uart_read(RA_UART_LSR) & UART_LSR_TEMT) == 0)
102 		;
103 }
104 
105 void
106 ra_console_early(void)
107 {
108 	uint32_t r;
109 
110 	/* reset */
111 	r = sysctl_read(RA_SYSCTL_RST);
112 	r |= RST_UARTL;
113 	sysctl_write(RA_SYSCTL_RST, r);
114 	r ^= RST_UARTL;
115 	sysctl_write(RA_SYSCTL_RST, r);
116 
117 	/* make sure we are in UART mode */
118 	r = sysctl_read(RA_SYSCTL_GPIOMODE);
119 	r &= ~GPIOMODE_UARTL;
120 	sysctl_write(RA_SYSCTL_GPIOMODE, r);
121 
122 	uart_write(RA_UART_IER, 0);		/* disable interrupts */
123 	uart_write(RA_UART_FCR, 0);		/* disable fifos */
124 
125 	/* set baud rate */
126 	uart_write(RA_UART_LCR,
127 		UART_LCR_WLS0 | UART_LCR_WLS1 | UART_LCR_DLAB);
128 	uart_write(RA_UART_DLL,
129 		(RA_UART_FREQ / RA_SERIAL_CLKDIV / RA_BAUDRATE)
130 			& 0xffff);
131 	uart_write(RA_UART_LCR,
132 		UART_LCR_WLS0 | UART_LCR_WLS1);
133 
134 	static struct consdev lite_cn = {
135 	    .cn_probe = NULL,
136 	    .cn_init = NULL,
137 	    .cn_getc = ra_console_getc,
138 	    .cn_putc = ra_console_putc,
139 	    .cn_pollc = nullcnpollc,
140 	    .cn_bell = NULL,
141 	    .cn_halt = NULL,
142 	    .cn_flush = ra_console_flush,
143 	    .cn_dev = makedev(0, 0),
144 	    .cn_pri = CN_DEAD,
145 	};
146 
147 	cn_tab = &lite_cn;
148 
149 }
150 #endif	/* RA_CONSOLE_EARLY */
151 
152 void
153 consinit(void)
154 {
155 	if (ra_check_memo_reg(SERIAL_CONSOLE)) {
156 		ralink_com_early(0);
157 		printf("Enabled early console\n");
158 	} else {
159 		/*
160 		 * this should be OK, but our shell configuration doesn't seem
161 		 * to be working, so create a silent console
162 		 */
163 		cn_tab = NULL;
164 		ralink_com_early(1);
165 		printf("Enabled silent console\n");
166 	}
167 
168 #if 0
169 	/* update ddb escape sequence to '~~' to avoid the undocking issue */
170 	cn_set_magic("\x7E\x7E");
171 #endif
172 }
173