blob: feba1f63d260b3a1465e6a2f742b7db23df94a8e [file] [log] [blame]
wdenk4a9cbbe2002-08-27 09:48:53 +00001/*
2 * (C) Copyright 2000, 2001, 2002
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, with
Stefan Roese88fbf932010-04-15 16:07:28 +020024 * changes based on the file arch/powerpc/mbxboot/m8260_tty.c from the
wdenk4a9cbbe2002-08-27 09:48:53 +000025 * Linux/PPC sources (m8260_tty.c had no copyright info in it).
26 */
27
28/*
29 * Minimal serial functions needed to use one of the SMC ports
30 * as serial console interface.
31 */
32
33#include <common.h>
34#include <mpc8260.h>
35#include <asm/cpm_8260.h>
Marek Vasut18a47792012-09-13 01:34:16 +020036#include <serial.h>
37#include <linux/compiler.h>
wdenk4a9cbbe2002-08-27 09:48:53 +000038
Wolfgang Denk6405a152006-03-31 18:32:53 +020039DECLARE_GLOBAL_DATA_PTR;
40
wdenk4a9cbbe2002-08-27 09:48:53 +000041#if defined(CONFIG_CONS_ON_SMC)
42
43#if CONFIG_CONS_INDEX == 1 /* Console on SMC1 */
44
45#define SMC_INDEX 0
46#define PROFF_SMC_BASE PROFF_SMC1_BASE
47#define PROFF_SMC PROFF_SMC1
48#define CPM_CR_SMC_PAGE CPM_CR_SMC1_PAGE
49#define CPM_CR_SMC_SBLOCK CPM_CR_SMC1_SBLOCK
50#define CMXSMR_MASK (CMXSMR_SMC1|CMXSMR_SMC1CS_MSK)
51#define CMXSMR_VALUE CMXSMR_SMC1CS_BRG7
52
53#elif CONFIG_CONS_INDEX == 2 /* Console on SMC2 */
54
55#define SMC_INDEX 1
56#define PROFF_SMC_BASE PROFF_SMC2_BASE
57#define PROFF_SMC PROFF_SMC2
58#define CPM_CR_SMC_PAGE CPM_CR_SMC2_PAGE
59#define CPM_CR_SMC_SBLOCK CPM_CR_SMC2_SBLOCK
60#define CMXSMR_MASK (CMXSMR_SMC2|CMXSMR_SMC2CS_MSK)
61#define CMXSMR_VALUE CMXSMR_SMC2CS_BRG8
62
63#else
64
65#error "console not correctly defined"
66
67#endif
68
Heiko Schocher327480a2009-01-30 12:55:38 +010069#if !defined(CONFIG_SYS_SMC_RXBUFLEN)
70#define CONFIG_SYS_SMC_RXBUFLEN 1
71#define CONFIG_SYS_MAXIDLE 0
72#else
73#if !defined(CONFIG_SYS_MAXIDLE)
74#error "you must define CONFIG_SYS_MAXIDLE"
75#endif
76#endif
77
78typedef volatile struct serialbuffer {
79 cbd_t rxbd; /* Rx BD */
80 cbd_t txbd; /* Tx BD */
81 uint rxindex; /* index for next character to read */
82 volatile uchar rxbuf[CONFIG_SYS_SMC_RXBUFLEN];/* rx buffers */
83 volatile uchar txbuf; /* tx buffers */
84} serialbuffer_t;
85
wdenk4a9cbbe2002-08-27 09:48:53 +000086/* map rs_table index to baud rate generator index */
87static unsigned char brg_map[] = {
88 6, /* BRG7 for SMC1 */
89 7, /* BRG8 for SMC2 */
90 0, /* BRG1 for SCC1 */
91 1, /* BRG1 for SCC2 */
92 2, /* BRG1 for SCC3 */
93 3, /* BRG1 for SCC4 */
94};
95
Marek Vasut18a47792012-09-13 01:34:16 +020096static int mpc8260_smc_serial_init(void)
wdenk4a9cbbe2002-08-27 09:48:53 +000097{
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020098 volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
wdenk4a9cbbe2002-08-27 09:48:53 +000099 volatile smc_t *sp;
100 volatile smc_uart_t *up;
wdenk4a9cbbe2002-08-27 09:48:53 +0000101 volatile cpm8260_t *cp = &(im->im_cpm);
102 uint dpaddr;
Heiko Schocher327480a2009-01-30 12:55:38 +0100103 volatile serialbuffer_t *rtx;
wdenk4a9cbbe2002-08-27 09:48:53 +0000104
105 /* initialize pointers to SMC */
106
107 sp = (smc_t *) &(im->im_smc[SMC_INDEX]);
108 *(ushort *)(&im->im_dprambase[PROFF_SMC_BASE]) = PROFF_SMC;
109 up = (smc_uart_t *)&im->im_dprambase[PROFF_SMC];
110
Heiko Schochere1873ba2009-01-30 12:56:15 +0100111 /* Disable transmitter/receiver. */
wdenk4a9cbbe2002-08-27 09:48:53 +0000112 sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
113
114 /* NOTE: I/O port pins are set up via the iop_conf_tab[] table */
115
116 /* Allocate space for two buffer descriptors in the DP ram.
117 * damm: allocating space after the two buffers for rx/tx data
118 */
Heiko Schocher327480a2009-01-30 12:55:38 +0100119
120 /* allocate size of struct serialbuffer with bd rx/tx,
121 * buffer rx/tx and rx index
122 */
123 dpaddr = m8260_cpm_dpalloc((sizeof(serialbuffer_t)), 16);
wdenk4a9cbbe2002-08-27 09:48:53 +0000124
Heiko Schocher327480a2009-01-30 12:55:38 +0100125 rtx = (serialbuffer_t *)&im->im_dprambase[dpaddr];
wdenk4a9cbbe2002-08-27 09:48:53 +0000126
127 /* Set the physical address of the host memory buffers in
128 * the buffer descriptors.
129 */
Heiko Schocher327480a2009-01-30 12:55:38 +0100130 rtx->rxbd.cbd_bufaddr = (uint) &rtx->rxbuf;
131 rtx->rxbd.cbd_sc = 0;
132
133 rtx->txbd.cbd_bufaddr = (uint) &rtx->txbuf;
134 rtx->txbd.cbd_sc = 0;
wdenk4a9cbbe2002-08-27 09:48:53 +0000135
Heiko Schochere1873ba2009-01-30 12:56:15 +0100136 /* Set up the uart parameters in the parameter ram. */
wdenk4a9cbbe2002-08-27 09:48:53 +0000137 up->smc_rbase = dpaddr;
138 up->smc_tbase = dpaddr+sizeof(cbd_t);
139 up->smc_rfcr = CPMFCR_EB;
140 up->smc_tfcr = CPMFCR_EB;
141 up->smc_brklen = 0;
142 up->smc_brkec = 0;
143 up->smc_brkcr = 0;
144
145 /* Set UART mode, 8 bit, no parity, one stop.
146 * Enable receive and transmit.
147 */
148 sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART;
149
Heiko Schochere1873ba2009-01-30 12:56:15 +0100150 /* Mask all interrupts and remove anything pending. */
wdenk4a9cbbe2002-08-27 09:48:53 +0000151 sp->smc_smcm = 0;
152 sp->smc_smce = 0xff;
153
154 /* put the SMC channel into NMSI (non multiplexd serial interface)
155 * mode and wire either BRG7 to SMC1 or BRG8 to SMC2 (15-17).
156 */
157 im->im_cpmux.cmx_smr = (im->im_cpmux.cmx_smr&~CMXSMR_MASK)|CMXSMR_VALUE;
158
Heiko Schochere1873ba2009-01-30 12:56:15 +0100159 /* Set up the baud rate generator. */
wdenk4a9cbbe2002-08-27 09:48:53 +0000160 serial_setbrg ();
161
Heiko Schochere1873ba2009-01-30 12:56:15 +0100162 /* Make the first buffer the only buffer. */
Heiko Schocher327480a2009-01-30 12:55:38 +0100163 rtx->txbd.cbd_sc |= BD_SC_WRAP;
164 rtx->rxbd.cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP;
wdenk4a9cbbe2002-08-27 09:48:53 +0000165
Heiko Schocher327480a2009-01-30 12:55:38 +0100166 /* single/multi character receive. */
167 up->smc_mrblr = CONFIG_SYS_SMC_RXBUFLEN;
168 up->smc_maxidl = CONFIG_SYS_MAXIDLE;
169 rtx->rxindex = 0;
wdenk4a9cbbe2002-08-27 09:48:53 +0000170
Heiko Schochere1873ba2009-01-30 12:56:15 +0100171 /* Initialize Tx/Rx parameters. */
wdenk4a9cbbe2002-08-27 09:48:53 +0000172
173 while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */
174 ;
175
176 cp->cp_cpcr = mk_cr_cmd(CPM_CR_SMC_PAGE, CPM_CR_SMC_SBLOCK,
177 0, CPM_CR_INIT_TRX) | CPM_CR_FLG;
178
179 while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */
180 ;
181
Heiko Schochere1873ba2009-01-30 12:56:15 +0100182 /* Enable transmitter/receiver. */
wdenk4a9cbbe2002-08-27 09:48:53 +0000183 sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN;
184
185 return (0);
186}
187
Marek Vasut18a47792012-09-13 01:34:16 +0200188static void mpc8260_smc_serial_setbrg(void)
wdenk4a9cbbe2002-08-27 09:48:53 +0000189{
wdenk4a9cbbe2002-08-27 09:48:53 +0000190#if defined(CONFIG_CONS_USE_EXTC)
191 m8260_cpm_extcbrg(brg_map[SMC_INDEX], gd->baudrate,
192 CONFIG_CONS_EXTC_RATE, CONFIG_CONS_EXTC_PINSEL);
193#else
194 m8260_cpm_setbrg(brg_map[SMC_INDEX], gd->baudrate);
195#endif
196}
197
Marek Vasut18a47792012-09-13 01:34:16 +0200198static void mpc8260_smc_serial_putc(const char c)
wdenk4a9cbbe2002-08-27 09:48:53 +0000199{
wdenk4a9cbbe2002-08-27 09:48:53 +0000200 volatile smc_uart_t *up;
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200201 volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
Heiko Schocher327480a2009-01-30 12:55:38 +0100202 volatile serialbuffer_t *rtx;
wdenk4a9cbbe2002-08-27 09:48:53 +0000203
204 if (c == '\n')
205 serial_putc ('\r');
206
207 up = (smc_uart_t *)&(im->im_dprambase[PROFF_SMC]);
208
Heiko Schocher327480a2009-01-30 12:55:38 +0100209 rtx = (serialbuffer_t *)&im->im_dprambase[up->smc_rbase];
wdenk4a9cbbe2002-08-27 09:48:53 +0000210
Heiko Schocher327480a2009-01-30 12:55:38 +0100211 /* Wait for last character to go. */
212 while (rtx->txbd.cbd_sc & BD_SC_READY & BD_SC_READY)
wdenk4a9cbbe2002-08-27 09:48:53 +0000213 ;
Heiko Schocher327480a2009-01-30 12:55:38 +0100214 rtx->txbuf = c;
215 rtx->txbd.cbd_datlen = 1;
216 rtx->txbd.cbd_sc |= BD_SC_READY;
wdenk4a9cbbe2002-08-27 09:48:53 +0000217}
218
Marek Vasut18a47792012-09-13 01:34:16 +0200219static int mpc8260_smc_serial_getc(void)
wdenk4a9cbbe2002-08-27 09:48:53 +0000220{
wdenk4a9cbbe2002-08-27 09:48:53 +0000221 volatile smc_uart_t *up;
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200222 volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
Heiko Schocher327480a2009-01-30 12:55:38 +0100223 volatile serialbuffer_t *rtx;
224 unsigned char c;
wdenk4a9cbbe2002-08-27 09:48:53 +0000225
226 up = (smc_uart_t *)&(im->im_dprambase[PROFF_SMC]);
227
Heiko Schocher327480a2009-01-30 12:55:38 +0100228 rtx = (serialbuffer_t *)&im->im_dprambase[up->smc_rbase];
wdenk4a9cbbe2002-08-27 09:48:53 +0000229
Heiko Schochere1873ba2009-01-30 12:56:15 +0100230 /* Wait for character to show up. */
Heiko Schocher327480a2009-01-30 12:55:38 +0100231 while (rtx->rxbd.cbd_sc & BD_SC_EMPTY)
wdenk4a9cbbe2002-08-27 09:48:53 +0000232 ;
wdenk4a9cbbe2002-08-27 09:48:53 +0000233
Heiko Schocher327480a2009-01-30 12:55:38 +0100234 /* the characters are read one by one,
235 * use the rxindex to know the next char to deliver
236 */
237 c = *(unsigned char *) (rtx->rxbd.cbd_bufaddr + rtx->rxindex);
238 rtx->rxindex++;
239
240 /* check if all char are readout, then make prepare for next receive */
241 if (rtx->rxindex >= rtx->rxbd.cbd_datlen) {
242 rtx->rxindex = 0;
243 rtx->rxbd.cbd_sc |= BD_SC_EMPTY;
244 }
wdenk4a9cbbe2002-08-27 09:48:53 +0000245 return(c);
246}
247
Marek Vasut18a47792012-09-13 01:34:16 +0200248static int mpc8260_smc_serial_tstc(void)
wdenk4a9cbbe2002-08-27 09:48:53 +0000249{
wdenk4a9cbbe2002-08-27 09:48:53 +0000250 volatile smc_uart_t *up;
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200251 volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
Heiko Schocher327480a2009-01-30 12:55:38 +0100252 volatile serialbuffer_t *rtx;
wdenk4a9cbbe2002-08-27 09:48:53 +0000253
254 up = (smc_uart_t *)&(im->im_dprambase[PROFF_SMC]);
Heiko Schocher327480a2009-01-30 12:55:38 +0100255 rtx = (serialbuffer_t *)&im->im_dprambase[up->smc_rbase];
wdenk4a9cbbe2002-08-27 09:48:53 +0000256
Heiko Schocher327480a2009-01-30 12:55:38 +0100257 return !(rtx->rxbd.cbd_sc & BD_SC_EMPTY);
wdenk4a9cbbe2002-08-27 09:48:53 +0000258}
259
Marek Vasut18a47792012-09-13 01:34:16 +0200260static struct serial_device mpc8260_smc_serial_drv = {
261 .name = "mpc8260_smc_uart",
262 .start = mpc8260_smc_serial_init,
263 .stop = NULL,
264 .setbrg = mpc8260_smc_serial_setbrg,
265 .putc = mpc8260_smc_serial_putc,
Marek Vasutd9c64492012-10-06 14:07:02 +0000266 .puts = default_serial_puts,
Marek Vasut18a47792012-09-13 01:34:16 +0200267 .getc = mpc8260_smc_serial_getc,
268 .tstc = mpc8260_smc_serial_tstc,
269};
270
271void mpc8260_smc_serial_initialize(void)
272{
273 serial_register(&mpc8260_smc_serial_drv);
274}
275
276__weak struct serial_device *default_serial_console(void)
277{
278 return &mpc8260_smc_serial_drv;
279}
wdenk4a9cbbe2002-08-27 09:48:53 +0000280#endif /* CONFIG_CONS_ON_SMC */
281
282#if defined(CONFIG_KGDB_ON_SMC)
283
284#if defined(CONFIG_CONS_ON_SMC) && CONFIG_KGDB_INDEX == CONFIG_CONS_INDEX
285#error Whoops! serial console and kgdb are on the same smc serial port
286#endif
287
288#if CONFIG_KGDB_INDEX == 1 /* KGDB Port on SMC1 */
289
290#define KGDB_SMC_INDEX 0
291#define KGDB_PROFF_SMC_BASE PROFF_SMC1_BASE
292#define KGDB_PROFF_SMC PROFF_SMC1
293#define KGDB_CPM_CR_SMC_PAGE CPM_CR_SMC1_PAGE
294#define KGDB_CPM_CR_SMC_SBLOCK CPM_CR_SMC1_SBLOCK
295#define KGDB_CMXSMR_MASK (CMXSMR_SMC1|CMXSMR_SMC1CS_MSK)
296#define KGDB_CMXSMR_VALUE CMXSMR_SMC1CS_BRG7
297
298#elif CONFIG_KGDB_INDEX == 2 /* KGDB Port on SMC2 */
299
300#define KGDB_SMC_INDEX 1
301#define KGDB_PROFF_SMC_BASE PROFF_SMC2_BASE
302#define KGDB_PROFF_SMC PROFF_SMC2
303#define KGDB_CPM_CR_SMC_PAGE CPM_CR_SMC2_PAGE
304#define KGDB_CPM_CR_SMC_SBLOCK CPM_CR_SMC2_SBLOCK
305#define KGDB_CMXSMR_MASK (CMXSMR_SMC2|CMXSMR_SMC2CS_MSK)
306#define KGDB_CMXSMR_VALUE CMXSMR_SMC2CS_BRG8
307
308#else
309
310#error "console not correctly defined"
311
312#endif
313
314void
315kgdb_serial_init (void)
316{
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200317 volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
wdenk4a9cbbe2002-08-27 09:48:53 +0000318 volatile smc_t *sp;
319 volatile smc_uart_t *up;
320 volatile cbd_t *tbdf, *rbdf;
321 volatile cpm8260_t *cp = &(im->im_cpm);
322 uint dpaddr, speed = CONFIG_KGDB_BAUDRATE;
323 char *s, *e;
324
325 if ((s = getenv("kgdbrate")) != NULL && *s != '\0') {
326 ulong rate = simple_strtoul(s, &e, 10);
327 if (e > s && *e == '\0')
328 speed = rate;
329 }
330
331 /* initialize pointers to SMC */
332
333 sp = (smc_t *) &(im->im_smc[KGDB_SMC_INDEX]);
334 *(ushort *)(&im->im_dprambase[KGDB_PROFF_SMC_BASE]) = KGDB_PROFF_SMC;
335 up = (smc_uart_t *)&im->im_dprambase[KGDB_PROFF_SMC];
336
Heiko Schochere1873ba2009-01-30 12:56:15 +0100337 /* Disable transmitter/receiver. */
wdenk4a9cbbe2002-08-27 09:48:53 +0000338 sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
339
340 /* NOTE: I/O port pins are set up via the iop_conf_tab[] table */
341
342 /* Allocate space for two buffer descriptors in the DP ram.
343 * damm: allocating space after the two buffers for rx/tx data
344 */
345
346 dpaddr = m8260_cpm_dpalloc((2 * sizeof (cbd_t)) + 2, 16);
347
348 /* Set the physical address of the host memory buffers in
349 * the buffer descriptors.
350 */
351 rbdf = (cbd_t *)&im->im_dprambase[dpaddr];
352 rbdf->cbd_bufaddr = (uint) (rbdf+2);
353 rbdf->cbd_sc = 0;
354 tbdf = rbdf + 1;
355 tbdf->cbd_bufaddr = ((uint) (rbdf+2)) + 1;
356 tbdf->cbd_sc = 0;
357
Heiko Schochere1873ba2009-01-30 12:56:15 +0100358 /* Set up the uart parameters in the parameter ram. */
wdenk4a9cbbe2002-08-27 09:48:53 +0000359 up->smc_rbase = dpaddr;
360 up->smc_tbase = dpaddr+sizeof(cbd_t);
361 up->smc_rfcr = CPMFCR_EB;
362 up->smc_tfcr = CPMFCR_EB;
363 up->smc_brklen = 0;
364 up->smc_brkec = 0;
365 up->smc_brkcr = 0;
366
367 /* Set UART mode, 8 bit, no parity, one stop.
368 * Enable receive and transmit.
369 */
370 sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART;
371
Heiko Schochere1873ba2009-01-30 12:56:15 +0100372 /* Mask all interrupts and remove anything pending. */
wdenk4a9cbbe2002-08-27 09:48:53 +0000373 sp->smc_smcm = 0;
374 sp->smc_smce = 0xff;
375
376 /* put the SMC channel into NMSI (non multiplexd serial interface)
377 * mode and wire either BRG7 to SMC1 or BRG8 to SMC2 (15-17).
378 */
379 im->im_cpmux.cmx_smr =
380 (im->im_cpmux.cmx_smr & ~KGDB_CMXSMR_MASK) | KGDB_CMXSMR_VALUE;
381
Heiko Schochere1873ba2009-01-30 12:56:15 +0100382 /* Set up the baud rate generator. */
wdenk4a9cbbe2002-08-27 09:48:53 +0000383#if defined(CONFIG_KGDB_USE_EXTC)
Wolfgang Denkaaa85952005-08-06 01:21:19 +0200384 m8260_cpm_extcbrg(brg_map[KGDB_SMC_INDEX], speed,
wdenk4a9cbbe2002-08-27 09:48:53 +0000385 CONFIG_KGDB_EXTC_RATE, CONFIG_KGDB_EXTC_PINSEL);
386#else
Wolfgang Denkaaa85952005-08-06 01:21:19 +0200387 m8260_cpm_setbrg(brg_map[KGDB_SMC_INDEX], speed);
wdenk4a9cbbe2002-08-27 09:48:53 +0000388#endif
389
Heiko Schochere1873ba2009-01-30 12:56:15 +0100390 /* Make the first buffer the only buffer. */
wdenk4a9cbbe2002-08-27 09:48:53 +0000391 tbdf->cbd_sc |= BD_SC_WRAP;
392 rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP;
393
Heiko Schochere1873ba2009-01-30 12:56:15 +0100394 /* Single character receive. */
wdenk4a9cbbe2002-08-27 09:48:53 +0000395 up->smc_mrblr = 1;
396 up->smc_maxidl = 0;
397
Heiko Schochere1873ba2009-01-30 12:56:15 +0100398 /* Initialize Tx/Rx parameters. */
wdenk4a9cbbe2002-08-27 09:48:53 +0000399
400 while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */
401 ;
402
403 cp->cp_cpcr = mk_cr_cmd(KGDB_CPM_CR_SMC_PAGE, KGDB_CPM_CR_SMC_SBLOCK,
404 0, CPM_CR_INIT_TRX) | CPM_CR_FLG;
405
406 while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */
407 ;
408
Heiko Schochere1873ba2009-01-30 12:56:15 +0100409 /* Enable transmitter/receiver. */
wdenk4a9cbbe2002-08-27 09:48:53 +0000410 sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN;
411
412 printf("SMC%d at %dbps ", CONFIG_KGDB_INDEX, speed);
413}
414
415void
416putDebugChar(const char c)
417{
418 volatile cbd_t *tbdf;
419 volatile char *buf;
420 volatile smc_uart_t *up;
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200421 volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
wdenk4a9cbbe2002-08-27 09:48:53 +0000422
423 if (c == '\n')
424 putDebugChar ('\r');
425
426 up = (smc_uart_t *)&(im->im_dprambase[KGDB_PROFF_SMC]);
427
428 tbdf = (cbd_t *)&im->im_dprambase[up->smc_tbase];
429
Heiko Schochere1873ba2009-01-30 12:56:15 +0100430 /* Wait for last character to go. */
wdenk4a9cbbe2002-08-27 09:48:53 +0000431 buf = (char *)tbdf->cbd_bufaddr;
432 while (tbdf->cbd_sc & BD_SC_READY)
433 ;
434
435 *buf = c;
436 tbdf->cbd_datlen = 1;
437 tbdf->cbd_sc |= BD_SC_READY;
438}
439
440void
441putDebugStr (const char *s)
442{
443 while (*s) {
444 putDebugChar (*s++);
445 }
446}
447
448int
449getDebugChar(void)
450{
451 volatile cbd_t *rbdf;
452 volatile unsigned char *buf;
453 volatile smc_uart_t *up;
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200454 volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
wdenk4a9cbbe2002-08-27 09:48:53 +0000455 unsigned char c;
456
457 up = (smc_uart_t *)&(im->im_dprambase[KGDB_PROFF_SMC]);
458
459 rbdf = (cbd_t *)&im->im_dprambase[up->smc_rbase];
460
Heiko Schochere1873ba2009-01-30 12:56:15 +0100461 /* Wait for character to show up. */
wdenk4a9cbbe2002-08-27 09:48:53 +0000462 buf = (unsigned char *)rbdf->cbd_bufaddr;
463 while (rbdf->cbd_sc & BD_SC_EMPTY)
464 ;
465 c = *buf;
466 rbdf->cbd_sc |= BD_SC_EMPTY;
467
468 return(c);
469}
470
471void
472kgdb_interruptible(int yes)
473{
474 return;
475}
476
477#endif /* CONFIG_KGDB_ON_SMC */