1
2
3
4
5#include <config.h>
6#include <common.h>
7#include <asm/inca-ip.h>
8#include "asc_serial.h"
9
10
11#define SET_BIT(reg, mask) reg |= (mask)
12#define CLEAR_BIT(reg, mask) reg &= (~mask)
13#define CLEAR_BITS(reg, mask) CLEAR_BIT(reg, mask)
14#define SET_BITS(reg, mask) SET_BIT(reg, mask)
15#define SET_BITFIELD(reg, mask, off, val) {reg &= (~mask); reg |= (val << off);}
16
17extern uint incaip_get_fpiclk(void);
18
19static int serial_setopt (void);
20
21
22static volatile incaAsc_t *pAsc = (incaAsc_t *)INCA_IP_ASC;
23
24
25
26
27
28
29
30
31
32
33
34
35int serial_init (void)
36{
37
38 INCAASC_PMU_ENABLE(13);
39
40
41 CLEAR_BIT(pAsc->asc_clc, ASCCLC_DISS);
42 SET_BITFIELD(pAsc->asc_clc, ASCCLC_RMCMASK, ASCCLC_RMCOFFSET, 0x0001);
43
44
45 pAsc->asc_con = ASCCON_M_8ASYNC;
46
47
48 pAsc->asc_pisel = (CONSOLE_TTY & 0x1);
49
50
51 SET_BITFIELD(pAsc->asc_txfcon, ASCTXFCON_TXFITLMASK,
52 ASCTXFCON_TXFITLOFF, INCAASC_TXFIFO_FL);
53
54 SET_BIT(pAsc->asc_txfcon, ASCTXFCON_TXFEN);
55
56
57 SET_BITFIELD(pAsc->asc_txfcon, ASCRXFCON_RXFITLMASK,
58 ASCRXFCON_RXFITLOFF, INCAASC_RXFIFO_FL);
59
60 SET_BIT(pAsc->asc_rxfcon, ASCRXFCON_RXFEN);
61
62
63 SET_BIT(pAsc->asc_con, ASCCON_FEN);
64 SET_BIT(pAsc->asc_con, ASCCON_OEN);
65
66
67 ASC_INTERRUPTS_CLEAR(INCAASC_IRQ_LINE_ALL);
68
69
70 ASC_INTERRUPTS_DISABLE(INCAASC_IRQ_LINE_ALL);
71
72
73 SET_BIT(pAsc->asc_txfcon, ASCTXFCON_TXTMEN);
74 SET_BIT(pAsc->asc_rxfcon, ASCRXFCON_RXTMEN);
75
76
77 serial_setbrg();
78
79
80 serial_setopt();
81
82 return 0;
83}
84
85void serial_setbrg (void)
86{
87 ulong uiReloadValue, fdv;
88 ulong f_ASC;
89
90 f_ASC = incaip_get_fpiclk();
91
92#ifndef INCAASC_USE_FDV
93 fdv = 2;
94 uiReloadValue = (f_ASC / (fdv * 16 * CONFIG_BAUDRATE)) - 1;
95#else
96 fdv = INCAASC_FDV_HIGH_BAUDRATE;
97 uiReloadValue = (f_ASC / (8192 * CONFIG_BAUDRATE / fdv)) - 1;
98#endif
99
100 if ( (uiReloadValue < 0) || (uiReloadValue > 8191) )
101 {
102#ifndef INCAASC_USE_FDV
103 fdv = 3;
104 uiReloadValue = (f_ASC / (fdv * 16 * CONFIG_BAUDRATE)) - 1;
105#else
106 fdv = INCAASC_FDV_LOW_BAUDRATE;
107 uiReloadValue = (f_ASC / (8192 * CONFIG_BAUDRATE / fdv)) - 1;
108#endif
109
110 if ( (uiReloadValue < 0) || (uiReloadValue > 8191) )
111 {
112 return;
113 }
114 }
115
116
117 CLEAR_BIT(pAsc->asc_con, ASCCON_R);
118
119#ifndef INCAASC_USE_FDV
120
121
122
123
124
125 CLEAR_BIT(pAsc->asc_con, ASCCON_FDE);
126
127 if ( fdv == 2 )
128 CLEAR_BIT(pAsc->asc_con, ASCCON_BRS);
129 else
130 SET_BIT(pAsc->asc_con, ASCCON_BRS);
131
132#else
133
134
135 SET_BIT(pAsc->asc_con, ASCCON_FDE);
136
137
138 pAsc->asc_fdv = fdv & ASCFDV_VALUE_MASK;
139
140#endif
141
142
143 pAsc->asc_bg = uiReloadValue;
144
145
146 SET_BIT(pAsc->asc_con, ASCCON_R);
147}
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163static int serial_setopt (void)
164{
165 ulong con;
166
167 switch ( ASC_OPTIONS & ASCOPT_CSIZE )
168 {
169
170 case ASCOPT_CS7:
171 con = ASCCON_M_7ASYNCPAR;
172 break;
173
174
175 case ASCOPT_CS8:
176 if ( ASC_OPTIONS & ASCOPT_PARENB )
177 con = ASCCON_M_8ASYNCPAR;
178 else
179 con = ASCCON_M_8ASYNC;
180 break;
181
182
183
184
185
186 default:
187 return -1;
188 }
189
190 if ( ASC_OPTIONS & ASCOPT_STOPB )
191 SET_BIT(con, ASCCON_STP);
192 else
193 CLEAR_BIT(con, ASCCON_STP);
194
195 if ( ASC_OPTIONS & ASCOPT_PARENB )
196 SET_BIT(con, ASCCON_PEN);
197 else
198 CLEAR_BIT(con, ASCCON_PEN);
199
200 if ( ASC_OPTIONS & ASCOPT_PARODD )
201 SET_BIT(con, ASCCON_ODD);
202 else
203 CLEAR_BIT(con, ASCCON_ODD);
204
205 if ( ASC_OPTIONS & ASCOPT_CREAD )
206 SET_BIT(pAsc->asc_whbcon, ASCWHBCON_SETREN);
207
208 pAsc->asc_con |= con;
209
210 return 0;
211}
212
213void serial_putc (const char c)
214{
215 uint txFl = 0;
216
217 if (c == '\n') serial_putc ('\r');
218
219
220
221 do
222 {
223 txFl = ( pAsc->asc_fstat & ASCFSTAT_TXFFLMASK ) >> ASCFSTAT_TXFFLOFF;
224 }
225 while ( txFl == INCAASC_TXFIFO_FULL );
226
227 pAsc->asc_tbuf = c;
228
229
230 if ( pAsc->asc_con & ASCCON_OE )
231 {
232 SET_BIT(pAsc->asc_whbcon, ASCWHBCON_CLROE);
233 return;
234 }
235}
236
237void serial_puts (const char *s)
238{
239 while (*s)
240 {
241 serial_putc (*s++);
242 }
243}
244
245int serial_getc (void)
246{
247 ulong symbol_mask;
248 char c;
249
250 while (!serial_tstc());
251
252 symbol_mask =
253 ((ASC_OPTIONS & ASCOPT_CSIZE) == ASCOPT_CS7) ? (0x7f) : (0xff);
254
255 c = (char)(pAsc->asc_rbuf & symbol_mask);
256
257 return c;
258}
259
260int serial_tstc (void)
261{
262 int res = 1;
263
264 if ( (pAsc->asc_fstat & ASCFSTAT_RXFFLMASK) == 0 )
265 {
266 res = 0;
267 }
268 else if ( pAsc->asc_con & ASCCON_FE )
269 {
270 SET_BIT(pAsc->asc_whbcon, ASCWHBCON_CLRFE);
271 res = 0;
272 }
273 else if ( pAsc->asc_con & ASCCON_PE )
274 {
275 SET_BIT(pAsc->asc_whbcon, ASCWHBCON_CLRPE);
276 res = 0;
277 }
278 else if ( pAsc->asc_con & ASCCON_OE )
279 {
280 SET_BIT(pAsc->asc_whbcon, ASCWHBCON_CLROE);
281 res = 0;
282 }
283
284 return res;
285}
286