1 /* $NetBSD: ralink_com.c,v 1.9 2019/01/12 15:44:08 thorpej 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.9 2019/01/12 15:44:08 thorpej 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 struct ralink_com_softc { 155 struct com_softc sc_com; 156 void *sc_ih; 157 bus_addr_t sc_addr; 158 int sc_irq; 159 }; 160 161 static int ralink_com_match(device_t, cfdata_t , void *); 162 static void ralink_com_attach(device_t, device_t, void *); 163 static void ralink_com_init_regs(struct com_regs *regsp, bus_space_tag_t, 164 bus_space_handle_t, bus_addr_t); 165 166 CFATTACH_DECL_NEW(ralink_com, sizeof(struct ralink_com_softc), 167 ralink_com_match, ralink_com_attach, NULL, NULL); 168 169 #define CONMODE \ 170 ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */ 171 172 #ifndef RALINK_CONADDR 173 #define RALINK_CONADDR RA_UART_LITE_BASE /* default console is UART_LITE */ 174 #endif 175 176 /* address/irq/rst/gpiomode mappings */ 177 static struct { 178 bus_addr_t addr; 179 int irq; 180 uint32_t rst; 181 uint32_t gpiomode; 182 } ralink_uart_maps[] = { 183 #ifdef MT7628 184 { RA_UART_LITE_BASE, RA_IRQ_UARTL, RST_UART0_7628, GPIO1MODE_UART0 }, 185 { RA_UART1_BASE, RA_IRQ_UART1, RST_UART1_7628, GPIO1MODE_UART1 }, 186 { RA_UART2_BASE, RA_IRQ_UART2, RST_UART2_7628, GPIO1MODE_UART2 }, 187 #else 188 { RA_UART_BASE, RA_IRQ_UARTF, RST_UART, GPIOMODE_UARTF0 }, 189 { RA_UART_LITE_BASE, RA_IRQ_UARTL, RST_UARTL, GPIOMODE_UARTL } 190 #endif 191 }; 192 193 static inline int 194 ra_uart2irq(bus_addr_t addr) 195 { 196 int i; 197 for (i = 0; __arraycount(ralink_uart_maps); i++) 198 if (ralink_uart_maps[i].addr == addr) 199 return ralink_uart_maps[i].irq; 200 return -1; 201 } 202 203 static inline uint32_t 204 ra_uart2rst(bus_addr_t addr) 205 { 206 int i; 207 for (i = 0; __arraycount(ralink_uart_maps); i++) 208 if (ralink_uart_maps[i].addr == addr) 209 return ralink_uart_maps[i].rst; 210 return 0; 211 } 212 213 static inline uint32_t 214 ra_uart2gpiomode(bus_addr_t addr) 215 { 216 int i; 217 for (i = 0; __arraycount(ralink_uart_maps); i++) 218 if (ralink_uart_maps[i].addr == addr) 219 return ralink_uart_maps[i].gpiomode; 220 return 0; 221 } 222 223 static inline uint32_t 224 sysctl_read(const u_int offset) 225 { 226 return *RA_IOREG_VADDR(RA_SYSCTL_BASE, offset); 227 } 228 229 static inline void 230 sysctl_write(const u_int offset, uint32_t val) 231 { 232 *RA_IOREG_VADDR(RA_SYSCTL_BASE, offset) = val; 233 } 234 235 static inline uint32_t 236 uart_read(const u_int offset) 237 { 238 return *RA_IOREG_VADDR(RALINK_CONADDR, offset); 239 } 240 241 static inline void 242 uart_write(const u_int offset, const uint32_t val) 243 { 244 *RA_IOREG_VADDR(RALINK_CONADDR, offset) = val; 245 } 246 247 #ifdef RALINK_CONSOLE_EARLY 248 static int 249 ralink_cngetc(dev_t dv) 250 { 251 if ((uart_read(RA_UART_LSR) & LSR_RXRDY) == 0) 252 return -1; 253 254 return uart_read(RA_UART_RBR) & 0xff; 255 } 256 257 static void 258 ralink_cnputc(dev_t dv, int c) 259 { 260 int timo = 150000; 261 262 while ((uart_read(RA_UART_LSR) & LSR_TXRDY) == 0 && --timo > 0) 263 ; 264 265 uart_write(RA_UART_TBR, c); 266 __asm __volatile("sync"); 267 268 timo = 150000; 269 while ((uart_read(RA_UART_LSR) & LSR_TSRE) == 0 && --timo > 0) 270 ; 271 } 272 273 static struct consdev ralink_earlycons = { 274 .cn_putc = ralink_cnputc, 275 .cn_getc = ralink_cngetc, 276 .cn_pollc = nullcnpollc, 277 }; 278 279 void 280 ralink_console_early(void) 281 { 282 cn_tab = &ralink_earlycons; 283 } 284 #endif /* RALINK_CONSOLE_EARLY */ 285 286 287 int 288 ralink_com_match(device_t parent, cfdata_t cf, void *aux) 289 { 290 const struct mainbus_attach_args *ma; 291 bus_addr_t addr; 292 293 ma = aux; 294 addr = ma->ma_addr; 295 if (addr == MAINBUSCF_ADDR_DEFAULT) 296 addr = RA_UART_LITE_BASE; 297 298 if (ra_uart2irq(addr) < 0) 299 return 0; 300 301 if (cn_tab == NULL || cn_tab->cn_pri < CN_NORMAL) { 302 printf("NULL console set, don't install ourselves " 303 "(of course this shouldn't print)"); 304 return 0; 305 } 306 307 /* 308 * If we got this far, assume we want to install it as the console. 309 * No need to probe. Future possibilities include checking to see if it 310 * is console or KGDB but now it is our only console method if we aren't 311 * forcing a null console 312 */ 313 return 1; 314 } 315 316 void 317 ralink_com_attach(device_t parent, device_t self, void *aux) 318 { 319 const struct mainbus_attach_args *ma = aux; 320 struct ralink_com_softc * const rtsc = device_private(self); 321 struct com_softc * const sc = &rtsc->sc_com; 322 bus_space_handle_t ioh; 323 int error; 324 325 /* opt addr and irq */ 326 rtsc->sc_addr = ma->ma_addr; 327 if (rtsc->sc_addr == MAINBUSCF_ADDR_DEFAULT) 328 rtsc->sc_addr = RA_UART_LITE_BASE; 329 rtsc->sc_irq = ra_uart2irq(rtsc->sc_addr); 330 331 if ((error = bus_space_map(ma->ma_memt, rtsc->sc_addr, 332 RA_UART_SIZE, 0, &ioh)) != 0) { 333 aprint_error(": can't map registers, error=%d\n", error); 334 return; 335 } 336 337 sc->sc_dev = self; 338 sc->sc_frequency = RA_UART_FREQ; 339 #if defined(MT7628) 340 sc->sc_type = COM_TYPE_NORMAL; 341 #else 342 sc->sc_type = COM_TYPE_AU1x00; 343 #endif 344 sc->enabled = 1; 345 346 /* reset hardware if not a console */ 347 if (rtsc->sc_addr != RALINK_CONADDR) { 348 uint32_t r; 349 350 /* reset */ 351 r = sysctl_read(RA_SYSCTL_RST); 352 r |= ra_uart2rst(rtsc->sc_addr); 353 sysctl_write(RA_SYSCTL_RST, r); 354 r ^= ra_uart2rst(rtsc->sc_addr); 355 sysctl_write(RA_SYSCTL_RST, r); 356 357 /* make sure we are in UART mode */ 358 r = sysctl_read(RA_SYSCTL_GPIOMODE); 359 r &= ra_uart2gpiomode(rtsc->sc_addr); 360 r |= __SHIFTIN(0, ra_uart2gpiomode(rtsc->sc_addr)); 361 sysctl_write(RA_SYSCTL_GPIOMODE, r); 362 } 363 364 ralink_com_init_regs(&sc->sc_regs, ma->ma_memt, ioh, rtsc->sc_addr); 365 366 rtsc->sc_ih = ra_intr_establish(rtsc->sc_irq, comintr, sc, 1); 367 com_attach_subr(sc); 368 } 369 370 static const bus_size_t ralink_com_regmap[COM_REGMAP_NENTRIES] = { 371 [COM_REG_RXDATA] = RA_UART_RBR, 372 [COM_REG_TXDATA] = RA_UART_TBR, 373 [COM_REG_DLBL] = RA_UART_DLL, 374 #if defined(MT7628) 375 [COM_REG_DLBH] = RA_UART_DLM, 376 #endif 377 [COM_REG_IER] = RA_UART_IER, 378 [COM_REG_IIR] = RA_UART_IIR, 379 [COM_REG_FIFO] = RA_UART_FCR, 380 [COM_REG_TCR] = RA_UART_FCR, 381 [COM_REG_LCR] = RA_UART_LCR, 382 [COM_REG_MCR] = RA_UART_MCR, 383 [COM_REG_LSR] = RA_UART_LSR, 384 [COM_REG_MSR] = RA_UART_MSR, 385 }; 386 387 static void 388 ralink_com_init_regs(struct com_regs *regsp, bus_space_tag_t st, 389 bus_space_handle_t sh, bus_addr_t addr) 390 { 391 392 com_init_regs(regsp, st, sh, addr); 393 394 memcpy(regsp->cr_map, ralink_com_regmap, sizeof(regsp->cr_map)); 395 regsp->cr_nports = 32; 396 } 397 398 void 399 ralink_com_early(int silent) 400 { 401 struct com_regs regs; 402 bus_space_handle_t bsh; 403 uint32_t r; 404 int error; 405 406 /* reset */ 407 r = sysctl_read(RA_SYSCTL_RST); 408 r |= ra_uart2rst(RALINK_CONADDR); 409 sysctl_write(RA_SYSCTL_RST, r); 410 r ^= ra_uart2rst(RALINK_CONADDR); 411 sysctl_write(RA_SYSCTL_RST, r); 412 413 if (silent) { 414 /* 415 * put us in PIO mode, 416 * effectively tri-stating the UARTL block 417 */ 418 r = sysctl_read(RA_SYSCTL_GPIOMODE); 419 r &= ra_uart2gpiomode(RALINK_CONADDR); 420 r |= __SHIFTIN(1, ra_uart2gpiomode(RALINK_CONADDR)); 421 sysctl_write(RA_SYSCTL_GPIOMODE, r); 422 } else { 423 /* make sure we are in UART mode */ 424 r = sysctl_read(RA_SYSCTL_GPIOMODE); 425 r &= ra_uart2gpiomode(RALINK_CONADDR); 426 r |= __SHIFTIN(0, ra_uart2gpiomode(RALINK_CONADDR)); 427 sysctl_write(RA_SYSCTL_GPIOMODE, r); 428 } 429 430 uart_write(RA_UART_IER, 0); /* disable interrupts */ 431 uart_write(RA_UART_FCR, 0); /* disable fifos */ 432 433 /* set baud rate */ 434 uart_write(RA_UART_LCR, 435 UART_LCR_WLS0 | UART_LCR_WLS1 | UART_LCR_DLAB); 436 uart_write(RA_UART_DLL, 437 (RA_UART_FREQ / RA_SERIAL_CLKDIV / RA_BAUDRATE) & 0xffff); 438 #if defined(MT7628) 439 uart_write(RA_UART_DLM, 440 ((RA_UART_FREQ / RA_SERIAL_CLKDIV / RA_BAUDRATE) & 0xffff) >> 8); 441 #endif 442 uart_write(RA_UART_LCR, UART_LCR_WLS0 | UART_LCR_WLS1); 443 444 if ((error = bus_space_map(&ra_bus_memt, RALINK_CONADDR, 445 32, 0, &bsh)) != 0) { 446 return; 447 } 448 ralink_com_init_regs(®s, &ra_bus_memt, bsh, RALINK_CONADDR); 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