]>
Commit | Line | Data |
---|---|---|
4a9cbbe8 WD |
1 | /* |
2 | * (C) Copyright 2000 | |
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 | * Hacked for MPC8260 by Murray.Jensen@cmst.csiro.au, 19-Oct-00. | |
24 | */ | |
25 | ||
26 | /* | |
27 | * Minimal serial functions needed to use one of the SCC ports | |
28 | * as serial console interface. | |
29 | */ | |
30 | ||
31 | #include <common.h> | |
32 | #include <mpc8260.h> | |
33 | #include <asm/cpm_8260.h> | |
d68f4da2 MV |
34 | #include <serial.h> |
35 | #include <linux/compiler.h> | |
4a9cbbe8 | 36 | |
d87080b7 WD |
37 | DECLARE_GLOBAL_DATA_PTR; |
38 | ||
4a9cbbe8 WD |
39 | #if defined(CONFIG_CONS_ON_SCC) |
40 | ||
41 | #if CONFIG_CONS_INDEX == 1 /* Console on SCC1 */ | |
42 | ||
43 | #define SCC_INDEX 0 | |
44 | #define PROFF_SCC PROFF_SCC1 | |
45 | #define CMXSCR_MASK (CMXSCR_GR1|CMXSCR_SC1|\ | |
46 | CMXSCR_RS1CS_MSK|CMXSCR_TS1CS_MSK) | |
47 | #define CMXSCR_VALUE (CMXSCR_RS1CS_BRG1|CMXSCR_TS1CS_BRG1) | |
48 | #define CPM_CR_SCC_PAGE CPM_CR_SCC1_PAGE | |
49 | #define CPM_CR_SCC_SBLOCK CPM_CR_SCC1_SBLOCK | |
50 | ||
51 | #elif CONFIG_CONS_INDEX == 2 /* Console on SCC2 */ | |
52 | ||
53 | #define SCC_INDEX 1 | |
54 | #define PROFF_SCC PROFF_SCC2 | |
55 | #define CMXSCR_MASK (CMXSCR_GR2|CMXSCR_SC2|\ | |
56 | CMXSCR_RS2CS_MSK|CMXSCR_TS2CS_MSK) | |
57 | #define CMXSCR_VALUE (CMXSCR_RS2CS_BRG2|CMXSCR_TS2CS_BRG2) | |
58 | #define CPM_CR_SCC_PAGE CPM_CR_SCC2_PAGE | |
59 | #define CPM_CR_SCC_SBLOCK CPM_CR_SCC2_SBLOCK | |
60 | ||
61 | #elif CONFIG_CONS_INDEX == 3 /* Console on SCC3 */ | |
62 | ||
63 | #define SCC_INDEX 2 | |
64 | #define PROFF_SCC PROFF_SCC3 | |
65 | #define CMXSCR_MASK (CMXSCR_GR3|CMXSCR_SC3|\ | |
66 | CMXSCR_RS3CS_MSK|CMXSCR_TS3CS_MSK) | |
67 | #define CMXSCR_VALUE (CMXSCR_RS3CS_BRG3|CMXSCR_TS3CS_BRG3) | |
68 | #define CPM_CR_SCC_PAGE CPM_CR_SCC3_PAGE | |
69 | #define CPM_CR_SCC_SBLOCK CPM_CR_SCC3_SBLOCK | |
70 | ||
71 | #elif CONFIG_CONS_INDEX == 4 /* Console on SCC4 */ | |
72 | ||
73 | #define SCC_INDEX 3 | |
74 | #define PROFF_SCC PROFF_SCC4 | |
75 | #define CMXSCR_MASK (CMXSCR_GR4|CMXSCR_SC4|\ | |
76 | CMXSCR_RS4CS_MSK|CMXSCR_TS4CS_MSK) | |
77 | #define CMXSCR_VALUE (CMXSCR_RS4CS_BRG4|CMXSCR_TS4CS_BRG4) | |
78 | #define CPM_CR_SCC_PAGE CPM_CR_SCC4_PAGE | |
79 | #define CPM_CR_SCC_SBLOCK CPM_CR_SCC4_SBLOCK | |
80 | ||
81 | #else | |
82 | ||
83 | #error "console not correctly defined" | |
84 | ||
85 | #endif | |
86 | ||
d68f4da2 | 87 | static int mpc8260_scc_serial_init(void) |
4a9cbbe8 | 88 | { |
6d0f6bcf | 89 | volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR; |
4a9cbbe8 WD |
90 | volatile scc_t *sp; |
91 | volatile scc_uart_t *up; | |
92 | volatile cbd_t *tbdf, *rbdf; | |
93 | volatile cpm8260_t *cp = &(im->im_cpm); | |
94 | uint dpaddr; | |
95 | ||
96 | /* initialize pointers to SCC */ | |
97 | ||
98 | sp = (scc_t *) &(im->im_scc[SCC_INDEX]); | |
99 | up = (scc_uart_t *)&im->im_dprambase[PROFF_SCC]; | |
100 | ||
101 | /* Disable transmitter/receiver. | |
102 | */ | |
103 | sp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); | |
104 | ||
105 | /* put the SCC channel into NMSI (non multiplexd serial interface) | |
106 | * mode and wire the selected SCC Tx and Rx clocks to BRGx (15-15). | |
107 | */ | |
108 | im->im_cpmux.cmx_scr = (im->im_cpmux.cmx_scr&~CMXSCR_MASK)|CMXSCR_VALUE; | |
109 | ||
110 | /* Set up the baud rate generator. | |
111 | */ | |
112 | serial_setbrg (); | |
113 | ||
114 | /* Allocate space for two buffer descriptors in the DP ram. | |
115 | * damm: allocating space after the two buffers for rx/tx data | |
116 | */ | |
117 | ||
118 | dpaddr = m8260_cpm_dpalloc((2 * sizeof (cbd_t)) + 2, 16); | |
119 | ||
120 | /* Set the physical address of the host memory buffers in | |
121 | * the buffer descriptors. | |
122 | */ | |
123 | rbdf = (cbd_t *)&im->im_dprambase[dpaddr]; | |
124 | rbdf->cbd_bufaddr = (uint) (rbdf+2); | |
125 | rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP; | |
126 | tbdf = rbdf + 1; | |
127 | tbdf->cbd_bufaddr = ((uint) (rbdf+2)) + 1; | |
128 | tbdf->cbd_sc = BD_SC_WRAP; | |
129 | ||
130 | /* Set up the uart parameters in the parameter ram. | |
131 | */ | |
132 | up->scc_genscc.scc_rbase = dpaddr; | |
133 | up->scc_genscc.scc_tbase = dpaddr+sizeof(cbd_t); | |
134 | up->scc_genscc.scc_rfcr = CPMFCR_EB; | |
135 | up->scc_genscc.scc_tfcr = CPMFCR_EB; | |
136 | up->scc_genscc.scc_mrblr = 1; | |
137 | up->scc_maxidl = 0; | |
138 | up->scc_brkcr = 1; | |
139 | up->scc_parec = 0; | |
140 | up->scc_frmec = 0; | |
141 | up->scc_nosec = 0; | |
142 | up->scc_brkec = 0; | |
143 | up->scc_uaddr1 = 0; | |
144 | up->scc_uaddr2 = 0; | |
145 | up->scc_toseq = 0; | |
146 | up->scc_char1 = up->scc_char2 = up->scc_char3 = up->scc_char4 = 0x8000; | |
147 | up->scc_char5 = up->scc_char6 = up->scc_char7 = up->scc_char8 = 0x8000; | |
148 | up->scc_rccm = 0xc0ff; | |
149 | ||
150 | /* Mask all interrupts and remove anything pending. | |
151 | */ | |
152 | sp->scc_sccm = 0; | |
153 | sp->scc_scce = 0xffff; | |
154 | ||
155 | /* Set 8 bit FIFO, 16 bit oversampling and UART mode. | |
156 | */ | |
157 | sp->scc_gsmrh = SCC_GSMRH_RFW; /* 8 bit FIFO */ | |
158 | sp->scc_gsmrl = \ | |
159 | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16 | SCC_GSMRL_MODE_UART; | |
160 | ||
161 | /* Set CTS flow control, 1 stop bit, 8 bit character length, | |
162 | * normal async UART mode, no parity | |
163 | */ | |
164 | sp->scc_psmr = SCU_PSMR_FLC | SCU_PSMR_CL; | |
165 | ||
166 | /* execute the "Init Rx and Tx params" CP command. | |
167 | */ | |
168 | ||
169 | while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */ | |
170 | ; | |
171 | ||
172 | cp->cp_cpcr = mk_cr_cmd(CPM_CR_SCC_PAGE, CPM_CR_SCC_SBLOCK, | |
173 | 0, CPM_CR_INIT_TRX) | CPM_CR_FLG; | |
174 | ||
175 | while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */ | |
176 | ; | |
177 | ||
178 | /* Enable transmitter/receiver. | |
179 | */ | |
180 | sp->scc_gsmrl |= SCC_GSMRL_ENR | SCC_GSMRL_ENT; | |
181 | ||
182 | return (0); | |
183 | } | |
184 | ||
d68f4da2 | 185 | static void mpc8260_scc_serial_setbrg(void) |
4a9cbbe8 | 186 | { |
4a9cbbe8 WD |
187 | #if defined(CONFIG_CONS_USE_EXTC) |
188 | m8260_cpm_extcbrg(SCC_INDEX, gd->baudrate, | |
189 | CONFIG_CONS_EXTC_RATE, CONFIG_CONS_EXTC_PINSEL); | |
190 | #else | |
191 | m8260_cpm_setbrg(SCC_INDEX, gd->baudrate); | |
192 | #endif | |
193 | } | |
194 | ||
d68f4da2 | 195 | static void mpc8260_scc_serial_putc(const char c) |
4a9cbbe8 WD |
196 | { |
197 | volatile scc_uart_t *up; | |
198 | volatile cbd_t *tbdf; | |
8bde7f77 | 199 | volatile immap_t *im; |
4a9cbbe8 WD |
200 | |
201 | if (c == '\n') | |
202 | serial_putc ('\r'); | |
203 | ||
6d0f6bcf | 204 | im = (immap_t *)CONFIG_SYS_IMMR; |
4a9cbbe8 WD |
205 | up = (scc_uart_t *)&im->im_dprambase[PROFF_SCC]; |
206 | tbdf = (cbd_t *)&im->im_dprambase[up->scc_genscc.scc_tbase]; | |
207 | ||
208 | /* Wait for last character to go. | |
209 | */ | |
210 | while (tbdf->cbd_sc & BD_SC_READY) | |
211 | ; | |
212 | ||
213 | /* Load the character into the transmit buffer. | |
214 | */ | |
215 | *(volatile char *)tbdf->cbd_bufaddr = c; | |
216 | tbdf->cbd_datlen = 1; | |
217 | tbdf->cbd_sc |= BD_SC_READY; | |
218 | } | |
219 | ||
d68f4da2 | 220 | static void mpc8260_scc_serial_puts(const char *s) |
4a9cbbe8 WD |
221 | { |
222 | while (*s) { | |
223 | serial_putc (*s++); | |
224 | } | |
225 | } | |
226 | ||
d68f4da2 | 227 | static int mpc8260_scc_serial_getc(void) |
4a9cbbe8 WD |
228 | { |
229 | volatile cbd_t *rbdf; | |
230 | volatile scc_uart_t *up; | |
8bde7f77 | 231 | volatile immap_t *im; |
4a9cbbe8 WD |
232 | unsigned char c; |
233 | ||
6d0f6bcf | 234 | im = (immap_t *)CONFIG_SYS_IMMR; |
4a9cbbe8 WD |
235 | up = (scc_uart_t *)&im->im_dprambase[PROFF_SCC]; |
236 | rbdf = (cbd_t *)&im->im_dprambase[up->scc_genscc.scc_rbase]; | |
237 | ||
238 | /* Wait for character to show up. | |
239 | */ | |
240 | while (rbdf->cbd_sc & BD_SC_EMPTY) | |
241 | ; | |
242 | ||
243 | /* Grab the char and clear the buffer again. | |
244 | */ | |
245 | c = *(volatile unsigned char *)rbdf->cbd_bufaddr; | |
246 | rbdf->cbd_sc |= BD_SC_EMPTY; | |
247 | ||
248 | return (c); | |
249 | } | |
250 | ||
d68f4da2 | 251 | static int mpc8260_scc_serial_tstc(void) |
4a9cbbe8 WD |
252 | { |
253 | volatile cbd_t *rbdf; | |
254 | volatile scc_uart_t *up; | |
8bde7f77 | 255 | volatile immap_t *im; |
4a9cbbe8 | 256 | |
6d0f6bcf | 257 | im = (immap_t *)CONFIG_SYS_IMMR; |
4a9cbbe8 WD |
258 | up = (scc_uart_t *)&im->im_dprambase[PROFF_SCC]; |
259 | rbdf = (cbd_t *)&im->im_dprambase[up->scc_genscc.scc_rbase]; | |
260 | ||
261 | return ((rbdf->cbd_sc & BD_SC_EMPTY) == 0); | |
262 | } | |
263 | ||
d68f4da2 MV |
264 | static struct serial_device mpc8260_scc_serial_drv = { |
265 | .name = "mpc8260_scc_uart", | |
266 | .start = mpc8260_scc_serial_init, | |
267 | .stop = NULL, | |
268 | .setbrg = mpc8260_scc_serial_setbrg, | |
269 | .putc = mpc8260_scc_serial_putc, | |
270 | .puts = mpc8260_scc_serial_puts, | |
271 | .getc = mpc8260_scc_serial_getc, | |
272 | .tstc = mpc8260_scc_serial_tstc, | |
273 | }; | |
274 | ||
275 | void mpc8260_scc_serial_initialize(void) | |
276 | { | |
277 | serial_register(&mpc8260_scc_serial_drv); | |
278 | } | |
279 | ||
280 | __weak struct serial_device *default_serial_console(void) | |
281 | { | |
282 | return &mpc8260_scc_serial_drv; | |
283 | } | |
4a9cbbe8 WD |
284 | #endif /* CONFIG_CONS_ON_SCC */ |
285 | ||
286 | #if defined(CONFIG_KGDB_ON_SCC) | |
287 | ||
288 | #if defined(CONFIG_CONS_ON_SCC) && CONFIG_KGDB_INDEX == CONFIG_CONS_INDEX | |
289 | #error Whoops! serial console and kgdb are on the same scc serial port | |
290 | #endif | |
291 | ||
292 | #if CONFIG_KGDB_INDEX == 1 /* KGDB Port on SCC1 */ | |
293 | ||
294 | #define KGDB_SCC_INDEX 0 | |
295 | #define KGDB_PROFF_SCC PROFF_SCC1 | |
296 | #define KGDB_CMXSCR_MASK (CMXSCR_GR1|CMXSCR_SC1|\ | |
297 | CMXSCR_RS1CS_MSK|CMXSCR_TS1CS_MSK) | |
298 | #define KGDB_CMXSCR_VALUE (CMXSCR_RS1CS_BRG1|CMXSCR_TS1CS_BRG1) | |
299 | #define KGDB_CPM_CR_SCC_PAGE CPM_CR_SCC1_PAGE | |
300 | #define KGDB_CPM_CR_SCC_SBLOCK CPM_CR_SCC1_SBLOCK | |
301 | ||
302 | #elif CONFIG_KGDB_INDEX == 2 /* KGDB Port on SCC2 */ | |
303 | ||
304 | #define KGDB_SCC_INDEX 1 | |
305 | #define KGDB_PROFF_SCC PROFF_SCC2 | |
306 | #define KGDB_CMXSCR_MASK (CMXSCR_GR2|CMXSCR_SC2|\ | |
307 | CMXSCR_RS2CS_MSK|CMXSCR_TS2CS_MSK) | |
308 | #define KGDB_CMXSCR_VALUE (CMXSCR_RS2CS_BRG2|CMXSCR_TS2CS_BRG2) | |
309 | #define KGDB_CPM_CR_SCC_PAGE CPM_CR_SCC2_PAGE | |
310 | #define KGDB_CPM_CR_SCC_SBLOCK CPM_CR_SCC2_SBLOCK | |
311 | ||
312 | #elif CONFIG_KGDB_INDEX == 3 /* KGDB Port on SCC3 */ | |
313 | ||
314 | #define KGDB_SCC_INDEX 2 | |
315 | #define KGDB_PROFF_SCC PROFF_SCC3 | |
316 | #define KGDB_CMXSCR_MASK (CMXSCR_GR3|CMXSCR_SC3|\ | |
317 | CMXSCR_RS3CS_MSK|CMXSCR_TS3CS_MSK) | |
318 | #define KGDB_CMXSCR_VALUE (CMXSCR_RS3CS_BRG3|CMXSCR_TS3CS_BRG3) | |
319 | #define KGDB_CPM_CR_SCC_PAGE CPM_CR_SCC3_PAGE | |
320 | #define KGDB_CPM_CR_SCC_SBLOCK CPM_CR_SCC3_SBLOCK | |
321 | ||
322 | #elif CONFIG_KGDB_INDEX == 4 /* KGDB Port on SCC4 */ | |
323 | ||
324 | #define KGDB_SCC_INDEX 3 | |
325 | #define KGDB_PROFF_SCC PROFF_SCC4 | |
326 | #define KGDB_CMXSCR_MASK (CMXSCR_GR4|CMXSCR_SC4|\ | |
327 | CMXSCR_RS4CS_MSK|CMXSCR_TS4CS_MSK) | |
328 | #define KGDB_CMXSCR_VALUE (CMXSCR_RS4CS_BRG4|CMXSCR_TS4CS_BRG4) | |
329 | #define KGDB_CPM_CR_SCC_PAGE CPM_CR_SCC4_PAGE | |
330 | #define KGDB_CPM_CR_SCC_SBLOCK CPM_CR_SCC4_SBLOCK | |
331 | ||
332 | #else | |
333 | ||
334 | #error "kgdb serial port not correctly defined" | |
335 | ||
336 | #endif | |
337 | ||
338 | void | |
339 | kgdb_serial_init (void) | |
340 | { | |
6d0f6bcf | 341 | volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR; |
4a9cbbe8 WD |
342 | volatile scc_t *sp; |
343 | volatile scc_uart_t *up; | |
344 | volatile cbd_t *tbdf, *rbdf; | |
345 | volatile cpm8260_t *cp = &(im->im_cpm); | |
346 | uint dpaddr, speed = CONFIG_KGDB_BAUDRATE; | |
347 | char *s, *e; | |
348 | ||
349 | if ((s = getenv("kgdbrate")) != NULL && *s != '\0') { | |
350 | ulong rate = simple_strtoul(s, &e, 10); | |
351 | if (e > s && *e == '\0') | |
352 | speed = rate; | |
353 | } | |
354 | ||
355 | /* initialize pointers to SCC */ | |
356 | ||
357 | sp = (scc_t *) &(im->im_scc[KGDB_SCC_INDEX]); | |
358 | up = (scc_uart_t *)&im->im_dprambase[KGDB_PROFF_SCC]; | |
359 | ||
360 | /* Disable transmitter/receiver. | |
361 | */ | |
362 | sp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); | |
363 | ||
364 | /* put the SCC channel into NMSI (non multiplexd serial interface) | |
365 | * mode and wire the selected SCC Tx and Rx clocks to BRGx (15-15). | |
366 | */ | |
367 | im->im_cpmux.cmx_scr = \ | |
368 | (im->im_cpmux.cmx_scr & ~KGDB_CMXSCR_MASK) | KGDB_CMXSCR_VALUE; | |
369 | ||
370 | /* Set up the baud rate generator. | |
371 | */ | |
372 | #if defined(CONFIG_KGDB_USE_EXTC) | |
373 | m8260_cpm_extcbrg(KGDB_SCC_INDEX, speed, | |
374 | CONFIG_KGDB_EXTC_RATE, CONFIG_KGDB_EXTC_PINSEL); | |
375 | #else | |
376 | m8260_cpm_setbrg(KGDB_SCC_INDEX, speed); | |
377 | #endif | |
378 | ||
379 | /* Allocate space for two buffer descriptors in the DP ram. | |
380 | * damm: allocating space after the two buffers for rx/tx data | |
381 | */ | |
382 | ||
383 | dpaddr = m8260_cpm_dpalloc((2 * sizeof (cbd_t)) + 2, 16); | |
384 | ||
385 | /* Set the physical address of the host memory buffers in | |
386 | * the buffer descriptors. | |
387 | */ | |
388 | rbdf = (cbd_t *)&im->im_dprambase[dpaddr]; | |
389 | rbdf->cbd_bufaddr = (uint) (rbdf+2); | |
390 | rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP; | |
391 | tbdf = rbdf + 1; | |
392 | tbdf->cbd_bufaddr = ((uint) (rbdf+2)) + 1; | |
393 | tbdf->cbd_sc = BD_SC_WRAP; | |
394 | ||
395 | /* Set up the uart parameters in the parameter ram. | |
396 | */ | |
397 | up->scc_genscc.scc_rbase = dpaddr; | |
398 | up->scc_genscc.scc_tbase = dpaddr+sizeof(cbd_t); | |
399 | up->scc_genscc.scc_rfcr = CPMFCR_EB; | |
400 | up->scc_genscc.scc_tfcr = CPMFCR_EB; | |
401 | up->scc_genscc.scc_mrblr = 1; | |
402 | up->scc_maxidl = 0; | |
403 | up->scc_brkcr = 1; | |
404 | up->scc_parec = 0; | |
405 | up->scc_frmec = 0; | |
406 | up->scc_nosec = 0; | |
407 | up->scc_brkec = 0; | |
408 | up->scc_uaddr1 = 0; | |
409 | up->scc_uaddr2 = 0; | |
410 | up->scc_toseq = 0; | |
411 | up->scc_char1 = up->scc_char2 = up->scc_char3 = up->scc_char4 = 0x8000; | |
412 | up->scc_char5 = up->scc_char6 = up->scc_char7 = up->scc_char8 = 0x8000; | |
413 | up->scc_rccm = 0xc0ff; | |
414 | ||
415 | /* Mask all interrupts and remove anything pending. | |
416 | */ | |
417 | sp->scc_sccm = 0; | |
418 | sp->scc_scce = 0xffff; | |
419 | ||
420 | /* Set 8 bit FIFO, 16 bit oversampling and UART mode. | |
421 | */ | |
422 | sp->scc_gsmrh = SCC_GSMRH_RFW; /* 8 bit FIFO */ | |
423 | sp->scc_gsmrl = \ | |
424 | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16 | SCC_GSMRL_MODE_UART; | |
425 | ||
426 | /* Set CTS flow control, 1 stop bit, 8 bit character length, | |
427 | * normal async UART mode, no parity | |
428 | */ | |
429 | sp->scc_psmr = SCU_PSMR_FLC | SCU_PSMR_CL; | |
430 | ||
431 | /* execute the "Init Rx and Tx params" CP command. | |
432 | */ | |
433 | ||
434 | while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */ | |
435 | ; | |
436 | ||
437 | cp->cp_cpcr = mk_cr_cmd(KGDB_CPM_CR_SCC_PAGE, KGDB_CPM_CR_SCC_SBLOCK, | |
438 | 0, CPM_CR_INIT_TRX) | CPM_CR_FLG; | |
439 | ||
440 | while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */ | |
441 | ; | |
442 | ||
443 | /* Enable transmitter/receiver. | |
444 | */ | |
445 | sp->scc_gsmrl |= SCC_GSMRL_ENR | SCC_GSMRL_ENT; | |
446 | ||
447 | printf("SCC%d at %dbps ", CONFIG_KGDB_INDEX, speed); | |
448 | } | |
449 | ||
450 | void | |
451 | putDebugChar(const char c) | |
452 | { | |
453 | volatile scc_uart_t *up; | |
454 | volatile cbd_t *tbdf; | |
8bde7f77 | 455 | volatile immap_t *im; |
4a9cbbe8 WD |
456 | |
457 | if (c == '\n') | |
458 | putDebugChar ('\r'); | |
459 | ||
6d0f6bcf | 460 | im = (immap_t *)CONFIG_SYS_IMMR; |
4a9cbbe8 WD |
461 | up = (scc_uart_t *)&im->im_dprambase[KGDB_PROFF_SCC]; |
462 | tbdf = (cbd_t *)&im->im_dprambase[up->scc_genscc.scc_tbase]; | |
463 | ||
464 | /* Wait for last character to go. | |
465 | */ | |
466 | while (tbdf->cbd_sc & BD_SC_READY) | |
467 | ; | |
468 | ||
469 | /* Load the character into the transmit buffer. | |
470 | */ | |
471 | *(volatile char *)tbdf->cbd_bufaddr = c; | |
472 | tbdf->cbd_datlen = 1; | |
473 | tbdf->cbd_sc |= BD_SC_READY; | |
474 | } | |
475 | ||
476 | void | |
477 | putDebugStr (const char *s) | |
478 | { | |
479 | while (*s) { | |
480 | putDebugChar (*s++); | |
481 | } | |
482 | } | |
483 | ||
484 | int | |
485 | getDebugChar(void) | |
486 | { | |
487 | volatile cbd_t *rbdf; | |
488 | volatile scc_uart_t *up; | |
8bde7f77 | 489 | volatile immap_t *im; |
4a9cbbe8 WD |
490 | unsigned char c; |
491 | ||
6d0f6bcf | 492 | im = (immap_t *)CONFIG_SYS_IMMR; |
4a9cbbe8 WD |
493 | up = (scc_uart_t *)&im->im_dprambase[KGDB_PROFF_SCC]; |
494 | rbdf = (cbd_t *)&im->im_dprambase[up->scc_genscc.scc_rbase]; | |
495 | ||
496 | /* Wait for character to show up. | |
497 | */ | |
498 | while (rbdf->cbd_sc & BD_SC_EMPTY) | |
499 | ; | |
500 | ||
501 | /* Grab the char and clear the buffer again. | |
502 | */ | |
503 | c = *(volatile unsigned char *)rbdf->cbd_bufaddr; | |
504 | rbdf->cbd_sc |= BD_SC_EMPTY; | |
505 | ||
506 | return (c); | |
507 | } | |
508 | ||
509 | void | |
510 | kgdb_interruptible(int yes) | |
511 | { | |
512 | return; | |
513 | } | |
514 | ||
515 | #endif /* CONFIG_KGDB_ON_SCC */ |