bccdcf7973af7b601c8c0c00a7f643dbd2f0f8d6
[platform/kernel/u-boot.git] / arch / powerpc / cpu / mpc5xxx / serial.c
1 /*
2  * (C) Copyright 2000 - 2003
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  *
7  * Hacked for MPC8260 by Murray.Jensen@cmst.csiro.au, 19-Oct-00, with
8  * changes based on the file arch/powerpc/mbxboot/m8260_tty.c from the
9  * Linux/PPC sources (m8260_tty.c had no copyright info in it).
10  *
11  * Martin Krause, 8 Jun 2006
12  * Added SERIAL_MULTI support
13  */
14
15 /*
16  * Minimal serial functions needed to use one of the PSC ports
17  * as serial console interface.
18  */
19
20 #include <common.h>
21 #include <linux/compiler.h>
22 #include <mpc5xxx.h>
23 #include <serial.h>
24
25 DECLARE_GLOBAL_DATA_PTR;
26
27 #if defined(CONFIG_PSC_CONSOLE)
28
29 #if CONFIG_PSC_CONSOLE == 1
30 #define PSC_BASE MPC5XXX_PSC1
31 #elif CONFIG_PSC_CONSOLE == 2
32 #define PSC_BASE MPC5XXX_PSC2
33 #elif CONFIG_PSC_CONSOLE == 3
34 #define PSC_BASE MPC5XXX_PSC3
35 #elif CONFIG_PSC_CONSOLE == 4
36 #define PSC_BASE MPC5XXX_PSC4
37 #elif CONFIG_PSC_CONSOLE == 5
38 #define PSC_BASE MPC5XXX_PSC5
39 #elif CONFIG_PSC_CONSOLE == 6
40 #define PSC_BASE MPC5XXX_PSC6
41 #else
42 #error CONFIG_PSC_CONSOLE must be in 1 ... 6
43 #endif
44
45 #if defined(CONFIG_PSC_CONSOLE2)
46
47 #if CONFIG_PSC_CONSOLE2 == 1
48 #define PSC_BASE2 MPC5XXX_PSC1
49 #elif CONFIG_PSC_CONSOLE2 == 2
50 #define PSC_BASE2 MPC5XXX_PSC2
51 #elif CONFIG_PSC_CONSOLE2 == 3
52 #define PSC_BASE2 MPC5XXX_PSC3
53 #elif CONFIG_PSC_CONSOLE2 == 4
54 #define PSC_BASE2 MPC5XXX_PSC4
55 #elif CONFIG_PSC_CONSOLE2 == 5
56 #define PSC_BASE2 MPC5XXX_PSC5
57 #elif CONFIG_PSC_CONSOLE2 == 6
58 #define PSC_BASE2 MPC5XXX_PSC6
59 #else
60 #error CONFIG_PSC_CONSOLE2 must be in 1 ... 6
61 #endif
62
63 #endif
64
65 int serial_init_dev (unsigned long dev_base)
66 {
67         volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
68         unsigned long baseclk;
69         int div;
70
71         /* reset PSC */
72         psc->command = PSC_SEL_MODE_REG_1;
73
74         /* select clock sources */
75         psc->psc_clock_select = 0;
76         baseclk = (gd->arch.ipb_clk + 16) / 32;
77
78         /* switch to UART mode */
79         psc->sicr = 0;
80
81         /* configure parity, bit length and so on */
82         psc->mode = PSC_MODE_8_BITS | PSC_MODE_PARNONE;
83         psc->mode = PSC_MODE_ONE_STOP;
84
85         /* set up UART divisor */
86         div = (baseclk + (gd->baudrate/2)) / gd->baudrate;
87         psc->ctur = (div >> 8) & 0xff;
88         psc->ctlr = div & 0xff;
89
90         /* disable all interrupts */
91         psc->psc_imr = 0;
92
93         /* reset and enable Rx/Tx */
94         psc->command = PSC_RST_RX;
95         psc->command = PSC_RST_TX;
96         psc->command = PSC_RX_ENABLE | PSC_TX_ENABLE;
97
98         return (0);
99 }
100
101 void serial_putc_dev (unsigned long dev_base, const char c)
102 {
103         volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
104
105         if (c == '\n')
106                 serial_putc_dev (dev_base, '\r');
107
108         /* Wait for last character to go. */
109         while (!(psc->psc_status & PSC_SR_TXEMP))
110                 ;
111
112         psc->psc_buffer_8 = c;
113 }
114
115 void serial_puts_dev (unsigned long dev_base, const char *s)
116 {
117         while (*s) {
118                 serial_putc_dev (dev_base, *s++);
119         }
120 }
121
122 int serial_getc_dev (unsigned long dev_base)
123 {
124         volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
125
126         /* Wait for a character to arrive. */
127         while (!(psc->psc_status & PSC_SR_RXRDY))
128                 ;
129
130         return psc->psc_buffer_8;
131 }
132
133 int serial_tstc_dev (unsigned long dev_base)
134 {
135         volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
136
137         return (psc->psc_status & PSC_SR_RXRDY);
138 }
139
140 void serial_setbrg_dev (unsigned long dev_base)
141 {
142         volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
143         unsigned long baseclk, div;
144
145         baseclk = (gd->arch.ipb_clk + 16) / 32;
146
147         /* set up UART divisor */
148         div = (baseclk + (gd->baudrate/2)) / gd->baudrate;
149         psc->ctur = (div >> 8) & 0xFF;
150         psc->ctlr =  div & 0xff;
151 }
152
153 void serial_setrts_dev (unsigned long dev_base, int s)
154 {
155         volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
156
157         if (s) {
158                 /* Assert RTS (become LOW) */
159                 psc->op1 = 0x1;
160         }
161         else {
162                 /* Negate RTS (become HIGH) */
163                 psc->op0 = 0x1;
164         }
165 }
166
167 int serial_getcts_dev (unsigned long dev_base)
168 {
169         volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
170
171         return (psc->ip & 0x1) ? 0 : 1;
172 }
173
174 int serial0_init(void)
175 {
176         return (serial_init_dev(PSC_BASE));
177 }
178
179 void serial0_setbrg (void)
180 {
181         serial_setbrg_dev(PSC_BASE);
182 }
183
184 void serial0_putc(const char c)
185 {
186         serial_putc_dev(PSC_BASE,c);
187 }
188
189 void serial0_puts(const char *s)
190 {
191         serial_puts_dev(PSC_BASE, s);
192 }
193
194 int serial0_getc(void)
195 {
196         return(serial_getc_dev(PSC_BASE));
197 }
198
199 int serial0_tstc(void)
200 {
201         return (serial_tstc_dev(PSC_BASE));
202 }
203
204 struct serial_device serial0_device =
205 {
206         .name   = "serial0",
207         .start  = serial0_init,
208         .stop   = NULL,
209         .setbrg = serial0_setbrg,
210         .getc   = serial0_getc,
211         .tstc   = serial0_tstc,
212         .putc   = serial0_putc,
213         .puts   = serial0_puts,
214 };
215
216 __weak struct serial_device *default_serial_console(void)
217 {
218         return &serial0_device;
219 }
220
221 #ifdef CONFIG_PSC_CONSOLE2
222 int serial1_init(void)
223 {
224         return serial_init_dev(PSC_BASE2);
225 }
226
227 void serial1_setbrg(void)
228 {
229         serial_setbrg_dev(PSC_BASE2);
230 }
231
232 void serial1_putc(const char c)
233 {
234         serial_putc_dev(PSC_BASE2, c);
235 }
236
237 void serial1_puts(const char *s)
238 {
239         serial_puts_dev(PSC_BASE2, s);
240 }
241
242 int serial1_getc(void)
243 {
244         return serial_getc_dev(PSC_BASE2);
245 }
246
247 int serial1_tstc(void)
248 {
249         return serial_tstc_dev(PSC_BASE2);
250 }
251
252 struct serial_device serial1_device =
253 {
254         .name   = "serial1",
255         .start  = serial1_init,
256         .stop   = NULL,
257         .setbrg = serial1_setbrg,
258         .getc   = serial1_getc,
259         .tstc   = serial1_tstc,
260         .putc   = serial1_putc,
261         .puts   = serial1_puts,
262 };
263 #endif /* CONFIG_PSC_CONSOLE2 */
264
265 #endif /* CONFIG_PSC_CONSOLE */