]> git.ipfire.org Git - people/ms/u-boot.git/blame - arch/powerpc/cpu/mpc5xxx/serial.c
Add GPL-2.0+ SPDX-License-Identifier to source files
[people/ms/u-boot.git] / arch / powerpc / cpu / mpc5xxx / serial.c
CommitLineData
945af8d7
WD
1/*
2 * (C) Copyright 2000 - 2003
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 *
1a459660 5 * SPDX-License-Identifier: GPL-2.0+
945af8d7
WD
6 *
7 * Hacked for MPC8260 by Murray.Jensen@cmst.csiro.au, 19-Oct-00, with
a47a12be 8 * changes based on the file arch/powerpc/mbxboot/m8260_tty.c from the
945af8d7 9 * Linux/PPC sources (m8260_tty.c had no copyright info in it).
c12cffc5
WD
10 *
11 * Martin Krause, 8 Jun 2006
a3827250 12 * Added SERIAL_MULTI support
945af8d7
WD
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>
6c768ca7 21#include <linux/compiler.h>
945af8d7 22#include <mpc5xxx.h>
c12cffc5 23#include <serial.h>
c12cffc5 24
d87080b7
WD
25DECLARE_GLOBAL_DATA_PTR;
26
945af8d7
WD
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
945af8d7
WD
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
a3827250 45#if defined(CONFIG_PSC_CONSOLE2)
c12cffc5 46
c12cffc5
WD
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
c12cffc5
WD
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
c12cffc5 62
c12cffc5 63#endif
a3827250
MV
64
65int serial_init_dev (unsigned long dev_base)
945af8d7 66{
c12cffc5 67 volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
945af8d7
WD
68 unsigned long baseclk;
69 int div;
70
71 /* reset PSC */
72 psc->command = PSC_SEL_MODE_REG_1;
73
74 /* select clock sources */
945af8d7 75 psc->psc_clock_select = 0;
b2877496 76 baseclk = (gd->arch.ipb_clk + 16) / 32;
945af8d7
WD
77
78 /* switch to UART mode */
79 psc->sicr = 0;
80
81 /* configure parity, bit length and so on */
945af8d7 82 psc->mode = PSC_MODE_8_BITS | PSC_MODE_PARNONE;
945af8d7
WD
83 psc->mode = PSC_MODE_ONE_STOP;
84
85 /* set up UART divisor */
b98fff1d
WD
86 div = (baseclk + (gd->baudrate/2)) / gd->baudrate;
87 psc->ctur = (div >> 8) & 0xff;
945af8d7
WD
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
c12cffc5 101void serial_putc_dev (unsigned long dev_base, const char c)
945af8d7 102{
c12cffc5 103 volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
945af8d7
WD
104
105 if (c == '\n')
c12cffc5 106 serial_putc_dev (dev_base, '\r');
945af8d7
WD
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
e8143e72 115void serial_putc_raw_dev(unsigned long dev_base, const char c)
e8143e72 116{
e8143e72 117 volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
e8143e72
WD
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
c12cffc5 126void serial_puts_dev (unsigned long dev_base, const char *s)
945af8d7
WD
127{
128 while (*s) {
c12cffc5 129 serial_putc_dev (dev_base, *s++);
945af8d7
WD
130 }
131}
132
c12cffc5 133int serial_getc_dev (unsigned long dev_base)
945af8d7 134{
c12cffc5 135 volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
945af8d7
WD
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
c12cffc5 144int serial_tstc_dev (unsigned long dev_base)
945af8d7 145{
c12cffc5 146 volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
945af8d7
WD
147
148 return (psc->psc_status & PSC_SR_RXRDY);
149}
150
c12cffc5 151void serial_setbrg_dev (unsigned long dev_base)
945af8d7 152{
c12cffc5 153 volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
945af8d7
WD
154 unsigned long baseclk, div;
155
b2877496 156 baseclk = (gd->arch.ipb_clk + 16) / 32;
945af8d7
WD
157
158 /* set up UART divisor */
342717f7 159 div = (baseclk + (gd->baudrate/2)) / gd->baudrate;
9f221d07
WD
160 psc->ctur = (div >> 8) & 0xFF;
161 psc->ctlr = div & 0xff;
945af8d7 162}
c12cffc5 163
e8143e72 164void serial_setrts_dev (unsigned long dev_base, int s)
e8143e72 165{
e8143e72 166 volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
e8143e72
WD
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
e8143e72 178int serial_getcts_dev (unsigned long dev_base)
e8143e72 179{
e8143e72 180 volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
e8143e72
WD
181
182 return (psc->ip & 0x1) ? 0 : 1;
183}
184
c12cffc5
WD
185int serial0_init(void)
186{
187 return (serial_init_dev(PSC_BASE));
188}
189
c12cffc5
WD
190void serial0_setbrg (void)
191{
192 serial_setbrg_dev(PSC_BASE);
193}
c12cffc5
WD
194
195void serial0_putc(const char c)
196{
197 serial_putc_dev(PSC_BASE,c);
198}
199
c12cffc5
WD
200void serial0_puts(const char *s)
201{
202 serial_puts_dev(PSC_BASE, s);
203}
204
c12cffc5
WD
205int serial0_getc(void)
206{
207 return(serial_getc_dev(PSC_BASE));
208}
209
c12cffc5
WD
210int serial0_tstc(void)
211{
212 return (serial_tstc_dev(PSC_BASE));
213}
214
c12cffc5
WD
215struct serial_device serial0_device =
216{
90bad891
MV
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,
c12cffc5
WD
225};
226
6c768ca7
MF
227__weak struct serial_device *default_serial_console(void)
228{
229 return &serial0_device;
230}
231
a3827250
MV
232#ifdef CONFIG_PSC_CONSOLE2
233int serial1_init(void)
234{
235 return serial_init_dev(PSC_BASE2);
236}
237
238void serial1_setbrg(void)
239{
240 serial_setbrg_dev(PSC_BASE2);
241}
242
243void serial1_putc(const char c)
244{
245 serial_putc_dev(PSC_BASE2, c);
246}
247
248void serial1_puts(const char *s)
249{
250 serial_puts_dev(PSC_BASE2, s);
251}
252
253int serial1_getc(void)
254{
255 return serial_getc_dev(PSC_BASE2);
256}
257
258int serial1_tstc(void)
259{
260 return serial_tstc_dev(PSC_BASE2);
261}
262
c12cffc5
WD
263struct serial_device serial1_device =
264{
90bad891
MV
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,
c12cffc5 273};
a3827250 274#endif /* CONFIG_PSC_CONSOLE2 */
c12cffc5 275
945af8d7 276#endif /* CONFIG_PSC_CONSOLE */