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