uboot/drivers/serial/serial_imx.c
<<
>>
Prefs
   1/*
   2 * (c) 2004 Sascha Hauer <sascha@saschahauer.de>
   3 *
   4 * This program is free software; you can redistribute it and/or modify
   5 * it under the terms of the GNU General Public License as published by
   6 * the Free Software Foundation; either version 2 of the License, or
   7 * (at your option) any later version.
   8 *
   9 * This program is distributed in the hope that it will be useful,
  10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12 * GNU General Public License for more details.
  13 *
  14 * You should have received a copy of the GNU General Public License
  15 * along with this program; if not, write to the Free Software
  16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  17 *
  18 */
  19
  20#include <common.h>
  21#include <asm/arch/imx-regs.h>
  22
  23#if defined CONFIG_IMX_SERIAL1
  24#define UART_BASE IMX_UART1_BASE
  25#elif defined CONFIG_IMX_SERIAL2
  26#define UART_BASE IMX_UART2_BASE
  27#else
  28#error "define CONFIG_IMX_SERIAL1, CONFIG_IMX_SERIAL2 or CONFIG_IMX_SERIAL_NONE"
  29#endif
  30
  31struct imx_serial {
  32        volatile uint32_t urxd[16];
  33        volatile uint32_t utxd[16];
  34        volatile uint32_t ucr1;
  35        volatile uint32_t ucr2;
  36        volatile uint32_t ucr3;
  37        volatile uint32_t ucr4;
  38        volatile uint32_t ufcr;
  39        volatile uint32_t usr1;
  40        volatile uint32_t usr2;
  41        volatile uint32_t uesc;
  42        volatile uint32_t utim;
  43        volatile uint32_t ubir;
  44        volatile uint32_t ubmr;
  45        volatile uint32_t ubrc;
  46        volatile uint32_t bipr[4];
  47        volatile uint32_t bmpr[4];
  48        volatile uint32_t uts;
  49};
  50
  51DECLARE_GLOBAL_DATA_PTR;
  52
  53void serial_setbrg (void)
  54{
  55        serial_init();
  56}
  57
  58extern void imx_gpio_mode(int gpio_mode);
  59
  60/*
  61 * Initialise the serial port with the given baudrate. The settings
  62 * are always 8 data bits, no parity, 1 stop bit, no start bits.
  63 *
  64 */
  65int serial_init (void)
  66{
  67        volatile struct imx_serial* base = (struct imx_serial *)UART_BASE;
  68        unsigned int ufcr_rfdiv;
  69        unsigned int refclk;
  70
  71#ifdef CONFIG_IMX_SERIAL1
  72        imx_gpio_mode(PC11_PF_UART1_TXD);
  73        imx_gpio_mode(PC12_PF_UART1_RXD);
  74#else
  75        imx_gpio_mode(PB30_PF_UART2_TXD);
  76        imx_gpio_mode(PB31_PF_UART2_RXD);
  77#endif
  78
  79        /* Disable UART */
  80        base->ucr1 &= ~UCR1_UARTEN;
  81
  82        /* Set to default POR state */
  83
  84        base->ucr1 = 0x00000004;
  85        base->ucr2 = 0x00000000;
  86        base->ucr3 = 0x00000000;
  87        base->ucr4 = 0x00008040;
  88        base->uesc = 0x0000002B;
  89        base->utim = 0x00000000;
  90        base->ubir = 0x00000000;
  91        base->ubmr = 0x00000000;
  92        base->uts  = 0x00000000;
  93        /* Set clocks */
  94        base->ucr4 |= UCR4_REF16;
  95
  96        /* Configure FIFOs */
  97        base->ufcr = 0xa81;
  98
  99        /* set the baud rate.
 100         *
 101         * baud * 16   x
 102         * --------- = -
 103         *  refclk     y
 104         *
 105         * x - 1 = UBIR
 106         * y - 1 = UBMR
 107         *
 108         * each register is 16 bits wide. refclk max is 96 MHz
 109         *
 110         */
 111
 112        ufcr_rfdiv = ((base->ufcr) & UFCR_RFDIV) >> 7;
 113        if (ufcr_rfdiv == 6)
 114                ufcr_rfdiv = 7;
 115        else
 116                ufcr_rfdiv = 6 - ufcr_rfdiv;
 117
 118        refclk = get_PERCLK1();
 119        refclk /= ufcr_rfdiv;
 120
 121        /* Set the numerator value minus one of the BRM ratio */
 122        base->ubir = (gd->baudrate / 100) - 1;
 123
 124        /* Set the denominator value minus one of the BRM ratio */
 125        base->ubmr = (refclk/(16 * 100)) - 1;
 126
 127        /* Set to 8N1 */
 128        base->ucr2 &= ~UCR2_PREN;
 129        base->ucr2 |= UCR2_WS;
 130        base->ucr2 &= ~UCR2_STPB;
 131
 132        /* Ignore RTS */
 133        base->ucr2 |= UCR2_IRTS;
 134
 135        /* Enable UART */
 136        base->ucr1 |= UCR1_UARTEN | UCR1_UARTCLKEN;
 137
 138        /* Enable FIFOs */
 139        base->ucr2 |= UCR2_SRST | UCR2_RXEN | UCR2_TXEN;
 140
 141        /* Clear status flags */
 142        base->usr2 |= USR2_ADET  |
 143                      USR2_DTRF  |
 144                      USR2_IDLE  |
 145                      USR2_IRINT |
 146                      USR2_WAKE  |
 147                      USR2_RTSF  |
 148                      USR2_BRCD  |
 149                      USR2_ORE;
 150
 151        /* Clear status flags */
 152        base->usr1 |= USR1_PARITYERR |
 153                      USR1_RTSD      |
 154                      USR1_ESCF      |
 155                      USR1_FRAMERR   |
 156                      USR1_AIRINT    |
 157                      USR1_AWAKE;
 158        return (0);
 159}
 160
 161/*
 162 * Read a single byte from the serial port. Returns 1 on success, 0
 163 * otherwise. When the function is successful, the character read is
 164 * written into its argument c.
 165 */
 166int serial_getc (void)
 167{
 168        volatile struct imx_serial* base = (struct imx_serial *)UART_BASE;
 169        unsigned char ch;
 170
 171        while(base->uts & UTS_RXEMPTY);
 172
 173        ch = (char)base->urxd[0];
 174
 175        return ch;
 176}
 177
 178#ifdef CONFIG_HWFLOW
 179static int hwflow = 0; /* turned off by default */
 180int hwflow_onoff(int on)
 181{
 182}
 183#endif
 184
 185/*
 186 * Output a single byte to the serial port.
 187 */
 188void serial_putc (const char c)
 189{
 190        volatile struct imx_serial* base = (struct imx_serial *)UART_BASE;
 191
 192        /* Wait for Tx FIFO not full */
 193        while (base->uts & UTS_TXFULL);
 194
 195        base->utxd[0] = c;
 196
 197        /* If \n, also do \r */
 198        if (c == '\n')
 199                serial_putc ('\r');
 200}
 201
 202/*
 203 * Test whether a character is in the RX buffer
 204 */
 205int serial_tstc (void)
 206{
 207        volatile struct imx_serial* base = (struct imx_serial *)UART_BASE;
 208
 209        /* If receive fifo is empty, return false */
 210        if (base->uts & UTS_RXEMPTY)
 211                return 0;
 212        return 1;
 213}
 214
 215void
 216serial_puts (const char *s)
 217{
 218        while (*s) {
 219                serial_putc (*s++);
 220        }
 221}
 222