]>
Commit | Line | Data |
---|---|---|
8993e54b RJ |
1 | /* |
2 | * (C) Copyright 2000 - 2007 | |
3 | * Wolfgang Denk, DENX Software Engineering, wd@denx.de. | |
4 | * | |
5 | * See file CREDITS for list of people who contributed to this | |
6 | * project. | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU General Public License as | |
10 | * published by the Free Software Foundation; either version 2 of | |
11 | * the License, or (at your option) any later version. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | * GNU General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License | |
19 | * along with this program; if not, write to the Free Software | |
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
21 | * MA 02111-1307 USA | |
22 | * | |
23 | * Based ont the MPC5200 PSC driver. | |
24 | * Adapted for MPC512x by Jan Wrobel <wrr@semihalf.com> | |
25 | */ | |
26 | ||
27 | /* | |
28 | * Minimal serial functions needed to use one of the PSC ports | |
29 | * as serial console interface. | |
30 | */ | |
31 | ||
32 | #include <common.h> | |
33 | ||
34 | DECLARE_GLOBAL_DATA_PTR; | |
35 | ||
36 | #if defined(CONFIG_PSC_CONSOLE) | |
37 | ||
38 | static void fifo_init (volatile psc512x_t *psc) | |
39 | { | |
6d0f6bcf | 40 | volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR; |
8993e54b RJ |
41 | |
42 | /* reset Rx & Tx fifo slice */ | |
43 | psc->rfcmd = PSC_FIFO_RESET_SLICE; | |
44 | psc->tfcmd = PSC_FIFO_RESET_SLICE; | |
45 | ||
46 | /* disable Tx & Rx FIFO interrupts */ | |
47 | psc->rfintmask = 0; | |
48 | psc->tfintmask = 0; | |
49 | ||
50 | psc->tfsize = CONSOLE_FIFO_TX_SIZE | (CONSOLE_FIFO_TX_ADDR << 16); | |
51 | psc->rfsize = CONSOLE_FIFO_RX_SIZE | (CONSOLE_FIFO_RX_ADDR << 16); | |
52 | ||
53 | /* enable Tx & Rx FIFO slice */ | |
54 | psc->rfcmd = PSC_FIFO_ENABLE_SLICE; | |
55 | psc->tfcmd = PSC_FIFO_ENABLE_SLICE; | |
56 | ||
57 | im->fifoc.fifoc_cmd = FIFOC_DISABLE_CLOCK_GATE; | |
58 | __asm__ volatile ("sync"); | |
59 | } | |
60 | ||
61 | int serial_init(void) | |
62 | { | |
6d0f6bcf | 63 | volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR; |
8993e54b RJ |
64 | volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE]; |
65 | unsigned long baseclk; | |
66 | int div; | |
67 | ||
68 | fifo_init (psc); | |
69 | ||
70 | /* set MR register to point to MR1 */ | |
71 | psc->command = PSC_SEL_MODE_REG_1; | |
72 | ||
73 | /* disable Tx/Rx */ | |
74 | psc->command = PSC_TX_DISABLE | PSC_RX_DISABLE; | |
75 | ||
76 | /* choose the prescaler by 16 for the Tx/Rx clock generation */ | |
77 | psc->psc_clock_select = 0xdd00; | |
78 | ||
79 | /* switch to UART mode */ | |
80 | psc->sicr = 0; | |
81 | ||
82 | /* mode register points to mr1 */ | |
83 | /* configure parity, bit length and so on in mode register 1*/ | |
84 | psc->mode = PSC_MODE_8_BITS | PSC_MODE_PARNONE; | |
85 | /* now, mode register points to mr2 */ | |
86 | psc->mode = PSC_MODE_1_STOPBIT; | |
87 | ||
88 | /* calculate dividor for setting PSC CTUR and CTLR registers */ | |
5d49e0e1 | 89 | baseclk = (gd->ips_clk + 8) / 16; |
8993e54b RJ |
90 | div = (baseclk + (gd->baudrate / 2)) / gd->baudrate; |
91 | ||
92 | psc->ctur = (div >> 8) & 0xff; | |
93 | /* set baudrate */ | |
94 | psc->ctlr = div & 0xff; | |
95 | ||
96 | /* disable all interrupts */ | |
97 | psc->psc_imr = 0; | |
98 | ||
99 | /* reset and enable Rx/Tx */ | |
100 | psc->command = PSC_RST_RX; | |
101 | psc->command = PSC_RST_TX; | |
102 | psc->command = PSC_RX_ENABLE | PSC_TX_ENABLE; | |
103 | ||
104 | return 0; | |
105 | } | |
106 | ||
107 | void serial_putc (const char c) | |
108 | { | |
6d0f6bcf | 109 | volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR; |
8993e54b RJ |
110 | volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE]; |
111 | ||
112 | if (c == '\n') | |
113 | serial_putc ('\r'); | |
114 | ||
115 | /* Wait for last character to go. */ | |
116 | while (!(psc->psc_status & PSC_SR_TXEMP)) | |
117 | ; | |
118 | ||
119 | psc->tfdata_8 = c; | |
120 | } | |
121 | ||
122 | void serial_putc_raw (const char c) | |
123 | { | |
6d0f6bcf | 124 | volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR; |
8993e54b RJ |
125 | volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE]; |
126 | ||
127 | /* Wait for last character to go. */ | |
128 | while (!(psc->psc_status & PSC_SR_TXEMP)) | |
129 | ; | |
130 | ||
131 | psc->tfdata_8 = c; | |
132 | } | |
133 | ||
134 | ||
135 | void serial_puts (const char *s) | |
136 | { | |
137 | while (*s) { | |
138 | serial_putc (*s++); | |
139 | } | |
140 | } | |
141 | ||
142 | int serial_getc (void) | |
143 | { | |
6d0f6bcf | 144 | volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR; |
8993e54b RJ |
145 | volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE]; |
146 | ||
147 | /* Wait for a character to arrive. */ | |
148 | while (psc->rfstat & PSC_FIFO_EMPTY) | |
149 | ; | |
150 | ||
151 | return psc->rfdata_8; | |
152 | } | |
153 | ||
154 | int serial_tstc (void) | |
155 | { | |
6d0f6bcf | 156 | volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR; |
8993e54b RJ |
157 | volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE]; |
158 | ||
159 | return !(psc->rfstat & PSC_FIFO_EMPTY); | |
160 | } | |
161 | ||
162 | void serial_setbrg (void) | |
163 | { | |
6d0f6bcf | 164 | volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR; |
8993e54b RJ |
165 | volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE]; |
166 | unsigned long baseclk, div; | |
167 | ||
168 | baseclk = (gd->csb_clk + 8) / 16; | |
169 | div = (baseclk + (gd->baudrate / 2)) / gd->baudrate; | |
170 | ||
171 | psc->ctur = (div >> 8) & 0xFF; | |
172 | psc->ctlr = div & 0xff; /* set baudrate */ | |
173 | } | |
174 | ||
175 | void serial_setrts(int s) | |
176 | { | |
6d0f6bcf | 177 | volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR; |
8993e54b RJ |
178 | volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE]; |
179 | ||
180 | if (s) { | |
181 | /* Assert RTS (become LOW) */ | |
182 | psc->op1 = 0x1; | |
183 | } | |
184 | else { | |
185 | /* Negate RTS (become HIGH) */ | |
186 | psc->op0 = 0x1; | |
187 | } | |
188 | } | |
189 | ||
190 | int serial_getcts(void) | |
191 | { | |
6d0f6bcf | 192 | volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR; |
8993e54b RJ |
193 | volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE]; |
194 | ||
195 | return (psc->ip & 0x1) ? 0 : 1; | |
196 | } | |
197 | #endif /* CONFIG_PSC_CONSOLE */ |