2 * (C) Copyright 2000 - 2003
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5 * SPDX-License-Identifier: GPL-2.0+
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).
11 * Martin Krause, 8 Jun 2006
12 * Added SERIAL_MULTI support
16 * Minimal serial functions needed to use one of the PSC ports
17 * as serial console interface.
21 #include <linux/compiler.h>
25 DECLARE_GLOBAL_DATA_PTR;
27 #if defined(CONFIG_PSC_CONSOLE)
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
42 #error CONFIG_PSC_CONSOLE must be in 1 ... 6
45 #if defined(CONFIG_PSC_CONSOLE2)
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
60 #error CONFIG_PSC_CONSOLE2 must be in 1 ... 6
65 int serial_init_dev (unsigned long dev_base)
67 volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
68 unsigned long baseclk;
72 psc->command = PSC_SEL_MODE_REG_1;
74 /* select clock sources */
75 psc->psc_clock_select = 0;
76 baseclk = (gd->arch.ipb_clk + 16) / 32;
78 /* switch to UART mode */
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;
85 /* set up UART divisor */
86 div = (baseclk + (gd->baudrate/2)) / gd->baudrate;
87 psc->ctur = (div >> 8) & 0xff;
88 psc->ctlr = div & 0xff;
90 /* disable all interrupts */
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;
101 void serial_putc_dev (unsigned long dev_base, const char c)
103 volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
106 serial_putc_dev (dev_base, '\r');
108 /* Wait for last character to go. */
109 while (!(psc->psc_status & PSC_SR_TXEMP))
112 psc->psc_buffer_8 = c;
115 void serial_putc_raw_dev(unsigned long dev_base, const char c)
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))
122 psc->psc_buffer_8 = c;
126 void serial_puts_dev (unsigned long dev_base, const char *s)
129 serial_putc_dev (dev_base, *s++);
133 int serial_getc_dev (unsigned long dev_base)
135 volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
137 /* Wait for a character to arrive. */
138 while (!(psc->psc_status & PSC_SR_RXRDY))
141 return psc->psc_buffer_8;
144 int serial_tstc_dev (unsigned long dev_base)
146 volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
148 return (psc->psc_status & PSC_SR_RXRDY);
151 void serial_setbrg_dev (unsigned long dev_base)
153 volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
154 unsigned long baseclk, div;
156 baseclk = (gd->arch.ipb_clk + 16) / 32;
158 /* set up UART divisor */
159 div = (baseclk + (gd->baudrate/2)) / gd->baudrate;
160 psc->ctur = (div >> 8) & 0xFF;
161 psc->ctlr = div & 0xff;
164 void serial_setrts_dev (unsigned long dev_base, int s)
166 volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
169 /* Assert RTS (become LOW) */
173 /* Negate RTS (become HIGH) */
178 int serial_getcts_dev (unsigned long dev_base)
180 volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
182 return (psc->ip & 0x1) ? 0 : 1;
185 int serial0_init(void)
187 return (serial_init_dev(PSC_BASE));
190 void serial0_setbrg (void)
192 serial_setbrg_dev(PSC_BASE);
195 void serial0_putc(const char c)
197 serial_putc_dev(PSC_BASE,c);
200 void serial0_puts(const char *s)
202 serial_puts_dev(PSC_BASE, s);
205 int serial0_getc(void)
207 return(serial_getc_dev(PSC_BASE));
210 int serial0_tstc(void)
212 return (serial_tstc_dev(PSC_BASE));
215 struct serial_device serial0_device =
218 .start = serial0_init,
220 .setbrg = serial0_setbrg,
221 .getc = serial0_getc,
222 .tstc = serial0_tstc,
223 .putc = serial0_putc,
224 .puts = serial0_puts,
227 __weak struct serial_device *default_serial_console(void)
229 return &serial0_device;
232 #ifdef CONFIG_PSC_CONSOLE2
233 int serial1_init(void)
235 return serial_init_dev(PSC_BASE2);
238 void serial1_setbrg(void)
240 serial_setbrg_dev(PSC_BASE2);
243 void serial1_putc(const char c)
245 serial_putc_dev(PSC_BASE2, c);
248 void serial1_puts(const char *s)
250 serial_puts_dev(PSC_BASE2, s);
253 int serial1_getc(void)
255 return serial_getc_dev(PSC_BASE2);
258 int serial1_tstc(void)
260 return serial_tstc_dev(PSC_BASE2);
263 struct serial_device serial1_device =
266 .start = serial1_init,
268 .setbrg = serial1_setbrg,
269 .getc = serial1_getc,
270 .tstc = serial1_tstc,
271 .putc = serial1_putc,
272 .puts = serial1_puts,
274 #endif /* CONFIG_PSC_CONSOLE2 */
276 #endif /* CONFIG_PSC_CONSOLE */