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