From 20c9226cb8cab08a111ee73db04e62d943ee0c97 Mon Sep 17 00:00:00 2001 From: Andreas Engel Date: Mon, 8 Sep 2008 10:17:31 +0200 Subject: Merged serial_pl010.c and serial_pl011.c. They only differ in the init function. This also adds the missing watchdog support for the PL011. Signed-off-by: Andreas Engel --- drivers/serial/Makefile | 3 +- drivers/serial/serial_pl010.c | 175 -------------------------------- drivers/serial/serial_pl011.c | 161 ----------------------------- drivers/serial/serial_pl011.h | 137 ------------------------- drivers/serial/serial_pl01x.c | 228 ++++++++++++++++++++++++++++++++++++++++++ drivers/serial/serial_pl01x.h | 137 +++++++++++++++++++++++++ 6 files changed, 366 insertions(+), 475 deletions(-) delete mode 100644 drivers/serial/serial_pl010.c delete mode 100644 drivers/serial/serial_pl011.c delete mode 100644 drivers/serial/serial_pl011.h create mode 100644 drivers/serial/serial_pl01x.c create mode 100644 drivers/serial/serial_pl01x.h (limited to 'drivers') diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index f30014d..3cc1999 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -33,8 +33,7 @@ COBJS-$(CONFIG_DRIVER_S3C4510_UART) += s3c4510b_uart.o COBJS-$(CONFIG_S3C64XX) += s3c64xx.o COBJS-y += serial.o COBJS-$(CONFIG_MAX3100_SERIAL) += serial_max3100.o -COBJS-y += serial_pl010.o -COBJS-y += serial_pl011.o +COBJS-y += serial_pl01x.o COBJS-$(CONFIG_XILINX_UARTLITE) += serial_xuartlite.o COBJS-$(CONFIG_SCIF_CONSOLE) += serial_sh.o COBJS-$(CONFIG_USB_TTY) += usbtty.o diff --git a/drivers/serial/serial_pl010.c b/drivers/serial/serial_pl010.c deleted file mode 100644 index 134ed09..0000000 --- a/drivers/serial/serial_pl010.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * (C) Copyright 2000 - * Rob Taylor, Flying Pig Systems. robt@flyingpig.com. - * - * (C) Copyright 2004 - * ARM Ltd. - * Philippe Robin, - * - * 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 - */ - -/* Simple U-Boot driver for the PrimeCell PL011 UARTs on the IntegratorCP */ -/* Should be fairly simple to make it work with the PL010 as well */ - -#include -#include - -#ifdef CFG_PL010_SERIAL - -#include "serial_pl011.h" - -#define IO_WRITE(addr, val) (*(volatile unsigned int *)(addr) = (val)) -#define IO_READ(addr) (*(volatile unsigned int *)(addr)) - -/* Integrator AP has two UARTs, we use the first one, at 38400-8-N-1 */ -#define CONSOLE_PORT CONFIG_CONS_INDEX -#define baudRate CONFIG_BAUDRATE -static volatile unsigned char *const port[] = CONFIG_PL01x_PORTS; -#define NUM_PORTS (sizeof(port)/sizeof(port[0])) - - -static void pl010_putc (int portnum, char c); -static int pl010_getc (int portnum); -static int pl010_tstc (int portnum); - - -int serial_init (void) -{ - unsigned int divisor; - - /* - ** First, disable everything. - */ - IO_WRITE (port[CONSOLE_PORT] + UART_PL010_CR, 0x0); - - /* - ** Set baud rate - ** - */ - switch (baudRate) { - case 9600: - divisor = UART_PL010_BAUD_9600; - break; - - case 19200: - divisor = UART_PL010_BAUD_9600; - break; - - case 38400: - divisor = UART_PL010_BAUD_38400; - break; - - case 57600: - divisor = UART_PL010_BAUD_57600; - break; - - case 115200: - divisor = UART_PL010_BAUD_115200; - break; - - default: - divisor = UART_PL010_BAUD_38400; - } - - IO_WRITE (port[CONSOLE_PORT] + UART_PL010_LCRM, - ((divisor & 0xf00) >> 8)); - IO_WRITE (port[CONSOLE_PORT] + UART_PL010_LCRL, (divisor & 0xff)); - - /* - ** Set the UART to be 8 bits, 1 stop bit, no parity, fifo enabled. - */ - IO_WRITE (port[CONSOLE_PORT] + UART_PL010_LCRH, - (UART_PL010_LCRH_WLEN_8 | UART_PL010_LCRH_FEN)); - - /* - ** Finally, enable the UART - */ - IO_WRITE (port[CONSOLE_PORT] + UART_PL010_CR, (UART_PL010_CR_UARTEN)); - - return (0); -} - -void serial_putc (const char c) -{ - if (c == '\n') - pl010_putc (CONSOLE_PORT, '\r'); - - pl010_putc (CONSOLE_PORT, c); -} - -void serial_puts (const char *s) -{ - while (*s) { - serial_putc (*s++); - } -} - -int serial_getc (void) -{ - return pl010_getc (CONSOLE_PORT); -} - -int serial_tstc (void) -{ - return pl010_tstc (CONSOLE_PORT); -} - -void serial_setbrg (void) -{ -} - -static void pl010_putc (int portnum, char c) -{ - /* Wait until there is space in the FIFO */ - while (IO_READ (port[portnum] + UART_PL01x_FR) & UART_PL01x_FR_TXFF) - WATCHDOG_RESET(); - - /* Send the character */ - IO_WRITE (port[portnum] + UART_PL01x_DR, c); -} - -static int pl010_getc (int portnum) -{ - unsigned int data; - - /* Wait until there is data in the FIFO */ - while (IO_READ (port[portnum] + UART_PL01x_FR) & UART_PL01x_FR_RXFE) - WATCHDOG_RESET(); - - data = IO_READ (port[portnum] + UART_PL01x_DR); - - /* Check for an error flag */ - if (data & 0xFFFFFF00) { - /* Clear the error */ - IO_WRITE (port[portnum] + UART_PL01x_ECR, 0xFFFFFFFF); - return -1; - } - - return (int) data; -} - -static int pl010_tstc (int portnum) -{ - WATCHDOG_RESET(); - return !(IO_READ (port[portnum] + UART_PL01x_FR) & - UART_PL01x_FR_RXFE); -} - -#endif diff --git a/drivers/serial/serial_pl011.c b/drivers/serial/serial_pl011.c deleted file mode 100644 index 4d35fe5..0000000 --- a/drivers/serial/serial_pl011.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * (C) Copyright 2000 - * Rob Taylor, Flying Pig Systems. robt@flyingpig.com. - * - * (C) Copyright 2004 - * ARM Ltd. - * Philippe Robin, - * - * 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 - */ - -/* Simple U-Boot driver for the PrimeCell PL011 UARTs on the IntegratorCP */ -/* Should be fairly simple to make it work with the PL010 as well */ - -#include - -#ifdef CFG_PL011_SERIAL - -#include "serial_pl011.h" - -#define IO_WRITE(addr, val) (*(volatile unsigned int *)(addr) = (val)) -#define IO_READ(addr) (*(volatile unsigned int *)(addr)) - -/* - * IntegratorCP has two UARTs, use the first one, at 38400-8-N-1 - * Versatile PB has four UARTs. - */ - -#define CONSOLE_PORT CONFIG_CONS_INDEX -#define baudRate CONFIG_BAUDRATE -static volatile unsigned char *const port[] = CONFIG_PL01x_PORTS; -#define NUM_PORTS (sizeof(port)/sizeof(port[0])) - -static void pl011_putc (int portnum, char c); -static int pl011_getc (int portnum); -static int pl011_tstc (int portnum); - - -int serial_init (void) -{ - unsigned int temp; - unsigned int divider; - unsigned int remainder; - unsigned int fraction; - - /* - ** First, disable everything. - */ - IO_WRITE (port[CONSOLE_PORT] + UART_PL011_CR, 0x0); - - /* - ** Set baud rate - ** - ** IBRD = UART_CLK / (16 * BAUD_RATE) - ** FBRD = ROUND((64 * MOD(UART_CLK,(16 * BAUD_RATE))) / (16 * BAUD_RATE)) - */ - temp = 16 * baudRate; - divider = CONFIG_PL011_CLOCK / temp; - remainder = CONFIG_PL011_CLOCK % temp; - temp = (8 * remainder) / baudRate; - fraction = (temp >> 1) + (temp & 1); - - IO_WRITE (port[CONSOLE_PORT] + UART_PL011_IBRD, divider); - IO_WRITE (port[CONSOLE_PORT] + UART_PL011_FBRD, fraction); - - /* - ** Set the UART to be 8 bits, 1 stop bit, no parity, fifo enabled. - */ - IO_WRITE (port[CONSOLE_PORT] + UART_PL011_LCRH, - (UART_PL011_LCRH_WLEN_8 | UART_PL011_LCRH_FEN)); - - /* - ** Finally, enable the UART - */ - IO_WRITE (port[CONSOLE_PORT] + UART_PL011_CR, - (UART_PL011_CR_UARTEN | UART_PL011_CR_TXE | - UART_PL011_CR_RXE)); - - return 0; -} - -void serial_putc (const char c) -{ - if (c == '\n') - pl011_putc (CONSOLE_PORT, '\r'); - - pl011_putc (CONSOLE_PORT, c); -} - -void serial_puts (const char *s) -{ - while (*s) { - serial_putc (*s++); - } -} - -int serial_getc (void) -{ - return pl011_getc (CONSOLE_PORT); -} - -int serial_tstc (void) -{ - return pl011_tstc (CONSOLE_PORT); -} - -void serial_setbrg (void) -{ -} - -static void pl011_putc (int portnum, char c) -{ - /* Wait until there is space in the FIFO */ - while (IO_READ (port[portnum] + UART_PL01x_FR) & UART_PL01x_FR_TXFF); - - /* Send the character */ - IO_WRITE (port[portnum] + UART_PL01x_DR, c); -} - -static int pl011_getc (int portnum) -{ - unsigned int data; - - /* Wait until there is data in the FIFO */ - while (IO_READ (port[portnum] + UART_PL01x_FR) & UART_PL01x_FR_RXFE); - - data = IO_READ (port[portnum] + UART_PL01x_DR); - - /* Check for an error flag */ - if (data & 0xFFFFFF00) { - /* Clear the error */ - IO_WRITE (port[portnum] + UART_PL01x_ECR, 0xFFFFFFFF); - return -1; - } - - return (int) data; -} - -static int pl011_tstc (int portnum) -{ - return !(IO_READ (port[portnum] + UART_PL01x_FR) & - UART_PL01x_FR_RXFE); -} - -#endif diff --git a/drivers/serial/serial_pl011.h b/drivers/serial/serial_pl011.h deleted file mode 100644 index 5f20fdd..0000000 --- a/drivers/serial/serial_pl011.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * (C) Copyright 2003, 2004 - * ARM Ltd. - * Philippe Robin, - * - * 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 - */ - -/* - * ARM PrimeCell UART's (PL010 & PL011) - * ------------------------------------ - * - * Definitions common to both PL010 & PL011 - * - */ -#define UART_PL01x_DR 0x00 /* Data read or written from the interface. */ -#define UART_PL01x_RSR 0x04 /* Receive status register (Read). */ -#define UART_PL01x_ECR 0x04 /* Error clear register (Write). */ -#define UART_PL01x_FR 0x18 /* Flag register (Read only). */ - -#define UART_PL01x_RSR_OE 0x08 -#define UART_PL01x_RSR_BE 0x04 -#define UART_PL01x_RSR_PE 0x02 -#define UART_PL01x_RSR_FE 0x01 - -#define UART_PL01x_FR_TXFE 0x80 -#define UART_PL01x_FR_RXFF 0x40 -#define UART_PL01x_FR_TXFF 0x20 -#define UART_PL01x_FR_RXFE 0x10 -#define UART_PL01x_FR_BUSY 0x08 -#define UART_PL01x_FR_TMSK (UART_PL01x_FR_TXFF + UART_PL01x_FR_BUSY) - -/* - * PL010 definitions - * - */ -#define UART_PL010_LCRH 0x08 /* Line control register, high byte. */ -#define UART_PL010_LCRM 0x0C /* Line control register, middle byte. */ -#define UART_PL010_LCRL 0x10 /* Line control register, low byte. */ -#define UART_PL010_CR 0x14 /* Control register. */ -#define UART_PL010_IIR 0x1C /* Interrupt indentification register (Read). */ -#define UART_PL010_ICR 0x1C /* Interrupt clear register (Write). */ -#define UART_PL010_ILPR 0x20 /* IrDA low power counter register. */ - -#define UART_PL010_CR_LPE (1 << 7) -#define UART_PL010_CR_RTIE (1 << 6) -#define UART_PL010_CR_TIE (1 << 5) -#define UART_PL010_CR_RIE (1 << 4) -#define UART_PL010_CR_MSIE (1 << 3) -#define UART_PL010_CR_IIRLP (1 << 2) -#define UART_PL010_CR_SIREN (1 << 1) -#define UART_PL010_CR_UARTEN (1 << 0) - -#define UART_PL010_LCRH_WLEN_8 (3 << 5) -#define UART_PL010_LCRH_WLEN_7 (2 << 5) -#define UART_PL010_LCRH_WLEN_6 (1 << 5) -#define UART_PL010_LCRH_WLEN_5 (0 << 5) -#define UART_PL010_LCRH_FEN (1 << 4) -#define UART_PL010_LCRH_STP2 (1 << 3) -#define UART_PL010_LCRH_EPS (1 << 2) -#define UART_PL010_LCRH_PEN (1 << 1) -#define UART_PL010_LCRH_BRK (1 << 0) - - -#define UART_PL010_BAUD_460800 1 -#define UART_PL010_BAUD_230400 3 -#define UART_PL010_BAUD_115200 7 -#define UART_PL010_BAUD_57600 15 -#define UART_PL010_BAUD_38400 23 -#define UART_PL010_BAUD_19200 47 -#define UART_PL010_BAUD_14400 63 -#define UART_PL010_BAUD_9600 95 -#define UART_PL010_BAUD_4800 191 -#define UART_PL010_BAUD_2400 383 -#define UART_PL010_BAUD_1200 767 -/* - * PL011 definitions - * - */ -#define UART_PL011_IBRD 0x24 -#define UART_PL011_FBRD 0x28 -#define UART_PL011_LCRH 0x2C -#define UART_PL011_CR 0x30 -#define UART_PL011_IMSC 0x38 -#define UART_PL011_PERIPH_ID0 0xFE0 - -#define UART_PL011_LCRH_SPS (1 << 7) -#define UART_PL011_LCRH_WLEN_8 (3 << 5) -#define UART_PL011_LCRH_WLEN_7 (2 << 5) -#define UART_PL011_LCRH_WLEN_6 (1 << 5) -#define UART_PL011_LCRH_WLEN_5 (0 << 5) -#define UART_PL011_LCRH_FEN (1 << 4) -#define UART_PL011_LCRH_STP2 (1 << 3) -#define UART_PL011_LCRH_EPS (1 << 2) -#define UART_PL011_LCRH_PEN (1 << 1) -#define UART_PL011_LCRH_BRK (1 << 0) - -#define UART_PL011_CR_CTSEN (1 << 15) -#define UART_PL011_CR_RTSEN (1 << 14) -#define UART_PL011_CR_OUT2 (1 << 13) -#define UART_PL011_CR_OUT1 (1 << 12) -#define UART_PL011_CR_RTS (1 << 11) -#define UART_PL011_CR_DTR (1 << 10) -#define UART_PL011_CR_RXE (1 << 9) -#define UART_PL011_CR_TXE (1 << 8) -#define UART_PL011_CR_LPE (1 << 7) -#define UART_PL011_CR_IIRLP (1 << 2) -#define UART_PL011_CR_SIREN (1 << 1) -#define UART_PL011_CR_UARTEN (1 << 0) - -#define UART_PL011_IMSC_OEIM (1 << 10) -#define UART_PL011_IMSC_BEIM (1 << 9) -#define UART_PL011_IMSC_PEIM (1 << 8) -#define UART_PL011_IMSC_FEIM (1 << 7) -#define UART_PL011_IMSC_RTIM (1 << 6) -#define UART_PL011_IMSC_TXIM (1 << 5) -#define UART_PL011_IMSC_RXIM (1 << 4) -#define UART_PL011_IMSC_DSRMIM (1 << 3) -#define UART_PL011_IMSC_DCDMIM (1 << 2) -#define UART_PL011_IMSC_CTSMIM (1 << 1) -#define UART_PL011_IMSC_RIMIM (1 << 0) diff --git a/drivers/serial/serial_pl01x.c b/drivers/serial/serial_pl01x.c new file mode 100644 index 0000000..d0497ec --- /dev/null +++ b/drivers/serial/serial_pl01x.c @@ -0,0 +1,228 @@ +/* + * (C) Copyright 2000 + * Rob Taylor, Flying Pig Systems. robt@flyingpig.com. + * + * (C) Copyright 2004 + * ARM Ltd. + * Philippe Robin, + * + * 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 + */ + +/* Simple U-Boot driver for the PrimeCell PL011 UARTs on the IntegratorCP */ +/* Should be fairly simple to make it work with the PL010 as well */ + +#include +#include + +#if defined(CFG_PL010_SERIAL) || defined(CFG_PL011_SERIAL) + +#include "serial_pl01x.h" + +#define IO_WRITE(addr, val) (*(volatile unsigned int *)(addr) = (val)) +#define IO_READ(addr) (*(volatile unsigned int *)(addr)) + +/* + * Integrator AP has two UARTs, we use the first one, at 38400-8-N-1 + * Integrator CP has two UARTs, use the first one, at 38400-8-N-1 + * Versatile PB has four UARTs. + */ +#define CONSOLE_PORT CONFIG_CONS_INDEX +#define baudRate CONFIG_BAUDRATE +static volatile unsigned char *const port[] = CONFIG_PL01x_PORTS; +#define NUM_PORTS (sizeof(port)/sizeof(port[0])) + +static void pl01x_putc (int portnum, char c); +static int pl01x_getc (int portnum); +static int pl01x_tstc (int portnum); + +#ifdef CFG_PL010_SERIAL + +int serial_init (void) +{ + unsigned int divisor; + + /* + ** First, disable everything. + */ + IO_WRITE (port[CONSOLE_PORT] + UART_PL010_CR, 0x0); + + /* + ** Set baud rate + ** + */ + switch (baudRate) { + case 9600: + divisor = UART_PL010_BAUD_9600; + break; + + case 19200: + divisor = UART_PL010_BAUD_9600; + break; + + case 38400: + divisor = UART_PL010_BAUD_38400; + break; + + case 57600: + divisor = UART_PL010_BAUD_57600; + break; + + case 115200: + divisor = UART_PL010_BAUD_115200; + break; + + default: + divisor = UART_PL010_BAUD_38400; + } + + IO_WRITE (port[CONSOLE_PORT] + UART_PL010_LCRM, + ((divisor & 0xf00) >> 8)); + IO_WRITE (port[CONSOLE_PORT] + UART_PL010_LCRL, (divisor & 0xff)); + + /* + ** Set the UART to be 8 bits, 1 stop bit, no parity, fifo enabled. + */ + IO_WRITE (port[CONSOLE_PORT] + UART_PL010_LCRH, + (UART_PL010_LCRH_WLEN_8 | UART_PL010_LCRH_FEN)); + + /* + ** Finally, enable the UART + */ + IO_WRITE (port[CONSOLE_PORT] + UART_PL010_CR, (UART_PL010_CR_UARTEN)); + + return 0; +} + +#endif /* CFG_PL010_SERIAL */ + +#ifdef CFG_PL011_SERIAL + +int serial_init (void) +{ + unsigned int temp; + unsigned int divider; + unsigned int remainder; + unsigned int fraction; + + /* + ** First, disable everything. + */ + IO_WRITE (port[CONSOLE_PORT] + UART_PL011_CR, 0x0); + + /* + ** Set baud rate + ** + ** IBRD = UART_CLK / (16 * BAUD_RATE) + ** FBRD = ROUND((64 * MOD(UART_CLK,(16 * BAUD_RATE))) / (16 * BAUD_RATE)) + */ + temp = 16 * baudRate; + divider = CONFIG_PL011_CLOCK / temp; + remainder = CONFIG_PL011_CLOCK % temp; + temp = (8 * remainder) / baudRate; + fraction = (temp >> 1) + (temp & 1); + + IO_WRITE (port[CONSOLE_PORT] + UART_PL011_IBRD, divider); + IO_WRITE (port[CONSOLE_PORT] + UART_PL011_FBRD, fraction); + + /* + ** Set the UART to be 8 bits, 1 stop bit, no parity, fifo enabled. + */ + IO_WRITE (port[CONSOLE_PORT] + UART_PL011_LCRH, + (UART_PL011_LCRH_WLEN_8 | UART_PL011_LCRH_FEN)); + + /* + ** Finally, enable the UART + */ + IO_WRITE (port[CONSOLE_PORT] + UART_PL011_CR, + (UART_PL011_CR_UARTEN | UART_PL011_CR_TXE | + UART_PL011_CR_RXE)); + + return 0; +} + +#endif /* CFG_PL011_SERIAL */ + +void serial_putc (const char c) +{ + if (c == '\n') + pl01x_putc (CONSOLE_PORT, '\r'); + + pl01x_putc (CONSOLE_PORT, c); +} + +void serial_puts (const char *s) +{ + while (*s) { + serial_putc (*s++); + } +} + +int serial_getc (void) +{ + return pl01x_getc (CONSOLE_PORT); +} + +int serial_tstc (void) +{ + return pl01x_tstc (CONSOLE_PORT); +} + +void serial_setbrg (void) +{ +} + +static void pl01x_putc (int portnum, char c) +{ + /* Wait until there is space in the FIFO */ + while (IO_READ (port[portnum] + UART_PL01x_FR) & UART_PL01x_FR_TXFF) + WATCHDOG_RESET(); + + /* Send the character */ + IO_WRITE (port[portnum] + UART_PL01x_DR, c); +} + +static int pl01x_getc (int portnum) +{ + unsigned int data; + + /* Wait until there is data in the FIFO */ + while (IO_READ (port[portnum] + UART_PL01x_FR) & UART_PL01x_FR_RXFE) + WATCHDOG_RESET(); + + data = IO_READ (port[portnum] + UART_PL01x_DR); + + /* Check for an error flag */ + if (data & 0xFFFFFF00) { + /* Clear the error */ + IO_WRITE (port[portnum] + UART_PL01x_ECR, 0xFFFFFFFF); + return -1; + } + + return (int) data; +} + +static int pl01x_tstc (int portnum) +{ + WATCHDOG_RESET(); + return !(IO_READ (port[portnum] + UART_PL01x_FR) & + UART_PL01x_FR_RXFE); +} + +#endif diff --git a/drivers/serial/serial_pl01x.h b/drivers/serial/serial_pl01x.h new file mode 100644 index 0000000..5f20fdd --- /dev/null +++ b/drivers/serial/serial_pl01x.h @@ -0,0 +1,137 @@ +/* + * (C) Copyright 2003, 2004 + * ARM Ltd. + * Philippe Robin, + * + * 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 + */ + +/* + * ARM PrimeCell UART's (PL010 & PL011) + * ------------------------------------ + * + * Definitions common to both PL010 & PL011 + * + */ +#define UART_PL01x_DR 0x00 /* Data read or written from the interface. */ +#define UART_PL01x_RSR 0x04 /* Receive status register (Read). */ +#define UART_PL01x_ECR 0x04 /* Error clear register (Write). */ +#define UART_PL01x_FR 0x18 /* Flag register (Read only). */ + +#define UART_PL01x_RSR_OE 0x08 +#define UART_PL01x_RSR_BE 0x04 +#define UART_PL01x_RSR_PE 0x02 +#define UART_PL01x_RSR_FE 0x01 + +#define UART_PL01x_FR_TXFE 0x80 +#define UART_PL01x_FR_RXFF 0x40 +#define UART_PL01x_FR_TXFF 0x20 +#define UART_PL01x_FR_RXFE 0x10 +#define UART_PL01x_FR_BUSY 0x08 +#define UART_PL01x_FR_TMSK (UART_PL01x_FR_TXFF + UART_PL01x_FR_BUSY) + +/* + * PL010 definitions + * + */ +#define UART_PL010_LCRH 0x08 /* Line control register, high byte. */ +#define UART_PL010_LCRM 0x0C /* Line control register, middle byte. */ +#define UART_PL010_LCRL 0x10 /* Line control register, low byte. */ +#define UART_PL010_CR 0x14 /* Control register. */ +#define UART_PL010_IIR 0x1C /* Interrupt indentification register (Read). */ +#define UART_PL010_ICR 0x1C /* Interrupt clear register (Write). */ +#define UART_PL010_ILPR 0x20 /* IrDA low power counter register. */ + +#define UART_PL010_CR_LPE (1 << 7) +#define UART_PL010_CR_RTIE (1 << 6) +#define UART_PL010_CR_TIE (1 << 5) +#define UART_PL010_CR_RIE (1 << 4) +#define UART_PL010_CR_MSIE (1 << 3) +#define UART_PL010_CR_IIRLP (1 << 2) +#define UART_PL010_CR_SIREN (1 << 1) +#define UART_PL010_CR_UARTEN (1 << 0) + +#define UART_PL010_LCRH_WLEN_8 (3 << 5) +#define UART_PL010_LCRH_WLEN_7 (2 << 5) +#define UART_PL010_LCRH_WLEN_6 (1 << 5) +#define UART_PL010_LCRH_WLEN_5 (0 << 5) +#define UART_PL010_LCRH_FEN (1 << 4) +#define UART_PL010_LCRH_STP2 (1 << 3) +#define UART_PL010_LCRH_EPS (1 << 2) +#define UART_PL010_LCRH_PEN (1 << 1) +#define UART_PL010_LCRH_BRK (1 << 0) + + +#define UART_PL010_BAUD_460800 1 +#define UART_PL010_BAUD_230400 3 +#define UART_PL010_BAUD_115200 7 +#define UART_PL010_BAUD_57600 15 +#define UART_PL010_BAUD_38400 23 +#define UART_PL010_BAUD_19200 47 +#define UART_PL010_BAUD_14400 63 +#define UART_PL010_BAUD_9600 95 +#define UART_PL010_BAUD_4800 191 +#define UART_PL010_BAUD_2400 383 +#define UART_PL010_BAUD_1200 767 +/* + * PL011 definitions + * + */ +#define UART_PL011_IBRD 0x24 +#define UART_PL011_FBRD 0x28 +#define UART_PL011_LCRH 0x2C +#define UART_PL011_CR 0x30 +#define UART_PL011_IMSC 0x38 +#define UART_PL011_PERIPH_ID0 0xFE0 + +#define UART_PL011_LCRH_SPS (1 << 7) +#define UART_PL011_LCRH_WLEN_8 (3 << 5) +#define UART_PL011_LCRH_WLEN_7 (2 << 5) +#define UART_PL011_LCRH_WLEN_6 (1 << 5) +#define UART_PL011_LCRH_WLEN_5 (0 << 5) +#define UART_PL011_LCRH_FEN (1 << 4) +#define UART_PL011_LCRH_STP2 (1 << 3) +#define UART_PL011_LCRH_EPS (1 << 2) +#define UART_PL011_LCRH_PEN (1 << 1) +#define UART_PL011_LCRH_BRK (1 << 0) + +#define UART_PL011_CR_CTSEN (1 << 15) +#define UART_PL011_CR_RTSEN (1 << 14) +#define UART_PL011_CR_OUT2 (1 << 13) +#define UART_PL011_CR_OUT1 (1 << 12) +#define UART_PL011_CR_RTS (1 << 11) +#define UART_PL011_CR_DTR (1 << 10) +#define UART_PL011_CR_RXE (1 << 9) +#define UART_PL011_CR_TXE (1 << 8) +#define UART_PL011_CR_LPE (1 << 7) +#define UART_PL011_CR_IIRLP (1 << 2) +#define UART_PL011_CR_SIREN (1 << 1) +#define UART_PL011_CR_UARTEN (1 << 0) + +#define UART_PL011_IMSC_OEIM (1 << 10) +#define UART_PL011_IMSC_BEIM (1 << 9) +#define UART_PL011_IMSC_PEIM (1 << 8) +#define UART_PL011_IMSC_FEIM (1 << 7) +#define UART_PL011_IMSC_RTIM (1 << 6) +#define UART_PL011_IMSC_TXIM (1 << 5) +#define UART_PL011_IMSC_RXIM (1 << 4) +#define UART_PL011_IMSC_DSRMIM (1 << 3) +#define UART_PL011_IMSC_DCDMIM (1 << 2) +#define UART_PL011_IMSC_CTSMIM (1 << 1) +#define UART_PL011_IMSC_RIMIM (1 << 0) -- cgit v1.1