1*f5ab653cSthorpej /* $Id: rmixl_com.c,v 1.8 2018/12/11 06:34:00 thorpej Exp $ */
2290a34a0Smatt /*-
3290a34a0Smatt * Copyright (c) 2006 Urbana-Champaign Independent Media Center.
4290a34a0Smatt * Copyright (c) 2006 Garrett D'Amore.
5290a34a0Smatt * All rights reserved.
6290a34a0Smatt *
7290a34a0Smatt * Portions of this code were written by Garrett D'Amore for the
8290a34a0Smatt * Champaign-Urbana Community Wireless Network Project.
9290a34a0Smatt *
10290a34a0Smatt * Redistribution and use in source and binary forms, with or
11290a34a0Smatt * without modification, are permitted provided that the following
12290a34a0Smatt * conditions are met:
13290a34a0Smatt * 1. Redistributions of source code must retain the above copyright
14290a34a0Smatt * notice, this list of conditions and the following disclaimer.
15290a34a0Smatt * 2. Redistributions in binary form must reproduce the above
16290a34a0Smatt * copyright notice, this list of conditions and the following
17290a34a0Smatt * disclaimer in the documentation and/or other materials provided
18290a34a0Smatt * with the distribution.
19290a34a0Smatt * 3. All advertising materials mentioning features or use of this
20290a34a0Smatt * software must display the following acknowledgements:
21290a34a0Smatt * This product includes software developed by the Urbana-Champaign
22290a34a0Smatt * Independent Media Center.
23290a34a0Smatt * This product includes software developed by Garrett D'Amore.
24290a34a0Smatt * 4. Urbana-Champaign Independent Media Center's name and Garrett
25290a34a0Smatt * D'Amore's name may not be used to endorse or promote products
26290a34a0Smatt * derived from this software without specific prior written permission.
27290a34a0Smatt *
28290a34a0Smatt * THIS SOFTWARE IS PROVIDED BY THE URBANA-CHAMPAIGN INDEPENDENT
29290a34a0Smatt * MEDIA CENTER AND GARRETT D'AMORE ``AS IS'' AND ANY EXPRESS OR
30290a34a0Smatt * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
31290a34a0Smatt * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32290a34a0Smatt * ARE DISCLAIMED. IN NO EVENT SHALL THE URBANA-CHAMPAIGN INDEPENDENT
33290a34a0Smatt * MEDIA CENTER OR GARRETT D'AMORE BE LIABLE FOR ANY DIRECT, INDIRECT,
34290a34a0Smatt * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
35290a34a0Smatt * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
36290a34a0Smatt * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
37290a34a0Smatt * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
38290a34a0Smatt * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
39290a34a0Smatt * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
40290a34a0Smatt * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41290a34a0Smatt */
42290a34a0Smatt
43290a34a0Smatt /*-
44290a34a0Smatt * Copyright (c) 1998 The NetBSD Foundation, Inc.
45290a34a0Smatt * All rights reserved.
46290a34a0Smatt *
47290a34a0Smatt * This code is derived from software contributed to The NetBSD Foundation
48290a34a0Smatt * by Charles M. Hannum.
49290a34a0Smatt *
50290a34a0Smatt * Redistribution and use in source and binary forms, with or without
51290a34a0Smatt * modification, are permitted provided that the following conditions
52290a34a0Smatt * are met:
53290a34a0Smatt * 1. Redistributions of source code must retain the above copyright
54290a34a0Smatt * notice, this list of conditions and the following disclaimer.
55290a34a0Smatt * 2. Redistributions in binary form must reproduce the above copyright
56290a34a0Smatt * notice, this list of conditions and the following disclaimer in the
57290a34a0Smatt * documentation and/or other materials provided with the distribution.
58290a34a0Smatt *
59290a34a0Smatt * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
60290a34a0Smatt * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
61290a34a0Smatt * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
62290a34a0Smatt * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
63290a34a0Smatt * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
64290a34a0Smatt * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
65290a34a0Smatt * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
66290a34a0Smatt * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
67290a34a0Smatt * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
68290a34a0Smatt * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
69290a34a0Smatt * POSSIBILITY OF SUCH DAMAGE.
70290a34a0Smatt */
71290a34a0Smatt
72290a34a0Smatt /*-
73290a34a0Smatt * Copyright (c) 1991 The Regents of the University of California.
74290a34a0Smatt * All rights reserved.
75290a34a0Smatt *
76290a34a0Smatt * Redistribution and use in source and binary forms, with or without
77290a34a0Smatt * modification, are permitted provided that the following conditions
78290a34a0Smatt * are met:
79290a34a0Smatt * 1. Redistributions of source code must retain the above copyright
80290a34a0Smatt * notice, this list of conditions and the following disclaimer.
81290a34a0Smatt * 2. Redistributions in binary form must reproduce the above copyright
82290a34a0Smatt * notice, this list of conditions and the following disclaimer in the
83290a34a0Smatt * documentation and/or other materials provided with the distribution.
84290a34a0Smatt * 3. Neither the name of the University nor the names of its contributors
85290a34a0Smatt * may be used to endorse or promote products derived from this software
86290a34a0Smatt * without specific prior written permission.
87290a34a0Smatt *
88290a34a0Smatt * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
89290a34a0Smatt * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
90290a34a0Smatt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
91290a34a0Smatt * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
92290a34a0Smatt * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
93290a34a0Smatt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
94290a34a0Smatt * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
95290a34a0Smatt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
96290a34a0Smatt * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
97290a34a0Smatt * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
98290a34a0Smatt * SUCH DAMAGE.
99290a34a0Smatt *
100290a34a0Smatt * @(#)com.c 7.5 (Berkeley) 5/16/91
101290a34a0Smatt */
102290a34a0Smatt
103290a34a0Smatt #include <sys/cdefs.h>
104*f5ab653cSthorpej __KERNEL_RCSID(0, "$NetBSD: rmixl_com.c,v 1.8 2018/12/11 06:34:00 thorpej Exp $");
105290a34a0Smatt
106290a34a0Smatt #include <sys/param.h>
107290a34a0Smatt #include <sys/systm.h>
108290a34a0Smatt #include <sys/device.h>
109290a34a0Smatt #include <sys/kernel.h>
110290a34a0Smatt #include <sys/termios.h>
111290a34a0Smatt #include <sys/ttydefaults.h>
112290a34a0Smatt #include <sys/types.h>
113290a34a0Smatt
114cf10107dSdyoung #include <sys/bus.h>
115290a34a0Smatt
116290a34a0Smatt #include <dev/cons.h>
117290a34a0Smatt #include <dev/ic/comreg.h>
118290a34a0Smatt #include <dev/ic/comvar.h>
119290a34a0Smatt
120290a34a0Smatt #include <mips/cpuregs.h>
121290a34a0Smatt
1223e67b512Smatt #include <mips/rmi/rmixlvar.h>
1233e67b512Smatt #include <mips/rmi/rmixl_intr.h>
124290a34a0Smatt #include <mips/rmi/rmixl_obiovar.h>
125290a34a0Smatt #include <mips/rmi/rmixl_comvar.h>
126290a34a0Smatt
1273e67b512Smatt /* span of UART regs in bytes */
1283e67b512Smatt #define RMIXL_IO_DEV_UART_SIZE (COM_NPORTS * sizeof(uint32_t))
1293e67b512Smatt
130290a34a0Smatt struct rmixl_com_softc {
131290a34a0Smatt struct com_softc sc_com;
132290a34a0Smatt };
133290a34a0Smatt
1346d487047Sthorpej static void rmixl_com_init_regs(struct com_regs *, bus_space_tag_t,
1356d487047Sthorpej bus_space_handle_t, bus_addr_t);
136290a34a0Smatt static int rmixl_com_match(device_t, cfdata_t , void *);
137290a34a0Smatt static void rmixl_com_attach(device_t, device_t, void *);
138290a34a0Smatt
1393e67b512Smatt CFATTACH_DECL_NEW(com_rmixl, sizeof(struct rmixl_com_softc),
140290a34a0Smatt rmixl_com_match, rmixl_com_attach, NULL, NULL);
141290a34a0Smatt
1423e67b512Smatt volatile int32_t *com0addr = (int32_t *)
143290a34a0Smatt MIPS_PHYS_TO_KSEG1(RMIXL_IO_DEV_PBASE + RMIXL_IO_DEV_UART_1);
144290a34a0Smatt
1453e67b512Smatt extern int comcnfreq;
1463e67b512Smatt extern int comcnspeed;
1473e67b512Smatt
148290a34a0Smatt void
rmixl_putchar_init(uint64_t io_pbase)149290a34a0Smatt rmixl_putchar_init(uint64_t io_pbase)
150290a34a0Smatt {
151290a34a0Smatt int rate;
152290a34a0Smatt extern int comspeed(long, long, int);
153290a34a0Smatt
154290a34a0Smatt com0addr = (uint32_t *)
155290a34a0Smatt MIPS_PHYS_TO_KSEG1(io_pbase + RMIXL_IO_DEV_UART_1);
156290a34a0Smatt
1573e67b512Smatt if (comcnfreq != -1) {
1583e67b512Smatt rate = comspeed(comcnspeed, comcnfreq, COM_TYPE_NORMAL);
159290a34a0Smatt if (rate < 0)
160290a34a0Smatt return; /* XXX */
161290a34a0Smatt
162290a34a0Smatt com0addr[com_ier] = 0;
163290a34a0Smatt com0addr[com_lctl] = htobe32(LCR_DLAB);
164290a34a0Smatt com0addr[com_dlbl] = htobe32(rate & 0xff);
165290a34a0Smatt com0addr[com_dlbh] = htobe32(rate >> 8);
166290a34a0Smatt com0addr[com_lctl] = htobe32(LCR_8BITS); /* XXX */
167290a34a0Smatt com0addr[com_mcr] = htobe32(MCR_DTR|MCR_RTS);
168290a34a0Smatt com0addr[com_fifo] = htobe32(
169290a34a0Smatt FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_1);
170290a34a0Smatt }
171290a34a0Smatt }
172290a34a0Smatt
173290a34a0Smatt
174290a34a0Smatt void
rmixl_putchar(char c)175290a34a0Smatt rmixl_putchar(char c)
176290a34a0Smatt {
177290a34a0Smatt int timo = 150000;
178290a34a0Smatt
179290a34a0Smatt while ((be32toh(com0addr[com_lsr]) & LSR_TXRDY) == 0)
180290a34a0Smatt if (--timo == 0)
181290a34a0Smatt break;
182290a34a0Smatt
183290a34a0Smatt com0addr[com_data] = htobe32((uint32_t)c);
184290a34a0Smatt
185290a34a0Smatt while ((be32toh(com0addr[com_lsr]) & LSR_TSRE) == 0)
186290a34a0Smatt if (--timo == 0)
187290a34a0Smatt break;
188290a34a0Smatt }
189290a34a0Smatt
190290a34a0Smatt void
rmixl_puts(const char * restrict s)191290a34a0Smatt rmixl_puts(const char *restrict s)
192290a34a0Smatt {
193290a34a0Smatt char c;
194290a34a0Smatt
195290a34a0Smatt while ((c = *s++) != 0)
196290a34a0Smatt rmixl_putchar(c);
197290a34a0Smatt }
198290a34a0Smatt
199290a34a0Smatt static char hexc[] = "0123456789abcdef";
200290a34a0Smatt
201290a34a0Smatt #define RMIXL_PUTHEX \
202290a34a0Smatt u_int shift = sizeof(val) * 8; \
203290a34a0Smatt rmixl_putchar('0'); \
204290a34a0Smatt rmixl_putchar('x'); \
205290a34a0Smatt do { \
206290a34a0Smatt shift -= 4; \
207290a34a0Smatt rmixl_putchar(hexc[(val >> shift) & 0xf]); \
208290a34a0Smatt } while(shift != 0)
209290a34a0Smatt
210290a34a0Smatt void
rmixl_puthex32(uint32_t val)211290a34a0Smatt rmixl_puthex32(uint32_t val)
212290a34a0Smatt {
213290a34a0Smatt RMIXL_PUTHEX;
214290a34a0Smatt }
215290a34a0Smatt
216290a34a0Smatt void
rmixl_puthex64(uint64_t val)217290a34a0Smatt rmixl_puthex64(uint64_t val)
218290a34a0Smatt {
219290a34a0Smatt RMIXL_PUTHEX;
220290a34a0Smatt }
221290a34a0Smatt
222290a34a0Smatt int
rmixl_com_match(device_t parent,cfdata_t cf,void * aux)223290a34a0Smatt rmixl_com_match(device_t parent, cfdata_t cf, void *aux)
224290a34a0Smatt {
225290a34a0Smatt struct obio_attach_args *obio = aux;
226290a34a0Smatt bus_space_tag_t bst;
2273e67b512Smatt bus_space_handle_t ioh;
228290a34a0Smatt bus_addr_t addr;
229290a34a0Smatt bus_size_t size;
230290a34a0Smatt struct com_regs regs;
231290a34a0Smatt int rv;
232290a34a0Smatt
2333e67b512Smatt bst = obio->obio_eb_bst;
234290a34a0Smatt addr = obio->obio_addr;
2353e67b512Smatt size = (bus_size_t)RMIXL_IO_DEV_UART_SIZE;
236290a34a0Smatt
237290a34a0Smatt if (com_is_console(bst, addr, ®s.cr_ioh))
238290a34a0Smatt return 1;
239290a34a0Smatt
2403e67b512Smatt if (bus_space_map(bst, addr, size, 0, &ioh))
241290a34a0Smatt return 0; /* FAIL */
242290a34a0Smatt
2436d487047Sthorpej rmixl_com_init_regs(®s, bst, ioh, addr);
244290a34a0Smatt
245290a34a0Smatt rv = com_probe_subr(®s);
246290a34a0Smatt
2473e67b512Smatt bus_space_unmap(bst, ioh, size);
248290a34a0Smatt
249290a34a0Smatt return rv;
250290a34a0Smatt }
251290a34a0Smatt
252290a34a0Smatt void
rmixl_com_attach(device_t parent,device_t self,void * aux)253290a34a0Smatt rmixl_com_attach(device_t parent, device_t self, void *aux)
254290a34a0Smatt {
255290a34a0Smatt struct rmixl_com_softc *rsc = device_private(self);
256290a34a0Smatt struct com_softc *sc = &rsc->sc_com;
257290a34a0Smatt struct obio_attach_args *obio = aux;
258290a34a0Smatt bus_space_tag_t bst;
259290a34a0Smatt bus_space_handle_t ioh;
260290a34a0Smatt bus_addr_t addr;
261290a34a0Smatt bus_size_t size;
262290a34a0Smatt
263290a34a0Smatt sc->sc_dev = self;
2643e67b512Smatt sc->sc_frequency = comcnfreq;
265290a34a0Smatt
2663e67b512Smatt bst = obio->obio_eb_bst;
267290a34a0Smatt addr = obio->obio_addr;
2683e67b512Smatt size = (bus_size_t)RMIXL_IO_DEV_UART_SIZE;
269290a34a0Smatt
270290a34a0Smatt if (!com_is_console(bst, addr, &ioh)
271290a34a0Smatt && bus_space_map(bst, addr, size, 0, &ioh) != 0) {
272290a34a0Smatt aprint_error(": can't map registers\n");
273290a34a0Smatt return;
274290a34a0Smatt }
275290a34a0Smatt
2766d487047Sthorpej rmixl_com_init_regs(&sc->sc_regs, bst, ioh, addr);
277290a34a0Smatt
278290a34a0Smatt com_attach_subr(sc);
279290a34a0Smatt
2803e67b512Smatt rmixl_intr_establish(obio->obio_intr, obio->obio_tmsk,
2813e67b512Smatt IPL_VM, RMIXL_TRIG_LEVEL, RMIXL_POLR_HIGH,
2823e67b512Smatt comintr, sc, true);
283290a34a0Smatt
284290a34a0Smatt }
285290a34a0Smatt
286290a34a0Smatt void
rmixl_com_init_regs(struct com_regs * regsp,bus_space_tag_t st,bus_space_handle_t sh,bus_addr_t addr)2876d487047Sthorpej rmixl_com_init_regs(struct com_regs *regsp, bus_space_tag_t st,
2886d487047Sthorpej bus_space_handle_t sh, bus_addr_t addr)
289290a34a0Smatt {
2906d487047Sthorpej
291*f5ab653cSthorpej com_init_regs_stride(regsp, st, sh, addr, 2);
292290a34a0Smatt }
293290a34a0Smatt
294290a34a0Smatt void
rmixl_com_cnattach(bus_addr_t addr,int speed,int freq,int type,tcflag_t mode)295290a34a0Smatt rmixl_com_cnattach(bus_addr_t addr, int speed, int freq,
296290a34a0Smatt int type, tcflag_t mode)
297290a34a0Smatt {
298290a34a0Smatt bus_space_tag_t bst;
299290a34a0Smatt struct com_regs regs;
300290a34a0Smatt
3013e67b512Smatt bst = (bus_space_tag_t)&rmixl_configuration.rc_obio_eb_memt;
302290a34a0Smatt
3036d487047Sthorpej rmixl_com_init_regs(®s, bst, 0, addr);
304290a34a0Smatt
305290a34a0Smatt comcnattach1(®s, speed, freq, type, mode);
306290a34a0Smatt }
307