GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / cfe / cfe / dev / dev_ns16550.c
blob27819caaad30949ea5eac0626f8af2c089361190
1 /* *********************************************************************
2 * Broadcom Common Firmware Environment (CFE)
3 *
4 * NS16550 UART driver File: dev_ns16550.c
5 *
6 * This is a console device driver for an NS16550 UART, either
7 * on-board or as a PCI-device. In the case of a PCI device,
8 * our probe routine is called from the PCI probe code
9 * over in dev_ns16550_pci.c
11 * Author: Mitch Lichtenberg (mpl@broadcom.com)
13 *********************************************************************
15 * Copyright 2000,2001,2002,2003
16 * Broadcom Corporation. All rights reserved.
18 * This software is furnished under license and may be used and
19 * copied only in accordance with the following terms and
20 * conditions. Subject to these conditions, you may download,
21 * copy, install, use, modify and distribute modified or unmodified
22 * copies of this software in source and/or binary form. No title
23 * or ownership is transferred hereby.
25 * 1) Any source code used, modified or distributed must reproduce
26 * and retain this copyright notice and list of conditions
27 * as they appear in the source file.
29 * 2) No right is granted to use any trade name, trademark, or
30 * logo of Broadcom Corporation. The "Broadcom Corporation"
31 * name may not be used to endorse or promote products derived
32 * from this software without the prior written permission of
33 * Broadcom Corporation.
35 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
36 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
37 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
38 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
39 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
40 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
41 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
42 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
43 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
44 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
45 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
46 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
47 * THE POSSIBILITY OF SUCH DAMAGE.
48 ********************************************************************* */
50 #if CFG_SIM && CFG_SIM_CONSOLE
51 #include <typedefs.h>
52 #include <osl.h>
53 #endif /* CFG_SIM && CFG_SIM_CONSOLE */
55 #include "lib_types.h"
56 #include "lib_malloc.h"
57 #include "lib_printf.h"
58 #include "cfe_iocb.h"
59 #include "cfe_device.h"
60 #include "cfe_ioctl.h"
62 #include "lib_physio.h"
64 #include "bsp_config.h"
66 #include "ns16550.h"
68 #ifdef BCM4704
69 #define WRITECSR(softc, offset, value) do { \
70 phys_write8((softc)->uart_base + ((offset) << (softc)->reg_shift), (value)); \
71 phys_read8(0x18000000); \
72 } while (0)
73 #else
74 #define WRITECSR(softc, offset, value) \
75 phys_write8((softc)->uart_base + ((offset) << (softc)->reg_shift), (value))
76 #endif
78 #define READCSR(softc, offset) \
79 phys_read8((softc)->uart_base + ((offset) << (softc)->reg_shift))
81 static int ns16550_uart_open(cfe_devctx_t *ctx);
82 static int ns16550_uart_read(cfe_devctx_t *ctx,iocb_buffer_t *buffer);
83 static int ns16550_uart_inpstat(cfe_devctx_t *ctx,iocb_inpstat_t *inpstat);
84 static int ns16550_uart_write(cfe_devctx_t *ctx,iocb_buffer_t *buffer);
85 static int ns16550_uart_ioctl(cfe_devctx_t *ctx,iocb_buffer_t *buffer);
86 static int ns16550_uart_close(cfe_devctx_t *ctx);
88 void ns16550_uart_probe(cfe_driver_t *drv,
89 unsigned long probe_a, unsigned long probe_b,
90 void *probe_ptr);
93 const cfe_devdisp_t ns16550_uart_dispatch = {
94 ns16550_uart_open,
95 ns16550_uart_read,
96 ns16550_uart_inpstat,
97 ns16550_uart_write,
98 ns16550_uart_ioctl,
99 ns16550_uart_close,
100 NULL,
101 NULL
104 const cfe_driver_t ns16550_uart = {
105 "NS16550 UART",
106 "uart",
107 CFE_DEV_SERIAL,
108 &ns16550_uart_dispatch,
109 ns16550_uart_probe
112 typedef struct ns16550_uart_s {
113 physaddr_t uart_base;
114 int uart_flowcontrol;
115 int baud_base;
116 int reg_shift;
117 int uart_speed;
118 } ns16550_uart_t;
122 * NS16550-compatible UART.
123 * probe_a: physical address of UART
126 void ns16550_uart_probe(cfe_driver_t *drv,
127 unsigned long probe_a, unsigned long probe_b,
128 void *probe_ptr)
130 ns16550_uart_t *softc;
131 char descr[80];
133 softc = (ns16550_uart_t *) KMALLOC(sizeof(ns16550_uart_t),0);
134 if (softc) {
135 softc->uart_base = probe_a;
136 softc->baud_base = probe_b ? : NS16550_HZ;
137 softc->reg_shift = probe_ptr ? *(int*)probe_ptr : 0;
138 softc->uart_speed = CFG_SERIAL_BAUD_RATE;
139 softc->uart_flowcontrol = SERIAL_FLOW_NONE;
140 xsprintf(descr, "%s at 0x%X", drv->drv_description, (uint32_t)probe_a);
142 cfe_attach(drv, softc, NULL, descr);
146 #if !defined(MIPS33xx)
148 #define DELAY(n) delay(n)
149 extern int32_t _getticks(void);
150 static void delay(int ticks)
152 int32_t t;
154 t = _getticks() + ticks;
155 while (_getticks() < t)
156 ; /* NULL LOOP */
158 #endif /* !MIPS33xx */
160 static void ns16550_uart_setflow(ns16550_uart_t *softc)
162 /* noop for now */
166 static int ns16550_uart_open(cfe_devctx_t *ctx)
168 ns16550_uart_t *softc = ctx->dev_softc;
169 unsigned int brtc;
171 brtc = BRTC(softc->baud_base, softc->uart_speed);
173 WRITECSR(softc,R_UART_CFCR,CFCR_DLAB);
174 WRITECSR(softc,R_UART_DATA,brtc & 0xFF);
175 WRITECSR(softc,R_UART_IER,brtc>>8);
176 WRITECSR(softc,R_UART_CFCR,CFCR_8BITS);
178 #if !defined(NS16550_NO_FLOW)
180 WRITECSR(softc,R_UART_CFCR,CFCR_DLAB);
181 WRITECSR(softc,R_UART_DATA,brtc & 0xFF);
182 WRITECSR(softc,R_UART_IER,brtc>>8);
183 WRITECSR(softc,R_UART_CFCR,CFCR_8BITS);
184 #if !defined(_BCM94702_CPCI_)
185 WRITECSR(softc,R_UART_MCR,MCR_DTR | MCR_RTS | MCR_IENABLE);
186 #endif
187 WRITECSR(softc,R_UART_IER,0);
189 WRITECSR(softc,R_UART_FIFO,FIFO_ENABLE);
190 DELAY(100);
191 WRITECSR(softc,R_UART_FIFO,
192 FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_1);
193 DELAY(100);
195 if ((READCSR(softc,R_UART_IIR) & IIR_FIFO_MASK) !=
196 IIR_FIFO_MASK) {
197 WRITECSR(softc,R_UART_FIFO,0);
199 #endif /* !NS16550_NO_FLOW */
201 ns16550_uart_setflow(softc);
203 return 0;
206 static int ns16550_uart_read(cfe_devctx_t *ctx, iocb_buffer_t *buffer)
208 ns16550_uart_t *softc = ctx->dev_softc;
209 unsigned char *bptr;
210 int blen;
212 bptr = buffer->buf_ptr;
213 blen = buffer->buf_length;
215 while ((blen > 0) && (READCSR(softc,R_UART_LSR) & LSR_RXRDY)) {
216 *bptr++ = (READCSR(softc,R_UART_DATA) & 0xFF);
217 blen--;
220 buffer->buf_retlen = buffer->buf_length - blen;
221 return 0;
224 static int ns16550_uart_inpstat(cfe_devctx_t *ctx, iocb_inpstat_t *inpstat)
226 ns16550_uart_t *softc = ctx->dev_softc;
228 inpstat->inp_status = (READCSR(softc,R_UART_LSR) & LSR_RXRDY) ? 1 : 0;
230 return 0;
233 #if CFG_SIM
234 #define LOG_BUF_LEN (4096)
235 #define LOG_BUF_MASK (LOG_BUF_LEN-1)
236 char log_buf[LOG_BUF_LEN];
237 unsigned long log_start;
239 #ifdef __mips__
240 #define UNCACHED(a) (((unsigned long)(a) & 0x1fffffff) | 0xa0000000)
241 #else
242 #define UNCACHED(a) ((unsigned long)(a))
243 #endif
245 #define WRITEBUF(c) \
246 do { \
247 *((char*)UNCACHED(&log_buf[log_start])) = c; \
248 log_start = (log_start + 1) & LOG_BUF_MASK; \
250 while (0)
251 #endif
253 static int ns16550_uart_write(cfe_devctx_t *ctx, iocb_buffer_t *buffer)
255 ns16550_uart_t *softc = ctx->dev_softc;
256 unsigned char *bptr;
257 int blen;
259 bptr = buffer->buf_ptr;
260 blen = buffer->buf_length;
261 while ((blen > 0) && (READCSR(softc,R_UART_LSR) & LSR_TXRDY)) {
262 #if CFG_SIM
263 WRITEBUF(*bptr);
264 #endif
265 WRITECSR(softc,R_UART_DATA, *bptr++);
266 blen--;
267 #if CFG_SIM && CFG_SIM_CONSOLE
268 OSL_DELAY(100);
269 #endif /* CFG_SIM && CFG_SIM_CONSOLE */
272 buffer->buf_retlen = buffer->buf_length - blen;
273 return 0;
276 static int ns16550_uart_ioctl(cfe_devctx_t *ctx, iocb_buffer_t *buffer)
278 ns16550_uart_t *softc = ctx->dev_softc;
280 unsigned int *info = (unsigned int *) buffer->buf_ptr;
282 switch ((int)buffer->buf_ioctlcmd) {
283 case IOCTL_SERIAL_GETSPEED:
284 *info = softc->uart_speed;
285 break;
286 case IOCTL_SERIAL_SETSPEED:
287 softc->uart_speed = *info;
288 /* NYI */
289 break;
290 case IOCTL_SERIAL_GETFLOW:
291 *info = softc->uart_flowcontrol;
292 break;
293 case IOCTL_SERIAL_SETFLOW:
294 softc->uart_flowcontrol = *info;
295 ns16550_uart_setflow(softc);
296 break;
297 default:
298 return -1;
301 return 0;
304 static int ns16550_uart_close(cfe_devctx_t *ctx)
306 ns16550_uart_t *softc = ctx->dev_softc;
308 WRITECSR(softc,R_UART_MCR,0);
310 return 0;