diff options
author | Sascha Hauer <sha@octopus.labnet.pengutronix.de> | 2007-09-11 10:16:13 +0200 |
---|---|---|
committer | Sascha Hauer <sha@octopus.labnet.pengutronix.de> | 2007-09-11 10:16:13 +0200 |
commit | 50a6dc93593e3026f532114dccfc647117819f81 (patch) | |
tree | 47b9b7438f7ef09f9221d7897926451d7d0a1fe2 /drivers | |
parent | 97c0278dc1cdef940d837be932a284c2bd7f4d35 (diff) | |
download | barebox-50a6dc93593e3026f532114dccfc647117819f81.tar.gz barebox-50a6dc93593e3026f532114dccfc647117819f81.tar.xz |
add blackfin serial driver
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/serial/Kconfig | 4 | ||||
-rw-r--r-- | drivers/serial/Makefile | 1 | ||||
-rw-r--r-- | drivers/serial/serial_bf533.c | 195 | ||||
-rw-r--r-- | drivers/serial/serial_bf533.h | 78 | ||||
-rw-r--r-- | drivers/serial/serial_blackfin.c | 147 |
5 files changed, 152 insertions, 273 deletions
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 7514e86c09..154600672e 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -20,4 +20,8 @@ config DRIVER_SERIAL_MPC5XXX default y bool "MPC5200 serial driver" +config DRIVER_SERIAL_BLACKFIN + depends on BLACKFIN + default y + bool "Blackfin serial driver" endmenu diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index c4ed00fc1e..088d03dfc5 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -9,3 +9,4 @@ obj-$(CONFIG_DRIVER_SERIAL_IMX) += serial_imx.o obj-$(CONFIG_DRIVER_SERIAL_NETX) += serial_netx.o obj-$(CONFIG_DRIVER_SERIAL_LINUX_COMSOLE) += linux_console.o obj-$(CONFIG_DRIVER_SERIAL_MPC5XXX) += serial_mpc5xxx.o +obj-$(CONFIG_DRIVER_SERIAL_BLACKFIN) += serial_blackfin.o diff --git a/drivers/serial/serial_bf533.c b/drivers/serial/serial_bf533.c deleted file mode 100644 index 7b43ffd188..0000000000 --- a/drivers/serial/serial_bf533.c +++ /dev/null @@ -1,195 +0,0 @@ -/* - * U-boot - serial.c Serial driver for BF533 - * - * Copyright (c) 2005 blackfin.uclinux.org - * - * This file is based on - * bf533_serial.c: Serial driver for BlackFin BF533 DSP internal UART. - * Copyright (c) 2003 Bas Vermeulen <bas@buyways.nl>, - * BuyWays B.V. (www.buyways.nl) - * - * Based heavily on blkfinserial.c - * blkfinserial.c: Serial driver for BlackFin DSP internal USRTs. - * Copyright(c) 2003 Metrowerks <mwaddel@metrowerks.com> - * Copyright(c) 2001 Tony Z. Kou <tonyko@arcturusnetworks.com> - * Copyright(c) 2001-2002 Arcturus Networks Inc. <www.arcturusnetworks.com> - * - * Based on code from 68328 version serial driver imlpementation which was: - * Copyright (C) 1995 David S. Miller <davem@caip.rutgers.edu> - * Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com> - * Copyright (C) 1998, 1999 D. Jeff Dionne <jeff@uclinux.org> - * Copyright (C) 1999 Vladimir Gurevich <vgurevic@cisco.com> - * - * (C) Copyright 2000-2004 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * 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 <common.h> -#include <asm/irq.h> -#include <asm/system.h> -#include <asm/segment.h> -#include <asm/bitops.h> -#include <asm/delay.h> -#include <asm/uaccess.h> -#include "bf533_serial.h" - -DECLARE_GLOBAL_DATA_PTR; - -unsigned long pll_div_fact; - -void calc_baud(void) -{ - unsigned char i; - int temp; - - for(i = 0; i < sizeof(baud_table)/sizeof(int); i++) { - temp = CONFIG_SCLK_HZ/(baud_table[i]*8); - if ( temp && 0x1 == 1 ) { - temp++; - } - temp = temp/2; - hw_baud_table[i].dl_high = (temp >> 8)& 0xFF; - hw_baud_table[i].dl_low = (temp) & 0xFF; - } -} - -void serial_setbrg(void) -{ - int i; - - calc_baud(); - - for (i = 0; i < sizeof(baud_table) / sizeof(int); i++) { - if (gd->baudrate == baud_table[i]) - break; - } - - /* Enable UART */ - *pUART_GCTL |= UART_GCTL_UCEN; - asm("ssync;"); - - /* Set DLAB in LCR to Access DLL and DLH */ - ACCESS_LATCH; - asm("ssync;"); - - *pUART_DLL = hw_baud_table[i].dl_low; - asm("ssync;"); - *pUART_DLH = hw_baud_table[i].dl_high; - asm("ssync;"); - - /* Clear DLAB in LCR to Access THR RBR IER */ - ACCESS_PORT_IER; - asm("ssync;"); - - /* Enable ERBFI and ELSI interrupts - * to poll SIC_ISR register*/ - *pUART_IER = UART_IER_ELSI | UART_IER_ERBFI | UART_IER_ETBEI; - asm("ssync;"); - - /* Set LCR to Word Lengh 8-bit word select */ - *pUART_LCR = UART_LCR_WLS8; - asm("ssync;"); - - return; -} - -int serial_init(void) -{ - serial_setbrg(); - return (0); -} - -void serial_putc(const char c) -{ - if ((*pUART_LSR) & UART_LSR_TEMT) - { - if (c == '\n') - serial_putc('\r'); - - local_put_char(c); - } - - while (!((*pUART_LSR) & UART_LSR_TEMT)) - SYNC_ALL; - - return; -} - -int serial_tstc(void) -{ - if (*pUART_LSR & UART_LSR_DR) - return 1; - else - return 0; -} - -int serial_getc(void) -{ - unsigned short uart_lsr_val, uart_rbr_val; - unsigned long isr_val; - int ret; - - /* Poll for RX Interrupt */ - while (!((isr_val = *(volatile unsigned long *)SIC_ISR) & IRQ_UART_RX_BIT)); - asm("csync;"); - - uart_lsr_val = *pUART_LSR; /* Clear status bit */ - uart_rbr_val = *pUART_RBR; /* getc() */ - - if (isr_val & IRQ_UART_ERROR_BIT) { - ret = -1; - } - else - { - ret = uart_rbr_val & 0xff; - } - - return ret; -} - -void serial_puts(const char *s) -{ - while (*s) { - serial_putc(*s++); - } -} - -static void local_put_char(char ch) -{ - int flags = 0; - unsigned long isr_val; - - save_and_cli(flags); - - /* Poll for TX Interruput */ - while (!((isr_val = *pSIC_ISR) & IRQ_UART_TX_BIT)); - asm("csync;"); - - *pUART_THR = ch; /* putc() */ - - if (isr_val & IRQ_UART_ERROR_BIT) { - printf("?"); - } - - restore_flags(flags); - - return ; -} diff --git a/drivers/serial/serial_bf533.h b/drivers/serial/serial_bf533.h deleted file mode 100644 index d430e6cabd..0000000000 --- a/drivers/serial/serial_bf533.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * U-boot - bf533_serial.h Serial Driver defines - * - * Copyright (c) 2005 blackfin.uclinux.org - * - * This file is based on - * bf533_serial.h: Definitions for the BlackFin BF533 DSP serial driver. - * Copyright (C) 2003 Bas Vermeulen <bas@buyways.nl> - * BuyWays B.V. (www.buyways.nl) - * - * Based heavily on: - * blkfinserial.h: Definitions for the BlackFin DSP serial driver. - * - * Copyright (C) 2001 Tony Z. Kou tonyko@arcturusnetworks.com - * Copyright (C) 2001 Arcturus Networks Inc. <www.arcturusnetworks.com> - * - * Based on code from 68328serial.c which was: - * Copyright (C) 1995 David S. Miller <davem@caip.rutgers.edu> - * Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com> - * Copyright (C) 1998, 1999 D. Jeff Dionne <jeff@uclinux.org> - * Copyright (C) 1999 Vladimir Gurevich <vgurevic@cisco.com> - * - * (C) Copyright 2000-2004 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * 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 - */ - -#ifndef _Bf533_SERIAL_H -#define _Bf533_SERIAL_H - -#include <linux/config.h> -#include <asm/blackfin.h> - -#define SYNC_ALL __asm__ __volatile__ ("ssync;\n") -#define ACCESS_LATCH *pUART_LCR |= UART_LCR_DLAB; -#define ACCESS_PORT_IER *pUART_LCR &= (~UART_LCR_DLAB); - -void serial_setbrg(void); -static void local_put_char(char ch); -void calc_baud(void); -void serial_setbrg(void); -int serial_init(void); -void serial_putc(const char c); -int serial_tstc(void); -int serial_getc(void); -void serial_puts(const char *s); -static void local_put_char(char ch); - -extern int get_clock(void); -int baud_table[5] = {9600, 19200, 38400, 57600, 115200}; - -struct { - unsigned char dl_high; - unsigned char dl_low; -} hw_baud_table[5]; - -#ifdef CONFIG_STAMP -extern unsigned long pll_div_fact; -#endif - -#endif diff --git a/drivers/serial/serial_blackfin.c b/drivers/serial/serial_blackfin.c new file mode 100644 index 0000000000..105e3493c9 --- /dev/null +++ b/drivers/serial/serial_blackfin.c @@ -0,0 +1,147 @@ +/* + * (C) Copyright 2005 + * Sascha Hauer, Pengutronix <s.hauer@pengutronix.de> + * + * 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 <common.h> +#include <driver.h> +#include <init.h> +#include <malloc.h> +#include <asm/io.h> +#include <asm/blackfin.h> + +#define UART_IER_ERBFI 0x01 +#define UART_IER_ETBEI 0x02 +#define UART_IER_ELSI 0x04 +#define UART_IER_EDDSI 0x08 + +#define UART_IIR_NOINT 0x01 +#define UART_IIR_STATUS 0x06 +#define UART_IIR_LSR 0x06 +#define UART_IIR_RBR 0x04 +#define UART_IIR_THR 0x02 +#define UART_IIR_MSR 0x00 + +#define UART_LCR_WLS5 0 +#define UART_LCR_WLS6 0x01 +#define UART_LCR_WLS7 0x02 +#define UART_LCR_WLS8 0x03 +#define UART_LCR_STB 0x04 +#define UART_LCR_PEN 0x08 +#define UART_LCR_EPS 0x10 +#define UART_LCR_SP 0x20 +#define UART_LCR_SB 0x40 +#define UART_LCR_DLAB 0x80 + +#define UART_LSR_DR 0x01 +#define UART_LSR_OE 0x02 +#define UART_LSR_PE 0x04 +#define UART_LSR_FE 0x08 +#define UART_LSR_BI 0x10 +#define UART_LSR_THRE 0x20 +#define UART_LSR_TEMT 0x40 + +#define UART_GCTL_UCEN 0x01 + +static int blackfin_serial_setbaudrate(struct console_device *cdev, int baudrate) +{ + int divisor, oldlcr; + + oldlcr = readw(UART_LCR); + + divisor = get_sclk() / (baudrate * 16); + + /* Set DLAB in LCR to Access DLL and DLH */ + writew(UART_LCR_DLAB, UART_LCR); + + writew(divisor & 0xff, UART_DLL); + writew((divisor >> 8) & 0xff, UART_DLH); + + /* Clear DLAB in LCR to Access THR RBR IER */ + writew(oldlcr, UART_LCR); + + return 0; +} + +static int blackfin_serial_init_port(struct console_device *cdev) +{ + /* Enable UART */ + writew(UART_GCTL_UCEN, UART_GCTL); + + /* Set LCR to Word Lengh 8-bit word select */ + writew(UART_LCR_WLS8, UART_LCR); + + return 0; +} + +static void blackfin_serial_putc(struct console_device *cdev, char c) +{ + while (!(readw(UART_LSR) & UART_LSR_TEMT)); + + writew(c, UART_THR); +} + +static int blackfin_serial_getc(struct console_device *cdev) +{ + while (!(readw(UART_LSR) & UART_LSR_DR)); + + return readw(UART_RBR); +} + +static int blackfin_serial_tstc(struct console_device *cdev) +{ + return (readw(UART_LSR) & UART_LSR_DR) ? 1 : 0; +} + +static int blackfin_serial_probe(struct device_d *dev) +{ + struct console_device *cdev; + + cdev = malloc(sizeof(struct console_device)); + dev->type_data = cdev; + cdev->dev = dev; + cdev->f_caps = CONSOLE_STDIN | CONSOLE_STDOUT | CONSOLE_STDERR; + cdev->tstc = blackfin_serial_tstc; + cdev->putc = blackfin_serial_putc; + cdev->getc = blackfin_serial_getc; + cdev->setbrg = blackfin_serial_setbaudrate; + + blackfin_serial_init_port(cdev); + + console_register(cdev); + + return 0; +} + +static struct driver_d blackfin_serial_driver = { + .name = "blackfin_serial", + .probe = blackfin_serial_probe, + .type = DEVICE_TYPE_CONSOLE, +}; + +static int blackfin_serial_init(void) +{ + register_driver(&blackfin_serial_driver); + return 0; +} + +console_initcall(blackfin_serial_init); + |