]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/powerpc/cpu/mpc8xx/serial.c
Merge branch 'master' of git://git.denx.de/u-boot-arm
[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
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         NULL,
396         smc_setbrg,
397         smc_getc,
398         smc_tstc,
399         smc_putc,
400         smc_puts,
401 };
402
403 #endif /* CONFIG_8xx_CONS_SMC1 || CONFIG_8xx_CONS_SMC2 */
404
405 #if defined(CONFIG_8xx_CONS_SCC1) || defined(CONFIG_8xx_CONS_SCC2) || \
406     defined(CONFIG_8xx_CONS_SCC3) || defined(CONFIG_8xx_CONS_SCC4)
407
408 static void
409 scc_setbrg (void)
410 {
411         volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
412         volatile cpm8xx_t *cp = &(im->im_cpm);
413
414         /* Set up the baud rate generator.
415          * See 8xx_io/commproc.c for details.
416          *
417          * Wire BRG1 to SCCx
418          */
419
420         cp->cp_sicr &= ~(0x000000FF << (8 * SCC_INDEX));
421
422         serial_setdivisor(cp);
423 }
424
425 static int scc_init (void)
426 {
427         volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
428         volatile scc_t *sp;
429         volatile scc_uart_t *up;
430         volatile cbd_t *tbdf, *rbdf;
431         volatile cpm8xx_t *cp = &(im->im_cpm);
432         uint     dpaddr;
433 #if (SCC_INDEX != 2) || !defined(CONFIG_MPC850)
434         volatile iop8xx_t *ip = (iop8xx_t *)&(im->im_ioport);
435 #endif
436
437         /* initialize pointers to SCC */
438
439         sp = (scc_t *) &(cp->cp_scc[SCC_INDEX]);
440         up = (scc_uart_t *) &cp->cp_dparam[PROFF_SCC];
441
442 #if defined(CONFIG_LWMON) && defined(CONFIG_8xx_CONS_SCC2)
443     {   /* Disable Ethernet, enable Serial */
444         uchar c;
445
446         c = pic_read  (0x61);
447         c &= ~0x40;     /* enable COM3 */
448         c |=  0x80;     /* disable Ethernet */
449         pic_write (0x61, c);
450
451         /* enable RTS2 */
452         cp->cp_pbpar |=  0x2000;
453         cp->cp_pbdat |=  0x2000;
454         cp->cp_pbdir |=  0x2000;
455     }
456 #endif  /* CONFIG_LWMON */
457
458         /* Disable transmitter/receiver. */
459         sp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
460
461 #if (SCC_INDEX == 2) && defined(CONFIG_MPC850)
462         /*
463          * The MPC850 has SCC3 on Port B
464          */
465         cp->cp_pbpar |=  0x06;
466         cp->cp_pbdir &= ~0x06;
467         cp->cp_pbodr &= ~0x06;
468
469 #elif (SCC_INDEX < 2) || !defined(CONFIG_IP860)
470         /*
471          * Standard configuration for SCC's is on Part A
472          */
473         ip->iop_papar |=  ((3 << (2 * SCC_INDEX)));
474         ip->iop_padir &= ~((3 << (2 * SCC_INDEX)));
475         ip->iop_paodr &= ~((3 << (2 * SCC_INDEX)));
476 #else
477         /*
478          * The IP860 has SCC3 and SCC4 on Port D
479          */
480         ip->iop_pdpar |=  ((3 << (2 * SCC_INDEX)));
481 #endif
482
483         /* Allocate space for two buffer descriptors in the DP ram. */
484
485 #ifdef CONFIG_SYS_ALLOC_DPRAM
486         dpaddr = dpram_alloc_align (sizeof(cbd_t)*2 + 2, 8) ;
487 #else
488         dpaddr = CPM_SERIAL2_BASE ;
489 #endif
490
491         /* Enable SDMA. */
492         im->im_siu_conf.sc_sdcr = 0x0001;
493
494         /* Set the physical address of the host memory buffers in
495          * the buffer descriptors.
496          */
497
498         rbdf = (cbd_t *)&cp->cp_dpmem[dpaddr];
499         rbdf->cbd_bufaddr = (uint) (rbdf+2);
500         rbdf->cbd_sc = 0;
501         tbdf = rbdf + 1;
502         tbdf->cbd_bufaddr = ((uint) (rbdf+2)) + 1;
503         tbdf->cbd_sc = 0;
504
505         /* Set up the baud rate generator. */
506         scc_setbrg ();
507
508         /* Set up the uart parameters in the parameter ram. */
509         up->scc_genscc.scc_rbase = dpaddr;
510         up->scc_genscc.scc_tbase = dpaddr+sizeof(cbd_t);
511
512         /* Initialize Tx/Rx parameters. */
513         while (cp->cp_cpcr & CPM_CR_FLG)  /* wait if cp is busy */
514                 ;
515         cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SCC, CPM_CR_INIT_TRX) | CPM_CR_FLG;
516
517         while (cp->cp_cpcr & CPM_CR_FLG)  /* wait if cp is busy */
518                 ;
519
520         up->scc_genscc.scc_rfcr  = SCC_EB | 0x05;
521         up->scc_genscc.scc_tfcr  = SCC_EB | 0x05;
522
523         up->scc_genscc.scc_mrblr = 1;   /* Single character receive */
524         up->scc_maxidl = 0;             /* disable max idle */
525         up->scc_brkcr  = 1;             /* send one break character on stop TX */
526         up->scc_parec  = 0;
527         up->scc_frmec  = 0;
528         up->scc_nosec  = 0;
529         up->scc_brkec  = 0;
530         up->scc_uaddr1 = 0;
531         up->scc_uaddr2 = 0;
532         up->scc_toseq  = 0;
533         up->scc_char1  = 0x8000;
534         up->scc_char2  = 0x8000;
535         up->scc_char3  = 0x8000;
536         up->scc_char4  = 0x8000;
537         up->scc_char5  = 0x8000;
538         up->scc_char6  = 0x8000;
539         up->scc_char7  = 0x8000;
540         up->scc_char8  = 0x8000;
541         up->scc_rccm   = 0xc0ff;
542
543         /* Set low latency / small fifo. */
544         sp->scc_gsmrh = SCC_GSMRH_RFW;
545
546         /* Set SCC(x) clock mode to 16x
547          * See 8xx_io/commproc.c for details.
548          *
549          * Wire BRG1 to SCCn
550          */
551
552         /* Set UART mode, clock divider 16 on Tx and Rx */
553         sp->scc_gsmrl &= ~0xF;
554         sp->scc_gsmrl |=
555                 (SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16);
556
557         sp->scc_psmr  = 0;
558         sp->scc_psmr  |= SCU_PSMR_CL;
559
560         /* Mask all interrupts and remove anything pending. */
561         sp->scc_sccm = 0;
562         sp->scc_scce = 0xffff;
563         sp->scc_dsr  = 0x7e7e;
564         sp->scc_psmr = 0x3000;
565
566         /* Make the first buffer the only buffer. */
567         tbdf->cbd_sc |= BD_SC_WRAP;
568         rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP;
569
570         /* Enable transmitter/receiver. */
571         sp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
572
573         return (0);
574 }
575
576 static void
577 scc_putc(const char c)
578 {
579         volatile cbd_t          *tbdf;
580         volatile char           *buf;
581         volatile scc_uart_t     *up;
582         volatile immap_t        *im = (immap_t *)CONFIG_SYS_IMMR;
583         volatile cpm8xx_t       *cpmp = &(im->im_cpm);
584
585 #ifdef CONFIG_MODEM_SUPPORT
586         if (gd->be_quiet)
587                 return;
588 #endif
589
590         if (c == '\n')
591                 scc_putc ('\r');
592
593         up = (scc_uart_t *)&cpmp->cp_dparam[PROFF_SCC];
594
595         tbdf = (cbd_t *)&cpmp->cp_dpmem[up->scc_genscc.scc_tbase];
596
597         /* Wait for last character to go. */
598
599         buf = (char *)tbdf->cbd_bufaddr;
600
601         *buf = c;
602         tbdf->cbd_datlen = 1;
603         tbdf->cbd_sc |= BD_SC_READY;
604         __asm__("eieio");
605
606         while (tbdf->cbd_sc & BD_SC_READY) {
607                 __asm__("eieio");
608                 WATCHDOG_RESET ();
609         }
610 }
611
612 static void
613 scc_puts (const char *s)
614 {
615         while (*s) {
616                 scc_putc (*s++);
617         }
618 }
619
620 static int
621 scc_getc(void)
622 {
623         volatile cbd_t          *rbdf;
624         volatile unsigned char  *buf;
625         volatile scc_uart_t     *up;
626         volatile immap_t        *im = (immap_t *)CONFIG_SYS_IMMR;
627         volatile cpm8xx_t       *cpmp = &(im->im_cpm);
628         unsigned char           c;
629
630         up = (scc_uart_t *)&cpmp->cp_dparam[PROFF_SCC];
631
632         rbdf = (cbd_t *)&cpmp->cp_dpmem[up->scc_genscc.scc_rbase];
633
634         /* Wait for character to show up. */
635         buf = (unsigned char *)rbdf->cbd_bufaddr;
636
637         while (rbdf->cbd_sc & BD_SC_EMPTY)
638                 WATCHDOG_RESET ();
639
640         c = *buf;
641         rbdf->cbd_sc |= BD_SC_EMPTY;
642
643         return(c);
644 }
645
646 static int
647 scc_tstc(void)
648 {
649         volatile cbd_t          *rbdf;
650         volatile scc_uart_t     *up;
651         volatile immap_t        *im = (immap_t *)CONFIG_SYS_IMMR;
652         volatile cpm8xx_t       *cpmp = &(im->im_cpm);
653
654         up = (scc_uart_t *)&cpmp->cp_dparam[PROFF_SCC];
655
656         rbdf = (cbd_t *)&cpmp->cp_dpmem[up->scc_genscc.scc_rbase];
657
658         return(!(rbdf->cbd_sc & BD_SC_EMPTY));
659 }
660
661 struct serial_device serial_scc_device =
662 {
663         "serial_scc",
664         "SCC",
665         scc_init,
666         NULL,
667         scc_setbrg,
668         scc_getc,
669         scc_tstc,
670         scc_putc,
671         scc_puts,
672 };
673
674 #endif  /* CONFIG_8xx_CONS_SCCx */
675
676 #ifdef CONFIG_MODEM_SUPPORT
677 void disable_putc(void)
678 {
679         gd->be_quiet = 1;
680 }
681
682 void enable_putc(void)
683 {
684         gd->be_quiet = 0;
685 }
686 #endif
687
688 #if defined(CONFIG_CMD_KGDB)
689
690 void
691 kgdb_serial_init(void)
692 {
693         int i = -1;
694
695         if (strcmp(default_serial_console()->ctlr, "SMC") == 0)
696         {
697 #if defined(CONFIG_8xx_CONS_SMC1)
698                 i = 1;
699 #elif defined(CONFIG_8xx_CONS_SMC2)
700                 i = 2;
701 #endif
702         }
703         else if (strcmp(default_serial_console()->ctlr, "SMC") == 0)
704         {
705 #if defined(CONFIG_8xx_CONS_SCC1)
706                 i = 1;
707 #elif defined(CONFIG_8xx_CONS_SCC2)
708                 i = 2;
709 #elif defined(CONFIG_8xx_CONS_SCC3)
710                 i = 3;
711 #elif defined(CONFIG_8xx_CONS_SCC4)
712                 i = 4;
713 #endif
714         }
715
716         if (i >= 0)
717         {
718                 serial_printf("[on %s%d] ", default_serial_console()->ctlr, i);
719         }
720 }
721
722 void
723 putDebugChar (int c)
724 {
725         serial_putc (c);
726 }
727
728 void
729 putDebugStr (const char *str)
730 {
731         serial_puts (str);
732 }
733
734 int
735 getDebugChar (void)
736 {
737         return serial_getc();
738 }
739
740 void
741 kgdb_interruptible (int yes)
742 {
743         return;
744 }
745 #endif
746
747 #endif  /* CONFIG_8xx_CONS_NONE */