1 /* $NetBSD: console.c,v 1.3 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 #include <sys/cdefs.h> 30 __KERNEL_RCSID(0, "$NetBSD: console.c,v 1.3 2016/10/05 15:54:58 ryo Exp $"); 31 32 #include <sys/param.h> 33 #include <sys/systm.h> 34 #include <sys/types.h> 35 36 #include <dev/cons.h> 37 38 #include <mips/ralink/ralink_reg.h> 39 #include <mips/ralink/ralink_var.h> 40 41 #ifndef RALINK_CONADDR 42 #define RALINK_CONADDR RA_UART_LITE_BASE /* default console is UART_LITE */ 43 #endif 44 45 static inline uint32_t 46 sysctl_read(const u_int offset) 47 { 48 return *RA_IOREG_VADDR(RA_SYSCTL_BASE, offset); 49 } 50 51 static inline void 52 sysctl_write(const u_int offset, uint32_t val) 53 { 54 *RA_IOREG_VADDR(RA_SYSCTL_BASE, offset) = val; 55 } 56 57 static inline uint32_t 58 uart_read(const u_int offset) 59 { 60 return *RA_IOREG_VADDR(RALINK_CONADDR, offset); 61 } 62 63 static inline void 64 uart_write(const u_int offset, const uint32_t val) 65 { 66 *RA_IOREG_VADDR(RALINK_CONADDR, offset) = val; 67 } 68 69 #ifdef RA_CONSOLE_EARLY 70 static void 71 ra_console_putc(dev_t dev, int c) 72 { 73 u_int timo; 74 75 timo = 150000; 76 do { 77 if ((uart_read(RA_UART_LSR) & UART_LSR_TDRQ) != 0) 78 break; 79 } while(--timo != 0); 80 81 uart_write(RA_UART_TBR, c); 82 if (c == '\n') 83 ra_console_putc (dev, '\r'); 84 #if 1 85 timo = 150000; 86 do { 87 if ((uart_read(RA_UART_LSR) & UART_LSR_TEMT) != 0) 88 break; 89 } while(--timo != 0); 90 #endif 91 } 92 93 static int 94 ra_console_getc(dev_t dev) 95 { 96 while ((uart_read(RA_UART_LSR) & UART_LSR_DR) == 0) 97 ; 98 return (char)(uart_read(RA_UART_RBR) & 0xff); 99 } 100 101 static void 102 ra_console_flush(dev_t dev) 103 { 104 while ((uart_read(RA_UART_LSR) & UART_LSR_TEMT) == 0) 105 ; 106 } 107 108 void 109 ra_console_early(void) 110 { 111 uint32_t r; 112 113 /* reset */ 114 r = sysctl_read(RA_SYSCTL_RST); 115 r |= RST_UARTL; 116 sysctl_write(RA_SYSCTL_RST, r); 117 r ^= RST_UARTL; 118 sysctl_write(RA_SYSCTL_RST, r); 119 120 /* make sure we are in UART mode */ 121 r = sysctl_read(RA_SYSCTL_GPIOMODE); 122 r &= ~GPIOMODE_UARTL; 123 sysctl_write(RA_SYSCTL_GPIOMODE, r); 124 125 uart_write(RA_UART_IER, 0); /* disable interrupts */ 126 uart_write(RA_UART_FCR, 0); /* disable fifos */ 127 128 /* set baud rate */ 129 uart_write(RA_UART_LCR, 130 UART_LCR_WLS0 | UART_LCR_WLS1 | UART_LCR_DLAB); 131 uart_write(RA_UART_DLL, 132 (RA_UART_FREQ / RA_SERIAL_CLKDIV / RA_BAUDRATE) 133 & 0xffff); 134 uart_write(RA_UART_LCR, 135 UART_LCR_WLS0 | UART_LCR_WLS1); 136 137 static struct consdev lite_cn = { 138 .cn_probe = NULL, 139 .cn_init = NULL, 140 .cn_getc = ra_console_getc, 141 .cn_putc = ra_console_putc, 142 .cn_pollc = nullcnpollc, 143 .cn_bell = NULL, 144 .cn_halt = NULL, 145 .cn_flush = ra_console_flush, 146 .cn_dev = makedev(0, 0), 147 .cn_pri = CN_DEAD, 148 }; 149 150 cn_tab = &lite_cn; 151 152 } 153 #endif /* RA_CONSOLE_EARLY */ 154 155 void 156 consinit(void) 157 { 158 if (ra_check_memo_reg(SERIAL_CONSOLE)) { 159 ralink_com_early(0); 160 printf("Enabled early console\n"); 161 } else { 162 /* 163 * this should be OK, but our shell configuration doesn't seem 164 * to be working, so create a silent console 165 */ 166 cn_tab = NULL; 167 ralink_com_early(1); 168 printf("Enabled silent console\n"); 169 } 170 171 #if 0 172 /* update ddb escape sequence to '~~' to avoid the undocking issue */ 173 cn_set_magic("\x7E\x7E"); 174 #endif 175 } 176