|  | /* | 
|  | * AU1X00 UART support | 
|  | * | 
|  | * Hardcoded to UART 0 for now | 
|  | * Speed and options also hardcoded to 115200 8N1 | 
|  | * | 
|  | *  Copyright (c) 2003	Thomas.Lange@corelatus.se | 
|  | * | 
|  | * See file CREDITS for list of people who contributed to this | 
|  | * project. | 
|  | * | 
|  | * This program is free software; you can redistribute it and/or | 
|  | * modify it under the terms of the GNU General Public License as | 
|  | * published by the Free Software Foundation; either version 2 of | 
|  | * the License, or (at your option) any later version. | 
|  | * | 
|  | * This program is distributed in the hope that it will be useful, | 
|  | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|  | * GNU General Public License for more details. | 
|  | * | 
|  | * You should have received a copy of the GNU General Public License | 
|  | * along with this program; if not, write to the Free Software | 
|  | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | 
|  | * MA 02111-1307 USA | 
|  | */ | 
|  |  | 
|  | #include <config.h> | 
|  | #include <common.h> | 
|  | #include <asm/au1x00.h> | 
|  |  | 
|  | /****************************************************************************** | 
|  | * | 
|  | * serial_init - initialize a channel | 
|  | * | 
|  | * This routine initializes the number of data bits, parity | 
|  | * and set the selected baud rate. Interrupts are disabled. | 
|  | * Set the modem control signals if the option is selected. | 
|  | * | 
|  | * RETURNS: N/A | 
|  | */ | 
|  |  | 
|  | int serial_init (void) | 
|  | { | 
|  | volatile u32 *uart_fifoctl = (volatile u32*)(UART0_ADDR+UART_FCR); | 
|  | volatile u32 *uart_enable = (volatile u32*)(UART0_ADDR+UART_ENABLE); | 
|  |  | 
|  | /* Enable clocks first */ | 
|  | *uart_enable = UART_EN_CE; | 
|  |  | 
|  | /* Then release reset */ | 
|  | /* Must release reset before setting other regs */ | 
|  | *uart_enable = UART_EN_CE|UART_EN_E; | 
|  |  | 
|  | /* Activate fifos, reset tx and rx */ | 
|  | /* Set tx trigger level to 12 */ | 
|  | *uart_fifoctl = UART_FCR_ENABLE_FIFO|UART_FCR_CLEAR_RCVR| | 
|  | UART_FCR_CLEAR_XMIT|UART_FCR_T_TRIGGER_12; | 
|  |  | 
|  | serial_setbrg(); | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  |  | 
|  | void serial_setbrg (void) | 
|  | { | 
|  | volatile u32 *uart_clk = (volatile u32*)(UART0_ADDR+UART_CLK); | 
|  | volatile u32 *uart_lcr = (volatile u32*)(UART0_ADDR+UART_LCR); | 
|  | volatile u32 *sys_powerctrl = (u32 *)SYS_POWERCTRL; | 
|  | int sd; | 
|  | int divisorx2; | 
|  |  | 
|  | /* sd is system clock divisor			*/ | 
|  | /* see section 10.4.5 in au1550 datasheet	*/ | 
|  | sd = (*sys_powerctrl & 0x03) + 2; | 
|  |  | 
|  | /* calulate 2x baudrate and round */ | 
|  | divisorx2 = ((CONFIG_SYS_MIPS_TIMER_FREQ/(sd * 16 * CONFIG_BAUDRATE))); | 
|  |  | 
|  | if (divisorx2 & 0x01) | 
|  | divisorx2 = divisorx2 + 1; | 
|  |  | 
|  | *uart_clk = divisorx2 / 2; | 
|  |  | 
|  | /* Set parity, stop bits and word length to 8N1 */ | 
|  | *uart_lcr = UART_LCR_WLEN8; | 
|  | } | 
|  |  | 
|  | void serial_putc (const char c) | 
|  | { | 
|  | volatile u32 *uart_lsr = (volatile u32*)(UART0_ADDR+UART_LSR); | 
|  | volatile u32 *uart_tx = (volatile u32*)(UART0_ADDR+UART_TX); | 
|  |  | 
|  | if (c == '\n') serial_putc ('\r'); | 
|  |  | 
|  | /* Wait for fifo to shift out some bytes */ | 
|  | while((*uart_lsr&UART_LSR_THRE)==0); | 
|  |  | 
|  | *uart_tx = (u32)c; | 
|  | } | 
|  |  | 
|  | void serial_puts (const char *s) | 
|  | { | 
|  | while (*s) | 
|  | { | 
|  | serial_putc (*s++); | 
|  | } | 
|  | } | 
|  |  | 
|  | int serial_getc (void) | 
|  | { | 
|  | volatile u32 *uart_rx = (volatile u32*)(UART0_ADDR+UART_RX); | 
|  | char c; | 
|  |  | 
|  | while (!serial_tstc()); | 
|  |  | 
|  | c = (*uart_rx&0xFF); | 
|  | return c; | 
|  | } | 
|  |  | 
|  | int serial_tstc (void) | 
|  | { | 
|  | volatile u32 *uart_lsr = (volatile u32*)(UART0_ADDR+UART_LSR); | 
|  |  | 
|  | if(*uart_lsr&UART_LSR_DR){ | 
|  | /* Data in rfifo */ | 
|  | return(1); | 
|  | } | 
|  | return 0; | 
|  | } |