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