1 /* $Id: rmixl_com.c,v 1.5 2011/07/01 19:01:30 dyoung Exp $ */ 2 /*- 3 * Copyright (c) 2006 Urbana-Champaign Independent Media Center. 4 * Copyright (c) 2006 Garrett D'Amore. 5 * All rights reserved. 6 * 7 * Portions of this code were written by Garrett D'Amore for the 8 * Champaign-Urbana Community Wireless Network Project. 9 * 10 * Redistribution and use in source and binary forms, with or 11 * without modification, are permitted provided that the following 12 * conditions are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above 16 * copyright notice, this list of conditions and the following 17 * disclaimer in the documentation and/or other materials provided 18 * with the distribution. 19 * 3. All advertising materials mentioning features or use of this 20 * software must display the following acknowledgements: 21 * This product includes software developed by the Urbana-Champaign 22 * Independent Media Center. 23 * This product includes software developed by Garrett D'Amore. 24 * 4. Urbana-Champaign Independent Media Center's name and Garrett 25 * D'Amore's name may not be used to endorse or promote products 26 * derived from this software without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE URBANA-CHAMPAIGN INDEPENDENT 29 * MEDIA CENTER AND GARRETT D'AMORE ``AS IS'' AND ANY EXPRESS OR 30 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 31 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 32 * ARE DISCLAIMED. IN NO EVENT SHALL THE URBANA-CHAMPAIGN INDEPENDENT 33 * MEDIA CENTER OR GARRETT D'AMORE BE LIABLE FOR ANY DIRECT, INDIRECT, 34 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 35 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 36 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 37 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 38 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 39 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 40 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 41 */ 42 43 /*- 44 * Copyright (c) 1998 The NetBSD Foundation, Inc. 45 * All rights reserved. 46 * 47 * This code is derived from software contributed to The NetBSD Foundation 48 * by Charles M. Hannum. 49 * 50 * Redistribution and use in source and binary forms, with or without 51 * modification, are permitted provided that the following conditions 52 * are met: 53 * 1. Redistributions of source code must retain the above copyright 54 * notice, this list of conditions and the following disclaimer. 55 * 2. Redistributions in binary form must reproduce the above copyright 56 * notice, this list of conditions and the following disclaimer in the 57 * documentation and/or other materials provided with the distribution. 58 * 59 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 60 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 61 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 62 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 63 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 64 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 65 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 66 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 67 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 68 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 69 * POSSIBILITY OF SUCH DAMAGE. 70 */ 71 72 /*- 73 * Copyright (c) 1991 The Regents of the University of California. 74 * All rights reserved. 75 * 76 * Redistribution and use in source and binary forms, with or without 77 * modification, are permitted provided that the following conditions 78 * are met: 79 * 1. Redistributions of source code must retain the above copyright 80 * notice, this list of conditions and the following disclaimer. 81 * 2. Redistributions in binary form must reproduce the above copyright 82 * notice, this list of conditions and the following disclaimer in the 83 * documentation and/or other materials provided with the distribution. 84 * 3. Neither the name of the University nor the names of its contributors 85 * may be used to endorse or promote products derived from this software 86 * without specific prior written permission. 87 * 88 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 89 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 90 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 91 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 92 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 93 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 94 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 95 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 96 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 97 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 98 * SUCH DAMAGE. 99 * 100 * @(#)com.c 7.5 (Berkeley) 5/16/91 101 */ 102 103 #include <sys/cdefs.h> 104 __KERNEL_RCSID(0, "$NetBSD: rmixl_com.c,v 1.5 2011/07/01 19:01:30 dyoung Exp $"); 105 106 #include <sys/param.h> 107 #include <sys/systm.h> 108 #include <sys/device.h> 109 #include <sys/kernel.h> 110 #include <sys/termios.h> 111 #include <sys/ttydefaults.h> 112 #include <sys/types.h> 113 114 #include <sys/bus.h> 115 116 #include <dev/cons.h> 117 #include <dev/ic/comreg.h> 118 #include <dev/ic/comvar.h> 119 120 #include <mips/cpuregs.h> 121 122 #include <mips/rmi/rmixlvar.h> 123 #include <mips/rmi/rmixl_intr.h> 124 #include <mips/rmi/rmixl_obiovar.h> 125 #include <mips/rmi/rmixl_comvar.h> 126 127 #include "opt_com.h" 128 129 /* span of UART regs in bytes */ 130 #define RMIXL_IO_DEV_UART_SIZE (COM_NPORTS * sizeof(uint32_t)) 131 132 #define RMIXL_COM_INIT_REGS(regs, bst, ioh, addr) \ 133 do { \ 134 memset(®s, 0, sizeof(regs)); \ 135 COM_INIT_REGS(regs, bst, ioh, addr); \ 136 regs.cr_nports = RMIXL_IO_DEV_UART_SIZE; \ 137 rmixl_com_initmap(®s); \ 138 } while (0) 139 140 141 struct rmixl_com_softc { 142 struct com_softc sc_com; 143 }; 144 145 static void rmixl_com_initmap(struct com_regs *); 146 static int rmixl_com_match(device_t, cfdata_t , void *); 147 static void rmixl_com_attach(device_t, device_t, void *); 148 149 CFATTACH_DECL_NEW(com_rmixl, sizeof(struct rmixl_com_softc), 150 rmixl_com_match, rmixl_com_attach, NULL, NULL); 151 152 #ifndef COM_REGMAP 153 #error COM_REGMAP not defined! 154 #endif 155 156 volatile int32_t *com0addr = (int32_t *) 157 MIPS_PHYS_TO_KSEG1(RMIXL_IO_DEV_PBASE + RMIXL_IO_DEV_UART_1); 158 159 extern int comcnfreq; 160 extern int comcnspeed; 161 162 void 163 rmixl_putchar_init(uint64_t io_pbase) 164 { 165 int rate; 166 extern int comspeed(long, long, int); 167 168 com0addr = (uint32_t *) 169 MIPS_PHYS_TO_KSEG1(io_pbase + RMIXL_IO_DEV_UART_1); 170 171 if (comcnfreq != -1) { 172 rate = comspeed(comcnspeed, comcnfreq, COM_TYPE_NORMAL); 173 if (rate < 0) 174 return; /* XXX */ 175 176 com0addr[com_ier] = 0; 177 com0addr[com_lctl] = htobe32(LCR_DLAB); 178 com0addr[com_dlbl] = htobe32(rate & 0xff); 179 com0addr[com_dlbh] = htobe32(rate >> 8); 180 com0addr[com_lctl] = htobe32(LCR_8BITS); /* XXX */ 181 com0addr[com_mcr] = htobe32(MCR_DTR|MCR_RTS); 182 com0addr[com_fifo] = htobe32( 183 FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_1); 184 } 185 } 186 187 188 void 189 rmixl_putchar(char c) 190 { 191 int timo = 150000; 192 193 while ((be32toh(com0addr[com_lsr]) & LSR_TXRDY) == 0) 194 if (--timo == 0) 195 break; 196 197 com0addr[com_data] = htobe32((uint32_t)c); 198 199 while ((be32toh(com0addr[com_lsr]) & LSR_TSRE) == 0) 200 if (--timo == 0) 201 break; 202 } 203 204 void 205 rmixl_puts(const char *restrict s) 206 { 207 char c; 208 209 while ((c = *s++) != 0) 210 rmixl_putchar(c); 211 } 212 213 static char hexc[] = "0123456789abcdef"; 214 215 #define RMIXL_PUTHEX \ 216 u_int shift = sizeof(val) * 8; \ 217 rmixl_putchar('0'); \ 218 rmixl_putchar('x'); \ 219 do { \ 220 shift -= 4; \ 221 rmixl_putchar(hexc[(val >> shift) & 0xf]); \ 222 } while(shift != 0) 223 224 void 225 rmixl_puthex32(uint32_t val) 226 { 227 RMIXL_PUTHEX; 228 } 229 230 void 231 rmixl_puthex64(uint64_t val) 232 { 233 RMIXL_PUTHEX; 234 } 235 236 int 237 rmixl_com_match(device_t parent, cfdata_t cf, void *aux) 238 { 239 struct obio_attach_args *obio = aux; 240 bus_space_tag_t bst; 241 bus_space_handle_t ioh; 242 bus_addr_t addr; 243 bus_size_t size; 244 struct com_regs regs; 245 int rv; 246 247 bst = obio->obio_eb_bst; 248 addr = obio->obio_addr; 249 size = (bus_size_t)RMIXL_IO_DEV_UART_SIZE; 250 251 if (com_is_console(bst, addr, ®s.cr_ioh)) 252 return 1; 253 254 if (bus_space_map(bst, addr, size, 0, &ioh)) 255 return 0; /* FAIL */ 256 257 RMIXL_COM_INIT_REGS(regs, bst, ioh, addr); 258 259 rv = com_probe_subr(®s); 260 261 bus_space_unmap(bst, ioh, size); 262 263 return rv; 264 } 265 266 void 267 rmixl_com_attach(device_t parent, device_t self, void *aux) 268 { 269 struct rmixl_com_softc *rsc = device_private(self); 270 struct com_softc *sc = &rsc->sc_com; 271 struct obio_attach_args *obio = aux; 272 bus_space_tag_t bst; 273 bus_space_handle_t ioh; 274 bus_addr_t addr; 275 bus_size_t size; 276 277 sc->sc_dev = self; 278 sc->sc_frequency = comcnfreq; 279 280 bst = obio->obio_eb_bst; 281 addr = obio->obio_addr; 282 size = (bus_size_t)RMIXL_IO_DEV_UART_SIZE; 283 284 if (!com_is_console(bst, addr, &ioh) 285 && bus_space_map(bst, addr, size, 0, &ioh) != 0) { 286 aprint_error(": can't map registers\n"); 287 return; 288 } 289 290 RMIXL_COM_INIT_REGS(sc->sc_regs, bst, ioh, addr); 291 292 com_attach_subr(sc); 293 294 rmixl_intr_establish(obio->obio_intr, obio->obio_tmsk, 295 IPL_VM, RMIXL_TRIG_LEVEL, RMIXL_POLR_HIGH, 296 comintr, sc, true); 297 298 } 299 300 void 301 rmixl_com_initmap(struct com_regs *regsp) 302 { 303 /* 304 * map the 4 byte register stride 305 */ 306 for (int i = 0; i < __arraycount(regsp->cr_map); i++) 307 regsp->cr_map[i] = com_std_map[i] * 4; 308 } 309 310 void 311 rmixl_com_cnattach(bus_addr_t addr, int speed, int freq, 312 int type, tcflag_t mode) 313 { 314 bus_space_tag_t bst; 315 struct com_regs regs; 316 317 bst = (bus_space_tag_t)&rmixl_configuration.rc_obio_eb_memt; 318 319 RMIXL_COM_INIT_REGS(regs, bst, 0, addr); 320 321 comcnattach1(®s, speed, freq, type, mode); 322 } 323