]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/powerpc/cpu/mpc5xxx/serial.c
Add GPL-2.0+ SPDX-License-Identifier to source files
[karo-tx-uboot.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_putc_raw_dev(unsigned long dev_base, const char c)
116 {
117         volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
118         /* Wait for last character to go. */
119         while (!(psc->psc_status & PSC_SR_TXEMP))
120                 ;
121
122         psc->psc_buffer_8 = c;
123 }
124
125
126 void serial_puts_dev (unsigned long dev_base, const char *s)
127 {
128         while (*s) {
129                 serial_putc_dev (dev_base, *s++);
130         }
131 }
132
133 int serial_getc_dev (unsigned long dev_base)
134 {
135         volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
136
137         /* Wait for a character to arrive. */
138         while (!(psc->psc_status & PSC_SR_RXRDY))
139                 ;
140
141         return psc->psc_buffer_8;
142 }
143
144 int serial_tstc_dev (unsigned long dev_base)
145 {
146         volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
147
148         return (psc->psc_status & PSC_SR_RXRDY);
149 }
150
151 void serial_setbrg_dev (unsigned long dev_base)
152 {
153         volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
154         unsigned long baseclk, div;
155
156         baseclk = (gd->arch.ipb_clk + 16) / 32;
157
158         /* set up UART divisor */
159         div = (baseclk + (gd->baudrate/2)) / gd->baudrate;
160         psc->ctur = (div >> 8) & 0xFF;
161         psc->ctlr =  div & 0xff;
162 }
163
164 void serial_setrts_dev (unsigned long dev_base, int s)
165 {
166         volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
167
168         if (s) {
169                 /* Assert RTS (become LOW) */
170                 psc->op1 = 0x1;
171         }
172         else {
173                 /* Negate RTS (become HIGH) */
174                 psc->op0 = 0x1;
175         }
176 }
177
178 int serial_getcts_dev (unsigned long dev_base)
179 {
180         volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
181
182         return (psc->ip & 0x1) ? 0 : 1;
183 }
184
185 int serial0_init(void)
186 {
187         return (serial_init_dev(PSC_BASE));
188 }
189
190 void serial0_setbrg (void)
191 {
192         serial_setbrg_dev(PSC_BASE);
193 }
194
195 void serial0_putc(const char c)
196 {
197         serial_putc_dev(PSC_BASE,c);
198 }
199
200 void serial0_puts(const char *s)
201 {
202         serial_puts_dev(PSC_BASE, s);
203 }
204
205 int serial0_getc(void)
206 {
207         return(serial_getc_dev(PSC_BASE));
208 }
209
210 int serial0_tstc(void)
211 {
212         return (serial_tstc_dev(PSC_BASE));
213 }
214
215 struct serial_device serial0_device =
216 {
217         .name   = "serial0",
218         .start  = serial0_init,
219         .stop   = NULL,
220         .setbrg = serial0_setbrg,
221         .getc   = serial0_getc,
222         .tstc   = serial0_tstc,
223         .putc   = serial0_putc,
224         .puts   = serial0_puts,
225 };
226
227 __weak struct serial_device *default_serial_console(void)
228 {
229         return &serial0_device;
230 }
231
232 #ifdef CONFIG_PSC_CONSOLE2
233 int serial1_init(void)
234 {
235         return serial_init_dev(PSC_BASE2);
236 }
237
238 void serial1_setbrg(void)
239 {
240         serial_setbrg_dev(PSC_BASE2);
241 }
242
243 void serial1_putc(const char c)
244 {
245         serial_putc_dev(PSC_BASE2, c);
246 }
247
248 void serial1_puts(const char *s)
249 {
250         serial_puts_dev(PSC_BASE2, s);
251 }
252
253 int serial1_getc(void)
254 {
255         return serial_getc_dev(PSC_BASE2);
256 }
257
258 int serial1_tstc(void)
259 {
260         return serial_tstc_dev(PSC_BASE2);
261 }
262
263 struct serial_device serial1_device =
264 {
265         .name   = "serial1",
266         .start  = serial1_init,
267         .stop   = NULL,
268         .setbrg = serial1_setbrg,
269         .getc   = serial1_getc,
270         .tstc   = serial1_tstc,
271         .putc   = serial1_putc,
272         .puts   = serial1_puts,
273 };
274 #endif /* CONFIG_PSC_CONSOLE2 */
275
276 #endif /* CONFIG_PSC_CONSOLE */