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