/* * Jz47xx UART support * * Hardcoded to UART 0 for now * Options also hardcoded to 8N1 * * Copyright (c) 2005 * Ingenic Semiconductor, * * 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 #if defined(CONFIG_JZ4740) #include #include #undef UART_BASE #ifndef CONFIG_SYS_UART_BASE #define UART_BASE UART0_BASE #else #define UART_BASE CONFIG_SYS_UART_BASE #endif /****************************************************************************** * * 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) { #if !defined(CONFIG_NAND_U_BOOT) || defined(CONFIG_NAND_SPL) volatile u8 *uart_fcr = (volatile u8 *)(UART_BASE + OFF_FCR); volatile u8 *uart_lcr = (volatile u8 *)(UART_BASE + OFF_LCR); volatile u8 *uart_ier = (volatile u8 *)(UART_BASE + OFF_IER); volatile u8 *uart_sircr = (volatile u8 *)(UART_BASE + OFF_SIRCR); /* Disable port interrupts while changing hardware */ *uart_ier = 0; /* Disable UART unit function */ *uart_fcr = ~UART_FCR_UUE; /* Set both receiver and transmitter in UART mode (not SIR) */ *uart_sircr = ~(SIRCR_RSIRE | SIRCR_TSIRE); /* Set databits, stopbits and parity. (8-bit data, 1 stopbit, no parity) */ *uart_lcr = UART_LCR_WLEN_8 | UART_LCR_STOP_1; /* Set baud rate */ serial_setbrg(); /* Enable UART unit, enable and clear FIFO */ *uart_fcr = UART_FCR_UUE | UART_FCR_FE | UART_FCR_TFLS | UART_FCR_RFLS; #endif return 0; } void serial_setbrg (void) { volatile u8 *uart_lcr = (volatile u8 *)(UART_BASE + OFF_LCR); volatile u8 *uart_dlhr = (volatile u8 *)(UART_BASE + OFF_DLHR); volatile u8 *uart_dllr = (volatile u8 *)(UART_BASE + OFF_DLLR); u32 baud_div, tmp; baud_div = CONFIG_SYS_EXTAL / 16 / CONFIG_BAUDRATE; tmp = *uart_lcr; tmp |= UART_LCR_DLAB; *uart_lcr = tmp; *uart_dlhr = (baud_div >> 8) & 0xff; *uart_dllr = baud_div & 0xff; tmp &= ~UART_LCR_DLAB; *uart_lcr = tmp; } void serial_putc (const char c) { volatile u8 *uart_lsr = (volatile u8 *)(UART_BASE + OFF_LSR); volatile u8 *uart_tdr = (volatile u8 *)(UART_BASE + OFF_TDR); if (c == '\n') serial_putc ('\r'); /* Wait for fifo to shift out some bytes */ while ( !((*uart_lsr & (UART_LSR_TDRQ | UART_LSR_TEMT)) == 0x60) ); *uart_tdr = (u8)c; } void serial_puts (const char *s) { while (*s) { serial_putc (*s++); } } int serial_getc (void) { volatile u8 *uart_rdr = (volatile u8 *)(UART_BASE + OFF_RDR); while (!serial_tstc()); return *uart_rdr; } int serial_tstc (void) { volatile u8 *uart_lsr = (volatile u8 *)(UART_BASE + OFF_LSR); if (*uart_lsr & UART_LSR_DR) { /* Data in rfifo */ return (1); } return 0; } #endif