0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <stdarg.h>
0012 #include <stddef.h>
0013 #include "types.h"
0014 #include "string.h"
0015 #include "stdio.h"
0016 #include "io.h"
0017 #include "ops.h"
0018 #include "of.h"
0019
0020 #define UART_DLL 0
0021 #define UART_DLM 1
0022 #define UART_FCR 2
0023 #define UART_LCR 3
0024 #define UART_MCR 4
0025 #define UART_LSR 5
0026 #define UART_LSR_THRE 0x20
0027 #define UART_LSR_DR 0x01
0028 #define UART_MSR 6
0029 #define UART_SCR 7
0030
0031 static unsigned char *reg_base;
0032 static u32 reg_shift;
0033
0034 static int ns16550_open(void)
0035 {
0036 out_8(reg_base + (UART_FCR << reg_shift), 0x06);
0037 return 0;
0038 }
0039
0040 static void ns16550_putc(unsigned char c)
0041 {
0042 while ((in_8(reg_base + (UART_LSR << reg_shift)) & UART_LSR_THRE) == 0);
0043 out_8(reg_base, c);
0044 }
0045
0046 static unsigned char ns16550_getc(void)
0047 {
0048 while ((in_8(reg_base + (UART_LSR << reg_shift)) & UART_LSR_DR) == 0);
0049 return in_8(reg_base);
0050 }
0051
0052 static u8 ns16550_tstc(void)
0053 {
0054 return ((in_8(reg_base + (UART_LSR << reg_shift)) & UART_LSR_DR) != 0);
0055 }
0056
0057 int ns16550_console_init(void *devp, struct serial_console_data *scdp)
0058 {
0059 int n;
0060 u32 reg_offset;
0061
0062 if (dt_get_virtual_reg(devp, (void **)®_base, 1) < 1) {
0063 printf("virt reg parse fail...\r\n");
0064 return -1;
0065 }
0066
0067 n = getprop(devp, "reg-offset", ®_offset, sizeof(reg_offset));
0068 if (n == sizeof(reg_offset))
0069 reg_base += be32_to_cpu(reg_offset);
0070
0071 n = getprop(devp, "reg-shift", ®_shift, sizeof(reg_shift));
0072 if (n != sizeof(reg_shift))
0073 reg_shift = 0;
0074 else
0075 reg_shift = be32_to_cpu(reg_shift);
0076
0077 scdp->open = ns16550_open;
0078 scdp->putc = ns16550_putc;
0079 scdp->getc = ns16550_getc;
0080 scdp->tstc = ns16550_tstc;
0081 scdp->close = NULL;
0082
0083 return 0;
0084 }