Merge branch 'origin'
[platform/kernel/u-boot.git] / cpu / arm920t / ks8695 / serial.c
1 /*
2  * serial.c -- KS8695 serial driver
3  *
4  * (C) Copyright 2004, Greg Ungerer <greg.ungerer@opengear.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <common.h>
22 #include <asm/arch/platform.h>
23
24 #ifndef CONFIG_SERIAL1
25 #error "Bad: you didn't configure serial ..."
26 #endif
27
28 /*
29  *      Define the UART hardware register access structure.
30  */
31 struct ks8695uart {
32         unsigned int    RX;             /* 0x00 - Receive data (r) */
33         unsigned int    TX;             /* 0x04 - Transmit data (w) */
34         unsigned int    FCR;            /* 0x08 - Fifo Control (r/w) */
35         unsigned int    LCR;            /* 0x0c - Line Control (r/w) */
36         unsigned int    MCR;            /* 0x10 - Modem Control (r/w) */
37         unsigned int    LSR;            /* 0x14 - Line Status (r/w) */
38         unsigned int    MSR;            /* 0x18 - Modem Status (r/w) */
39         unsigned int    BD;             /* 0x1c - Baud Rate (r/w) */
40         unsigned int    SR;             /* 0x20 - Status (r/w) */
41 };
42
43 #define KS8695_UART_ADDR        ((void *) (KS8695_IO_BASE + KS8695_UART_RX_BUFFER))
44 #define KS8695_UART_CLK         25000000
45
46
47 /*
48  * Under some circumstances we want to be "quiet" and not issue any
49  * serial output - though we want u-boot to otherwise work and behave
50  * the same. By default be noisy.
51  */
52 int serial_console = 1;
53
54
55 void serial_setbrg(void)
56 {
57         DECLARE_GLOBAL_DATA_PTR;
58         volatile struct ks8695uart *uartp = KS8695_UART_ADDR;
59
60         /* Set to global baud rate and 8 data bits, no parity, 1 stop bit*/
61         uartp->BD = KS8695_UART_CLK / gd->baudrate;
62         uartp->LCR = KS8695_UART_LINEC_WLEN8;
63 }
64
65 int serial_init(void)
66 {
67         serial_console = 1;
68         serial_setbrg();
69         return 0;
70 }
71
72 void serial_raw_putc(const char c)
73 {
74         volatile struct ks8695uart *uartp = KS8695_UART_ADDR;
75         int i;
76
77         for (i = 0; (i < 0x100000); i++) {
78                 if (uartp->LSR & KS8695_UART_LINES_TXFE)
79                         break;
80         }
81
82         uartp->TX = c;
83 }
84
85 void serial_putc(const char c)
86 {
87         if (serial_console) {
88                 serial_raw_putc(c);
89                 if (c == '\n')
90                         serial_raw_putc('\r');
91         }
92 }
93
94 int serial_tstc(void)
95 {
96         volatile struct ks8695uart *uartp = KS8695_UART_ADDR;
97         if (serial_console)
98                 return ((uartp->LSR & KS8695_UART_LINES_RXFE) ? 1 : 0);
99         return 0;
100 }
101
102 void serial_puts(const char *s)
103 {
104         char c;
105         while ((c = *s++) != 0)
106                 serial_putc(c);
107 }
108
109 int serial_getc(void)
110 {
111         volatile struct ks8695uart *uartp = KS8695_UART_ADDR;
112
113         while ((uartp->LSR & KS8695_UART_LINES_RXFE) == 0)
114                 ;
115         return (uartp->RX);
116 }