1 1.3 ryo /* $NetBSD: console.c,v 1.3 2016/10/05 15:54:58 ryo Exp $ */ 2 1.2 matt /*- 3 1.2 matt * Copyright (c) 2011 CradlePoint Technology, Inc. 4 1.2 matt * All rights reserved. 5 1.2 matt * 6 1.2 matt * 7 1.2 matt * Redistribution and use in source and binary forms, with or without 8 1.2 matt * modification, are permitted provided that the following conditions 9 1.2 matt * are met: 10 1.2 matt * 1. Redistributions of source code must retain the above copyright 11 1.2 matt * notice, this list of conditions and the following disclaimer. 12 1.2 matt * 2. Redistributions in binary form must reproduce the above copyright 13 1.2 matt * notice, this list of conditions and the following disclaimer in the 14 1.2 matt * documentation and/or other materials provided with the distribution. 15 1.2 matt * 16 1.2 matt * THIS SOFTWARE IS PROVIDED BY CRADLEPOINT TECHNOLOGY, INC. AND CONTRIBUTORS 17 1.2 matt * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 1.2 matt * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 1.2 matt * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS 20 1.2 matt * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 1.2 matt * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 1.2 matt * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 1.2 matt * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 1.2 matt * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 1.2 matt * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 1.2 matt * POSSIBILITY OF SUCH DAMAGE. 27 1.2 matt */ 28 1.2 matt 29 1.2 matt #include <sys/cdefs.h> 30 1.3 ryo __KERNEL_RCSID(0, "$NetBSD: console.c,v 1.3 2016/10/05 15:54:58 ryo Exp $"); 31 1.2 matt 32 1.2 matt #include <sys/param.h> 33 1.2 matt #include <sys/systm.h> 34 1.2 matt #include <sys/types.h> 35 1.2 matt 36 1.2 matt #include <dev/cons.h> 37 1.2 matt 38 1.2 matt #include <mips/ralink/ralink_reg.h> 39 1.2 matt #include <mips/ralink/ralink_var.h> 40 1.2 matt 41 1.3 ryo #ifndef RALINK_CONADDR 42 1.3 ryo #define RALINK_CONADDR RA_UART_LITE_BASE /* default console is UART_LITE */ 43 1.3 ryo #endif 44 1.2 matt 45 1.2 matt static inline uint32_t 46 1.2 matt sysctl_read(const u_int offset) 47 1.2 matt { 48 1.2 matt return *RA_IOREG_VADDR(RA_SYSCTL_BASE, offset); 49 1.2 matt } 50 1.2 matt 51 1.2 matt static inline void 52 1.2 matt sysctl_write(const u_int offset, uint32_t val) 53 1.2 matt { 54 1.2 matt *RA_IOREG_VADDR(RA_SYSCTL_BASE, offset) = val; 55 1.2 matt } 56 1.2 matt 57 1.2 matt static inline uint32_t 58 1.2 matt uart_read(const u_int offset) 59 1.2 matt { 60 1.3 ryo return *RA_IOREG_VADDR(RALINK_CONADDR, offset); 61 1.2 matt } 62 1.2 matt 63 1.2 matt static inline void 64 1.2 matt uart_write(const u_int offset, const uint32_t val) 65 1.2 matt { 66 1.3 ryo *RA_IOREG_VADDR(RALINK_CONADDR, offset) = val; 67 1.2 matt } 68 1.2 matt 69 1.2 matt #ifdef RA_CONSOLE_EARLY 70 1.2 matt static void 71 1.2 matt ra_console_putc(dev_t dev, int c) 72 1.2 matt { 73 1.2 matt u_int timo; 74 1.2 matt 75 1.2 matt timo = 150000; 76 1.2 matt do { 77 1.2 matt if ((uart_read(RA_UART_LSR) & UART_LSR_TDRQ) != 0) 78 1.2 matt break; 79 1.2 matt } while(--timo != 0); 80 1.2 matt 81 1.2 matt uart_write(RA_UART_TBR, c); 82 1.2 matt if (c == '\n') 83 1.2 matt ra_console_putc (dev, '\r'); 84 1.2 matt #if 1 85 1.2 matt timo = 150000; 86 1.2 matt do { 87 1.2 matt if ((uart_read(RA_UART_LSR) & UART_LSR_TEMT) != 0) 88 1.2 matt break; 89 1.2 matt } while(--timo != 0); 90 1.2 matt #endif 91 1.2 matt } 92 1.2 matt 93 1.2 matt static int 94 1.2 matt ra_console_getc(dev_t dev) 95 1.2 matt { 96 1.2 matt while ((uart_read(RA_UART_LSR) & UART_LSR_DR) == 0) 97 1.2 matt ; 98 1.2 matt return (char)(uart_read(RA_UART_RBR) & 0xff); 99 1.2 matt } 100 1.2 matt 101 1.2 matt static void 102 1.2 matt ra_console_flush(dev_t dev) 103 1.2 matt { 104 1.2 matt while ((uart_read(RA_UART_LSR) & UART_LSR_TEMT) == 0) 105 1.2 matt ; 106 1.2 matt } 107 1.2 matt 108 1.2 matt void 109 1.2 matt ra_console_early(void) 110 1.2 matt { 111 1.2 matt uint32_t r; 112 1.2 matt 113 1.2 matt /* reset */ 114 1.2 matt r = sysctl_read(RA_SYSCTL_RST); 115 1.2 matt r |= RST_UARTL; 116 1.2 matt sysctl_write(RA_SYSCTL_RST, r); 117 1.2 matt r ^= RST_UARTL; 118 1.2 matt sysctl_write(RA_SYSCTL_RST, r); 119 1.2 matt 120 1.2 matt /* make sure we are in UART mode */ 121 1.2 matt r = sysctl_read(RA_SYSCTL_GPIOMODE); 122 1.2 matt r &= ~GPIOMODE_UARTL; 123 1.2 matt sysctl_write(RA_SYSCTL_GPIOMODE, r); 124 1.2 matt 125 1.2 matt uart_write(RA_UART_IER, 0); /* disable interrupts */ 126 1.2 matt uart_write(RA_UART_FCR, 0); /* disable fifos */ 127 1.2 matt 128 1.2 matt /* set baud rate */ 129 1.2 matt uart_write(RA_UART_LCR, 130 1.2 matt UART_LCR_WLS0 | UART_LCR_WLS1 | UART_LCR_DLAB); 131 1.2 matt uart_write(RA_UART_DLL, 132 1.2 matt (RA_UART_FREQ / RA_SERIAL_CLKDIV / RA_BAUDRATE) 133 1.2 matt & 0xffff); 134 1.2 matt uart_write(RA_UART_LCR, 135 1.2 matt UART_LCR_WLS0 | UART_LCR_WLS1); 136 1.2 matt 137 1.2 matt static struct consdev lite_cn = { 138 1.2 matt .cn_probe = NULL, 139 1.2 matt .cn_init = NULL, 140 1.2 matt .cn_getc = ra_console_getc, 141 1.2 matt .cn_putc = ra_console_putc, 142 1.2 matt .cn_pollc = nullcnpollc, 143 1.2 matt .cn_bell = NULL, 144 1.2 matt .cn_halt = NULL, 145 1.2 matt .cn_flush = ra_console_flush, 146 1.2 matt .cn_dev = makedev(0, 0), 147 1.2 matt .cn_pri = CN_DEAD, 148 1.2 matt }; 149 1.2 matt 150 1.2 matt cn_tab = &lite_cn; 151 1.2 matt 152 1.2 matt } 153 1.2 matt #endif /* RA_CONSOLE_EARLY */ 154 1.2 matt 155 1.2 matt void 156 1.2 matt consinit(void) 157 1.2 matt { 158 1.2 matt if (ra_check_memo_reg(SERIAL_CONSOLE)) { 159 1.2 matt ralink_com_early(0); 160 1.2 matt printf("Enabled early console\n"); 161 1.2 matt } else { 162 1.2 matt /* 163 1.2 matt * this should be OK, but our shell configuration doesn't seem 164 1.2 matt * to be working, so create a silent console 165 1.2 matt */ 166 1.2 matt cn_tab = NULL; 167 1.2 matt ralink_com_early(1); 168 1.2 matt printf("Enabled silent console\n"); 169 1.2 matt } 170 1.2 matt 171 1.2 matt #if 0 172 1.2 matt /* update ddb escape sequence to '~~' to avoid the undocking issue */ 173 1.2 matt cn_set_magic("\x7E\x7E"); 174 1.2 matt #endif 175 1.2 matt } 176