]> git.karo-electronics.de Git - karo-tx-uboot.git/blob - arch/powerpc/cpu/mpc8xx/serial.c
serial: push default_serial_console to drivers
[karo-tx-uboot.git] / arch / powerpc / cpu / mpc8xx / serial.c
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
24 #include <common.h>
25 #include <commproc.h>
26 #include <command.h>
27 #include <serial.h>
28 #include <watchdog.h>
29 #include <linux/compiler.h>
30
31 DECLARE_GLOBAL_DATA_PTR;
32
33 #if !defined(CONFIG_8xx_CONS_NONE)      /* No Console at all */
34
35 #if defined(CONFIG_8xx_CONS_SMC1)       /* Console on SMC1 */
36 #define SMC_INDEX       0
37 #define PROFF_SMC       PROFF_SMC1
38 #define CPM_CR_CH_SMC   CPM_CR_CH_SMC1
39
40 #elif defined(CONFIG_8xx_CONS_SMC2)     /* Console on SMC2 */
41 #define SMC_INDEX       1
42 #define PROFF_SMC       PROFF_SMC2
43 #define CPM_CR_CH_SMC   CPM_CR_CH_SMC2
44
45 #endif /* CONFIG_8xx_CONS_SMCx */
46
47 #if defined(CONFIG_8xx_CONS_SCC1)       /* Console on SCC1 */
48 #define SCC_INDEX       0
49 #define PROFF_SCC       PROFF_SCC1
50 #define CPM_CR_CH_SCC   CPM_CR_CH_SCC1
51
52 #elif defined(CONFIG_8xx_CONS_SCC2)     /* Console on SCC2 */
53 #define SCC_INDEX       1
54 #define PROFF_SCC       PROFF_SCC2
55 #define CPM_CR_CH_SCC   CPM_CR_CH_SCC2
56
57 #elif defined(CONFIG_8xx_CONS_SCC3)     /* Console on SCC3 */
58 #define SCC_INDEX       2
59 #define PROFF_SCC       PROFF_SCC3
60 #define CPM_CR_CH_SCC   CPM_CR_CH_SCC3
61
62 #elif defined(CONFIG_8xx_CONS_SCC4)     /* Console on SCC4 */
63 #define SCC_INDEX       3
64 #define PROFF_SCC       PROFF_SCC4
65 #define CPM_CR_CH_SCC   CPM_CR_CH_SCC4
66
67 #endif /* CONFIG_8xx_CONS_SCCx */
68
69 #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
78 typedef 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
86 static void serial_setdivisor(volatile cpm8xx_t *cp)
87 {
88         int divisor=(gd->cpu_clk + 8*gd->baudrate)/16/gd->baudrate;
89
90         if(divisor/16>0x1000) {
91                 /* bad divisor, assume 50MHz clock and 9600 baud */
92                 divisor=(50*1000*1000 + 8*9600)/16/9600;
93         }
94
95 #ifdef CONFIG_SYS_BRGCLK_PRESCALE
96         divisor /= CONFIG_SYS_BRGCLK_PRESCALE;
97 #endif
98
99         if(divisor<=0x1000) {
100                 cp->cp_brgc1=((divisor-1)<<1) | CPM_BRG_EN;
101         } else {
102                 cp->cp_brgc1=((divisor/16-1)<<1) | CPM_BRG_EN | CPM_BRG_DIV16;
103         }
104 }
105
106 #if (defined (CONFIG_8xx_CONS_SMC1) || defined (CONFIG_8xx_CONS_SMC2))
107
108 /*
109  * Minimal serial functions needed to use one of the SMC ports
110  * as serial console interface.
111  */
112
113 static void smc_setbrg (void)
114 {
115         volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
116         volatile cpm8xx_t *cp = &(im->im_cpm);
117
118         /* Set up the baud rate generator.
119          * See 8xx_io/commproc.c for details.
120          *
121          * Wire BRG1 to SMCx
122          */
123
124         cp->cp_simode = 0x00000000;
125
126         serial_setdivisor(cp);
127 }
128
129 static int smc_init (void)
130 {
131         volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
132         volatile smc_t *sp;
133         volatile smc_uart_t *up;
134         volatile cpm8xx_t *cp = &(im->im_cpm);
135 #if (!defined(CONFIG_8xx_CONS_SMC1)) && (defined(CONFIG_MPC823) || defined(CONFIG_MPC850))
136         volatile iop8xx_t *ip = (iop8xx_t *)&(im->im_ioport);
137 #endif
138         uint    dpaddr;
139         volatile serialbuffer_t *rtx;
140
141         /* initialize pointers to SMC */
142
143         sp = (smc_t *) &(cp->cp_smc[SMC_INDEX]);
144         up = (smc_uart_t *) &cp->cp_dparam[PROFF_SMC];
145 #ifdef CONFIG_SYS_SMC_UCODE_PATCH
146         up = (smc_uart_t *) &cp->cp_dpmem[up->smc_rpbase];
147 #else
148         /* Disable relocation */
149         up->smc_rpbase = 0;
150 #endif
151
152         /* Disable transmitter/receiver. */
153         sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
154
155         /* Enable SDMA. */
156         im->im_siu_conf.sc_sdcr = 1;
157
158         /* clear error conditions */
159 #ifdef  CONFIG_SYS_SDSR
160         im->im_sdma.sdma_sdsr = CONFIG_SYS_SDSR;
161 #else
162         im->im_sdma.sdma_sdsr = 0x83;
163 #endif
164
165         /* clear SDMA interrupt mask */
166 #ifdef  CONFIG_SYS_SDMR
167         im->im_sdma.sdma_sdmr = CONFIG_SYS_SDMR;
168 #else
169         im->im_sdma.sdma_sdmr = 0x00;
170 #endif
171
172 #if defined(CONFIG_8xx_CONS_SMC1)
173         /* Use Port B for SMC1 instead of other functions. */
174         cp->cp_pbpar |=  0x000000c0;
175         cp->cp_pbdir &= ~0x000000c0;
176         cp->cp_pbodr &= ~0x000000c0;
177 #else   /* CONFIG_8xx_CONS_SMC2 */
178 # if defined(CONFIG_MPC823) || defined(CONFIG_MPC850)
179         /* Use Port A for SMC2 instead of other functions. */
180         ip->iop_papar |=  0x00c0;
181         ip->iop_padir &= ~0x00c0;
182         ip->iop_paodr &= ~0x00c0;
183 # else  /* must be a 860 then */
184         /* Use Port B for SMC2 instead of other functions.
185          */
186         cp->cp_pbpar |=  0x00000c00;
187         cp->cp_pbdir &= ~0x00000c00;
188         cp->cp_pbodr &= ~0x00000c00;
189 # endif
190 #endif
191
192 #if defined(CONFIG_FADS) || defined(CONFIG_ADS)
193         /* Enable RS232 */
194 #if defined(CONFIG_8xx_CONS_SMC1)
195         *((uint *) BCSR1) &= ~BCSR1_RS232EN_1;
196 #else
197         *((uint *) BCSR1) &= ~BCSR1_RS232EN_2;
198 #endif
199 #endif  /* CONFIG_FADS */
200
201 #if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC)
202         /* Enable Monitor Port Transceiver */
203         *((uchar *) BCSR0) |= BCSR0_ENMONXCVR ;
204 #endif /* CONFIG_RPXLITE */
205
206         /* Set the physical address of the host memory buffers in
207          * the buffer descriptors.
208          */
209
210 #ifdef CONFIG_SYS_ALLOC_DPRAM
211         /* allocate
212          * size of struct serialbuffer with bd rx/tx, buffer rx/tx and rx index
213          */
214         dpaddr = dpram_alloc_align((sizeof(serialbuffer_t)), 8);
215 #else
216         dpaddr = CPM_SERIAL_BASE ;
217 #endif
218
219         rtx = (serialbuffer_t *)&cp->cp_dpmem[dpaddr];
220         /* Allocate space for two buffer descriptors in the DP ram.
221          * For now, this address seems OK, but it may have to
222          * change with newer versions of the firmware.
223          * damm: allocating space after the two buffers for rx/tx data
224          */
225
226         rtx->rxbd.cbd_bufaddr = (uint) &rtx->rxbuf;
227         rtx->rxbd.cbd_sc      = 0;
228
229         rtx->txbd.cbd_bufaddr = (uint) &rtx->txbuf;
230         rtx->txbd.cbd_sc      = 0;
231
232         /* Set up the uart parameters in the parameter ram. */
233         up->smc_rbase = dpaddr;
234         up->smc_tbase = dpaddr+sizeof(cbd_t);
235         up->smc_rfcr = SMC_EB;
236         up->smc_tfcr = SMC_EB;
237 #if defined (CONFIG_SYS_SMC_UCODE_PATCH)
238         up->smc_rbptr = up->smc_rbase;
239         up->smc_tbptr = up->smc_tbase;
240         up->smc_rstate = 0;
241         up->smc_tstate = 0;
242 #endif
243
244 #if defined(CONFIG_MBX)
245         board_serial_init();
246 #endif  /* CONFIG_MBX */
247
248         /* Set UART mode, 8 bit, no parity, one stop.
249          * Enable receive and transmit.
250          */
251         sp->smc_smcmr = smcr_mk_clen(9) |  SMCMR_SM_UART;
252
253         /* Mask all interrupts and remove anything pending.
254         */
255         sp->smc_smcm = 0;
256         sp->smc_smce = 0xff;
257
258 #ifdef CONFIG_SYS_SPC1920_SMC1_CLK4
259         /* clock source is PLD */
260
261         /* set freq to 19200 Baud */
262         *((volatile uchar *) CONFIG_SYS_SPC1920_PLD_BASE+6) = 0x3;
263         /* configure clk4 as input */
264         im->im_ioport.iop_pdpar |= 0x800;
265         im->im_ioport.iop_pddir &= ~0x800;
266
267         cp->cp_simode = ((cp->cp_simode & ~0xf000) | 0x7000);
268 #else
269         /* Set up the baud rate generator */
270         smc_setbrg ();
271 #endif
272
273         /* Make the first buffer the only buffer. */
274         rtx->txbd.cbd_sc |= BD_SC_WRAP;
275         rtx->rxbd.cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP;
276
277         /* single/multi character receive. */
278         up->smc_mrblr = CONFIG_SYS_SMC_RXBUFLEN;
279         up->smc_maxidl = CONFIG_SYS_MAXIDLE;
280         rtx->rxindex = 0;
281
282         /* Initialize Tx/Rx parameters. */
283         while (cp->cp_cpcr & CPM_CR_FLG)  /* wait if cp is busy */
284           ;
285
286         cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC, CPM_CR_INIT_TRX) | CPM_CR_FLG;
287
288         while (cp->cp_cpcr & CPM_CR_FLG)  /* wait if cp is busy */
289           ;
290
291         /* Enable transmitter/receiver. */
292         sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN;
293
294         return (0);
295 }
296
297 static void
298 smc_putc(const char c)
299 {
300         volatile smc_uart_t     *up;
301         volatile immap_t        *im = (immap_t *)CONFIG_SYS_IMMR;
302         volatile cpm8xx_t       *cpmp = &(im->im_cpm);
303         volatile serialbuffer_t *rtx;
304
305 #ifdef CONFIG_MODEM_SUPPORT
306         if (gd->be_quiet)
307                 return;
308 #endif
309
310         if (c == '\n')
311                 smc_putc ('\r');
312
313         up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_SMC];
314 #ifdef CONFIG_SYS_SMC_UCODE_PATCH
315         up = (smc_uart_t *) &cpmp->cp_dpmem[up->smc_rpbase];
316 #endif
317
318         rtx = (serialbuffer_t *)&cpmp->cp_dpmem[up->smc_rbase];
319
320         /* Wait for last character to go. */
321         rtx->txbuf = c;
322         rtx->txbd.cbd_datlen = 1;
323         rtx->txbd.cbd_sc |= BD_SC_READY;
324         __asm__("eieio");
325
326         while (rtx->txbd.cbd_sc & BD_SC_READY) {
327                 WATCHDOG_RESET ();
328                 __asm__("eieio");
329         }
330 }
331
332 static void
333 smc_puts (const char *s)
334 {
335         while (*s) {
336                 smc_putc (*s++);
337         }
338 }
339
340 static int
341 smc_getc(void)
342 {
343         volatile smc_uart_t     *up;
344         volatile immap_t        *im = (immap_t *)CONFIG_SYS_IMMR;
345         volatile cpm8xx_t       *cpmp = &(im->im_cpm);
346         volatile serialbuffer_t *rtx;
347         unsigned char  c;
348
349         up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_SMC];
350 #ifdef CONFIG_SYS_SMC_UCODE_PATCH
351         up = (smc_uart_t *) &cpmp->cp_dpmem[up->smc_rpbase];
352 #endif
353         rtx = (serialbuffer_t *)&cpmp->cp_dpmem[up->smc_rbase];
354
355         /* Wait for character to show up. */
356         while (rtx->rxbd.cbd_sc & BD_SC_EMPTY)
357                 WATCHDOG_RESET ();
358
359         /* the characters are read one by one,
360          * use the rxindex to know the next char to deliver
361          */
362         c = *(unsigned char *) (rtx->rxbd.cbd_bufaddr+rtx->rxindex);
363         rtx->rxindex++;
364
365         /* check if all char are readout, then make prepare for next receive */
366         if (rtx->rxindex >= rtx->rxbd.cbd_datlen) {
367                 rtx->rxindex = 0;
368                 rtx->rxbd.cbd_sc |= BD_SC_EMPTY;
369         }
370         return(c);
371 }
372
373 static int
374 smc_tstc(void)
375 {
376         volatile smc_uart_t     *up;
377         volatile immap_t        *im = (immap_t *)CONFIG_SYS_IMMR;
378         volatile cpm8xx_t       *cpmp = &(im->im_cpm);
379         volatile serialbuffer_t *rtx;
380
381         up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_SMC];
382 #ifdef CONFIG_SYS_SMC_UCODE_PATCH
383         up = (smc_uart_t *) &cpmp->cp_dpmem[up->smc_rpbase];
384 #endif
385
386         rtx = (serialbuffer_t *)&cpmp->cp_dpmem[up->smc_rbase];
387
388         return !(rtx->rxbd.cbd_sc & BD_SC_EMPTY);
389 }
390
391 struct serial_device serial_smc_device =
392 {
393         "serial_smc",
394         "SMC",
395         smc_init,
396         NULL,
397         smc_setbrg,
398         smc_getc,
399         smc_tstc,
400         smc_putc,
401         smc_puts,
402 };
403
404 #endif /* CONFIG_8xx_CONS_SMC1 || CONFIG_8xx_CONS_SMC2 */
405
406 #if defined(CONFIG_8xx_CONS_SCC1) || defined(CONFIG_8xx_CONS_SCC2) || \
407     defined(CONFIG_8xx_CONS_SCC3) || defined(CONFIG_8xx_CONS_SCC4)
408
409 static void
410 scc_setbrg (void)
411 {
412         volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
413         volatile cpm8xx_t *cp = &(im->im_cpm);
414
415         /* Set up the baud rate generator.
416          * See 8xx_io/commproc.c for details.
417          *
418          * Wire BRG1 to SCCx
419          */
420
421         cp->cp_sicr &= ~(0x000000FF << (8 * SCC_INDEX));
422
423         serial_setdivisor(cp);
424 }
425
426 static int scc_init (void)
427 {
428         volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
429         volatile scc_t *sp;
430         volatile scc_uart_t *up;
431         volatile cbd_t *tbdf, *rbdf;
432         volatile cpm8xx_t *cp = &(im->im_cpm);
433         uint     dpaddr;
434 #if (SCC_INDEX != 2) || !defined(CONFIG_MPC850)
435         volatile iop8xx_t *ip = (iop8xx_t *)&(im->im_ioport);
436 #endif
437
438         /* initialize pointers to SCC */
439
440         sp = (scc_t *) &(cp->cp_scc[SCC_INDEX]);
441         up = (scc_uart_t *) &cp->cp_dparam[PROFF_SCC];
442
443 #if defined(CONFIG_LWMON) && defined(CONFIG_8xx_CONS_SCC2)
444     {   /* Disable Ethernet, enable Serial */
445         uchar c;
446
447         c = pic_read  (0x61);
448         c &= ~0x40;     /* enable COM3 */
449         c |=  0x80;     /* disable Ethernet */
450         pic_write (0x61, c);
451
452         /* enable RTS2 */
453         cp->cp_pbpar |=  0x2000;
454         cp->cp_pbdat |=  0x2000;
455         cp->cp_pbdir |=  0x2000;
456     }
457 #endif  /* CONFIG_LWMON */
458
459         /* Disable transmitter/receiver. */
460         sp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
461
462 #if (SCC_INDEX == 2) && defined(CONFIG_MPC850)
463         /*
464          * The MPC850 has SCC3 on Port B
465          */
466         cp->cp_pbpar |=  0x06;
467         cp->cp_pbdir &= ~0x06;
468         cp->cp_pbodr &= ~0x06;
469
470 #elif (SCC_INDEX < 2) || !defined(CONFIG_IP860)
471         /*
472          * Standard configuration for SCC's is on Part A
473          */
474         ip->iop_papar |=  ((3 << (2 * SCC_INDEX)));
475         ip->iop_padir &= ~((3 << (2 * SCC_INDEX)));
476         ip->iop_paodr &= ~((3 << (2 * SCC_INDEX)));
477 #else
478         /*
479          * The IP860 has SCC3 and SCC4 on Port D
480          */
481         ip->iop_pdpar |=  ((3 << (2 * SCC_INDEX)));
482 #endif
483
484         /* Allocate space for two buffer descriptors in the DP ram. */
485
486 #ifdef CONFIG_SYS_ALLOC_DPRAM
487         dpaddr = dpram_alloc_align (sizeof(cbd_t)*2 + 2, 8) ;
488 #else
489         dpaddr = CPM_SERIAL2_BASE ;
490 #endif
491
492         /* Enable SDMA. */
493         im->im_siu_conf.sc_sdcr = 0x0001;
494
495         /* Set the physical address of the host memory buffers in
496          * the buffer descriptors.
497          */
498
499         rbdf = (cbd_t *)&cp->cp_dpmem[dpaddr];
500         rbdf->cbd_bufaddr = (uint) (rbdf+2);
501         rbdf->cbd_sc = 0;
502         tbdf = rbdf + 1;
503         tbdf->cbd_bufaddr = ((uint) (rbdf+2)) + 1;
504         tbdf->cbd_sc = 0;
505
506         /* Set up the baud rate generator. */
507         scc_setbrg ();
508
509         /* Set up the uart parameters in the parameter ram. */
510         up->scc_genscc.scc_rbase = dpaddr;
511         up->scc_genscc.scc_tbase = dpaddr+sizeof(cbd_t);
512
513         /* Initialize Tx/Rx parameters. */
514         while (cp->cp_cpcr & CPM_CR_FLG)  /* wait if cp is busy */
515                 ;
516         cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SCC, CPM_CR_INIT_TRX) | CPM_CR_FLG;
517
518         while (cp->cp_cpcr & CPM_CR_FLG)  /* wait if cp is busy */
519                 ;
520
521         up->scc_genscc.scc_rfcr  = SCC_EB | 0x05;
522         up->scc_genscc.scc_tfcr  = SCC_EB | 0x05;
523
524         up->scc_genscc.scc_mrblr = 1;   /* Single character receive */
525         up->scc_maxidl = 0;             /* disable max idle */
526         up->scc_brkcr  = 1;             /* send one break character on stop TX */
527         up->scc_parec  = 0;
528         up->scc_frmec  = 0;
529         up->scc_nosec  = 0;
530         up->scc_brkec  = 0;
531         up->scc_uaddr1 = 0;
532         up->scc_uaddr2 = 0;
533         up->scc_toseq  = 0;
534         up->scc_char1  = 0x8000;
535         up->scc_char2  = 0x8000;
536         up->scc_char3  = 0x8000;
537         up->scc_char4  = 0x8000;
538         up->scc_char5  = 0x8000;
539         up->scc_char6  = 0x8000;
540         up->scc_char7  = 0x8000;
541         up->scc_char8  = 0x8000;
542         up->scc_rccm   = 0xc0ff;
543
544         /* Set low latency / small fifo. */
545         sp->scc_gsmrh = SCC_GSMRH_RFW;
546
547         /* Set SCC(x) clock mode to 16x
548          * See 8xx_io/commproc.c for details.
549          *
550          * Wire BRG1 to SCCn
551          */
552
553         /* Set UART mode, clock divider 16 on Tx and Rx */
554         sp->scc_gsmrl &= ~0xF;
555         sp->scc_gsmrl |=
556                 (SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16);
557
558         sp->scc_psmr  = 0;
559         sp->scc_psmr  |= SCU_PSMR_CL;
560
561         /* Mask all interrupts and remove anything pending. */
562         sp->scc_sccm = 0;
563         sp->scc_scce = 0xffff;
564         sp->scc_dsr  = 0x7e7e;
565         sp->scc_psmr = 0x3000;
566
567         /* Make the first buffer the only buffer. */
568         tbdf->cbd_sc |= BD_SC_WRAP;
569         rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP;
570
571         /* Enable transmitter/receiver. */
572         sp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
573
574         return (0);
575 }
576
577 static void
578 scc_putc(const char c)
579 {
580         volatile cbd_t          *tbdf;
581         volatile char           *buf;
582         volatile scc_uart_t     *up;
583         volatile immap_t        *im = (immap_t *)CONFIG_SYS_IMMR;
584         volatile cpm8xx_t       *cpmp = &(im->im_cpm);
585
586 #ifdef CONFIG_MODEM_SUPPORT
587         if (gd->be_quiet)
588                 return;
589 #endif
590
591         if (c == '\n')
592                 scc_putc ('\r');
593
594         up = (scc_uart_t *)&cpmp->cp_dparam[PROFF_SCC];
595
596         tbdf = (cbd_t *)&cpmp->cp_dpmem[up->scc_genscc.scc_tbase];
597
598         /* Wait for last character to go. */
599
600         buf = (char *)tbdf->cbd_bufaddr;
601
602         *buf = c;
603         tbdf->cbd_datlen = 1;
604         tbdf->cbd_sc |= BD_SC_READY;
605         __asm__("eieio");
606
607         while (tbdf->cbd_sc & BD_SC_READY) {
608                 __asm__("eieio");
609                 WATCHDOG_RESET ();
610         }
611 }
612
613 static void
614 scc_puts (const char *s)
615 {
616         while (*s) {
617                 scc_putc (*s++);
618         }
619 }
620
621 static int
622 scc_getc(void)
623 {
624         volatile cbd_t          *rbdf;
625         volatile unsigned char  *buf;
626         volatile scc_uart_t     *up;
627         volatile immap_t        *im = (immap_t *)CONFIG_SYS_IMMR;
628         volatile cpm8xx_t       *cpmp = &(im->im_cpm);
629         unsigned char           c;
630
631         up = (scc_uart_t *)&cpmp->cp_dparam[PROFF_SCC];
632
633         rbdf = (cbd_t *)&cpmp->cp_dpmem[up->scc_genscc.scc_rbase];
634
635         /* Wait for character to show up. */
636         buf = (unsigned char *)rbdf->cbd_bufaddr;
637
638         while (rbdf->cbd_sc & BD_SC_EMPTY)
639                 WATCHDOG_RESET ();
640
641         c = *buf;
642         rbdf->cbd_sc |= BD_SC_EMPTY;
643
644         return(c);
645 }
646
647 static int
648 scc_tstc(void)
649 {
650         volatile cbd_t          *rbdf;
651         volatile scc_uart_t     *up;
652         volatile immap_t        *im = (immap_t *)CONFIG_SYS_IMMR;
653         volatile cpm8xx_t       *cpmp = &(im->im_cpm);
654
655         up = (scc_uart_t *)&cpmp->cp_dparam[PROFF_SCC];
656
657         rbdf = (cbd_t *)&cpmp->cp_dpmem[up->scc_genscc.scc_rbase];
658
659         return(!(rbdf->cbd_sc & BD_SC_EMPTY));
660 }
661
662 struct serial_device serial_scc_device =
663 {
664         "serial_scc",
665         "SCC",
666         scc_init,
667         NULL,
668         scc_setbrg,
669         scc_getc,
670         scc_tstc,
671         scc_putc,
672         scc_puts,
673 };
674
675 #endif  /* CONFIG_8xx_CONS_SCCx */
676
677 __weak struct serial_device *default_serial_console(void)
678 {
679 #if defined(CONFIG_8xx_CONS_SMC1) || defined(CONFIG_8xx_CONS_SMC2)
680         return &serial_smc_device;
681 #else
682         return &serial_scc_device;
683 #endif
684 }
685
686 #ifdef CONFIG_MODEM_SUPPORT
687 void disable_putc(void)
688 {
689         gd->be_quiet = 1;
690 }
691
692 void enable_putc(void)
693 {
694         gd->be_quiet = 0;
695 }
696 #endif
697
698 #if defined(CONFIG_CMD_KGDB)
699
700 void
701 kgdb_serial_init(void)
702 {
703         int i = -1;
704
705         if (strcmp(default_serial_console()->ctlr, "SMC") == 0)
706         {
707 #if defined(CONFIG_8xx_CONS_SMC1)
708                 i = 1;
709 #elif defined(CONFIG_8xx_CONS_SMC2)
710                 i = 2;
711 #endif
712         }
713         else if (strcmp(default_serial_console()->ctlr, "SMC") == 0)
714         {
715 #if defined(CONFIG_8xx_CONS_SCC1)
716                 i = 1;
717 #elif defined(CONFIG_8xx_CONS_SCC2)
718                 i = 2;
719 #elif defined(CONFIG_8xx_CONS_SCC3)
720                 i = 3;
721 #elif defined(CONFIG_8xx_CONS_SCC4)
722                 i = 4;
723 #endif
724         }
725
726         if (i >= 0)
727         {
728                 serial_printf("[on %s%d] ", default_serial_console()->ctlr, i);
729         }
730 }
731
732 void
733 putDebugChar (int c)
734 {
735         serial_putc (c);
736 }
737
738 void
739 putDebugStr (const char *str)
740 {
741         serial_puts (str);
742 }
743
744 int
745 getDebugChar (void)
746 {
747         return serial_getc();
748 }
749
750 void
751 kgdb_interruptible (int yes)
752 {
753         return;
754 }
755 #endif
756
757 #endif  /* CONFIG_8xx_CONS_NONE */