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