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(®s); 444 445 if ((error = bus_space_map(regs.cr_iot, regs.cr_iobase, regs.cr_nports, 446 0, ®s.cr_ioh)) != 0) { 447 return; 448 } 449 450 #if defined(MT7628) 451 comcnattach1(®s, 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(®s, RA_BAUDRATE, RA_UART_FREQ, 456 COM_TYPE_AU1x00, CONMODE); 457 #endif 458 } 459