uboot/arch/powerpc/cpu/ppc4xx/iop480_uart.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2000-2006
   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 <asm/processor.h>
  27#include <asm/io.h>
  28#include <watchdog.h>
  29
  30#ifdef CONFIG_SERIAL_MULTI
  31#include <serial.h>
  32#endif
  33
  34DECLARE_GLOBAL_DATA_PTR;
  35
  36#ifdef CONFIG_IOP480
  37
  38#define SPU_BASE         0x40000000
  39
  40#define spu_LineStat_rc  0x00   /* Line Status Register (Read/Clear) */
  41#define spu_LineStat_w   0x04   /* Line Status Register (Set) */
  42#define spu_Handshk_rc   0x08   /* Handshake Status Register (Read/Clear) */
  43#define spu_Handshk_w    0x0c   /* Handshake Status Register (Set) */
  44#define spu_BRateDivh    0x10   /* Baud rate divisor high */
  45#define spu_BRateDivl    0x14   /* Baud rate divisor low */
  46#define spu_CtlReg       0x18   /* Control Register */
  47#define spu_RxCmd        0x1c   /* Rx Command Register */
  48#define spu_TxCmd        0x20   /* Tx Command Register */
  49#define spu_RxBuff       0x24   /* Rx data buffer */
  50#define spu_TxBuff       0x24   /* Tx data buffer */
  51
  52/*-----------------------------------------------------------------------------+
  53  | Line Status Register.
  54  +-----------------------------------------------------------------------------*/
  55#define asyncLSRport1           0x40000000
  56#define asyncLSRport1set        0x40000004
  57#define asyncLSRDataReady             0x80
  58#define asyncLSRFramingError          0x40
  59#define asyncLSROverrunError          0x20
  60#define asyncLSRParityError           0x10
  61#define asyncLSRBreakInterrupt        0x08
  62#define asyncLSRTxHoldEmpty           0x04
  63#define asyncLSRTxShiftEmpty          0x02
  64
  65/*-----------------------------------------------------------------------------+
  66  | Handshake Status Register.
  67  +-----------------------------------------------------------------------------*/
  68#define asyncHSRport1           0x40000008
  69#define asyncHSRport1set        0x4000000c
  70#define asyncHSRDsr                   0x80
  71#define asyncLSRCts                   0x40
  72
  73/*-----------------------------------------------------------------------------+
  74  | Control Register.
  75  +-----------------------------------------------------------------------------*/
  76#define asyncCRport1            0x40000018
  77#define asyncCRNormal                 0x00
  78#define asyncCRLoopback               0x40
  79#define asyncCRAutoEcho               0x80
  80#define asyncCRDtr                    0x20
  81#define asyncCRRts                    0x10
  82#define asyncCRWordLength7            0x00
  83#define asyncCRWordLength8            0x08
  84#define asyncCRParityDisable          0x00
  85#define asyncCRParityEnable           0x04
  86#define asyncCREvenParity             0x00
  87#define asyncCROddParity              0x02
  88#define asyncCRStopBitsOne            0x00
  89#define asyncCRStopBitsTwo            0x01
  90#define asyncCRDisableDtrRts          0x00
  91
  92/*-----------------------------------------------------------------------------+
  93  | Receiver Command Register.
  94  +-----------------------------------------------------------------------------*/
  95#define asyncRCRport1           0x4000001c
  96#define asyncRCRDisable               0x00
  97#define asyncRCREnable                0x80
  98#define asyncRCRIntDisable            0x00
  99#define asyncRCRIntEnabled            0x20
 100#define asyncRCRDMACh2                0x40
 101#define asyncRCRDMACh3                0x60
 102#define asyncRCRErrorInt              0x10
 103#define asyncRCRPauseEnable           0x08
 104
 105/*-----------------------------------------------------------------------------+
 106  | Transmitter Command Register.
 107  +-----------------------------------------------------------------------------*/
 108#define asyncTCRport1           0x40000020
 109#define asyncTCRDisable               0x00
 110#define asyncTCREnable                0x80
 111#define asyncTCRIntDisable            0x00
 112#define asyncTCRIntEnabled            0x20
 113#define asyncTCRDMACh2                0x40
 114#define asyncTCRDMACh3                0x60
 115#define asyncTCRTxEmpty               0x10
 116#define asyncTCRErrorInt              0x08
 117#define asyncTCRStopPause             0x04
 118#define asyncTCRBreakGen              0x02
 119
 120/*-----------------------------------------------------------------------------+
 121  | Miscellanies defines.
 122  +-----------------------------------------------------------------------------*/
 123#define asyncTxBufferport1      0x40000024
 124#define asyncRxBufferport1      0x40000024
 125#define asyncDLABLsbport1       0x40000014
 126#define asyncDLABMsbport1       0x40000010
 127#define asyncXOFFchar                 0x13
 128#define asyncXONchar                  0x11
 129
 130/*
 131 * Minimal serial functions needed to use one of the SMC ports
 132 * as serial console interface.
 133 */
 134
 135int serial_init (void)
 136{
 137        volatile char val;
 138        unsigned short br_reg;
 139
 140        br_reg = ((((CONFIG_CPUCLOCK * 1000000) / 16) / gd->baudrate) - 1);
 141
 142        /*
 143         * Init onboard UART
 144         */
 145        out_8((u8 *)SPU_BASE + spu_LineStat_rc, 0x78); /* Clear all bits in Line Status Reg */
 146        out_8((u8 *)SPU_BASE + spu_BRateDivl, (br_reg & 0x00ff)); /* Set baud rate divisor... */
 147        out_8((u8 *)SPU_BASE + spu_BRateDivh, ((br_reg & 0xff00) >> 8)); /* ... */
 148        out_8((u8 *)SPU_BASE + spu_CtlReg, 0x08);       /* Set 8 bits, no parity and 1 stop bit */
 149        out_8((u8 *)SPU_BASE + spu_RxCmd, 0xb0);        /* Enable Rx */
 150        out_8((u8 *)SPU_BASE + spu_TxCmd, 0x9c);        /* Enable Tx */
 151        out_8((u8 *)SPU_BASE + spu_Handshk_rc, 0xff);   /* Clear Handshake */
 152        val = in_8((u8 *)SPU_BASE + spu_RxBuff);        /* Dummy read, to clear receiver */
 153
 154        return (0);
 155}
 156
 157void serial_setbrg (void)
 158{
 159        unsigned short br_reg;
 160
 161        br_reg = ((((CONFIG_CPUCLOCK * 1000000) / 16) / gd->baudrate) - 1);
 162
 163        out_8((u8 *)SPU_BASE + spu_BRateDivl,
 164              (br_reg & 0x00ff)); /* Set baud rate divisor... */
 165        out_8((u8 *)SPU_BASE + spu_BRateDivh,
 166              ((br_reg & 0xff00) >> 8)); /* ... */
 167}
 168
 169void serial_putc (const char c)
 170{
 171        if (c == '\n')
 172                serial_putc ('\r');
 173
 174        /* load status from handshake register */
 175        if (in_8((u8 *)SPU_BASE + spu_Handshk_rc) != 00)
 176                out_8((u8 *)SPU_BASE + spu_Handshk_rc, 0xff);   /* Clear Handshake */
 177
 178        out_8((u8 *)SPU_BASE + spu_TxBuff, c);  /* Put char */
 179
 180        while ((in_8((u8 *)SPU_BASE + spu_LineStat_rc) & 04) != 04) {
 181                if (in_8((u8 *)SPU_BASE + spu_Handshk_rc) != 00)
 182                        out_8((u8 *)SPU_BASE + spu_Handshk_rc, 0xff);   /* Clear Handshake */
 183        }
 184}
 185
 186void serial_puts (const char *s)
 187{
 188        while (*s) {
 189                serial_putc (*s++);
 190        }
 191}
 192
 193int serial_getc ()
 194{
 195        unsigned char status = 0;
 196
 197        while (1) {
 198                status = in_8((u8 *)asyncLSRport1);
 199                if ((status & asyncLSRDataReady) != 0x0) {
 200                        break;
 201                }
 202                if ((status & ( asyncLSRFramingError |
 203                                asyncLSROverrunError |
 204                                asyncLSRParityError  |
 205                                asyncLSRBreakInterrupt )) != 0) {
 206                        (void) out_8((u8 *)asyncLSRport1,
 207                                     asyncLSRFramingError |
 208                                     asyncLSROverrunError |
 209                                     asyncLSRParityError  |
 210                                     asyncLSRBreakInterrupt );
 211                }
 212        }
 213        return (0x000000ff & (int) in_8((u8 *)asyncRxBufferport1));
 214}
 215
 216int serial_tstc ()
 217{
 218        unsigned char status;
 219
 220        status = in_8((u8 *)asyncLSRport1);
 221        if ((status & asyncLSRDataReady) != 0x0) {
 222                return (1);
 223        }
 224        if ((status & ( asyncLSRFramingError |
 225                        asyncLSROverrunError |
 226                        asyncLSRParityError  |
 227                        asyncLSRBreakInterrupt )) != 0) {
 228                (void) out_8((u8 *)asyncLSRport1,
 229                             asyncLSRFramingError |
 230                             asyncLSROverrunError |
 231                             asyncLSRParityError  |
 232                             asyncLSRBreakInterrupt);
 233        }
 234        return 0;
 235}
 236
 237#endif  /* CONFIG_IOP480 */
 238