
The fact that cpu/i386 has contained a serial driver has been a pet peeve of mine for some time. I was just going to move it into lib_i386, but decided that migrating to SERIAL_MULTI was probably the better option since there is already a 16550 driver which is SERIAL_MULTI compatible and my board has no less than five serial ports.
My only concern is that the 16550 driver is a memory-mapped driver, while the x86 arch uses port-mapping. I've hacked the driver to use port-mapping for x86 and it works fine.
Looking at the driver though, I think it should be using memory accessor functions (readb, writeb) to prevent gcc optimisations doing funny things as the writing of commands to the 16550 is very order dependent.
Should I instead define some macros that allow easy selection of inb/outb versus readb/writeb based on arch?
Regards,
Graeme
--- board/eNET/eNET.c | 3 +- common/serial.c | 3 +- cpu/i386/Makefile | 2 +- drivers/serial/ns16550.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++ include/configs/eNET.h | 25 +++++++++++++++++---- include/serial.h | 3 +- lib_i386/board.c | 4 +++ 7 files changed, 83 insertions(+), 9 deletions(-)
diff --git a/board/eNET/eNET.c b/board/eNET/eNET.c index baf7c95..03bca00 100644 --- a/board/eNET/eNET.c +++ b/board/eNET/eNET.c @@ -111,8 +111,9 @@ int board_early_init_f(void) sc520_mmcr->romcs1ctl = 0x0615; sc520_mmcr->romcs2ctl = 0x0615;
- sc520_mmcr->adddecctl = 0x02; + sc520_mmcr->adddecctl = 0x00; sc520_mmcr->uart1ctl = 0x07; + sc520_mmcr->uart2ctl = 0x07; sc520_mmcr->sysarbctl = 0x06; sc520_mmcr->sysarbmenb = 0x0003;
diff --git a/common/serial.c b/common/serial.c index b4db46b..0c88416 100644 --- a/common/serial.c +++ b/common/serial.c @@ -41,7 +41,8 @@ struct serial_device *__default_serial_console (void) #elif defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440) \ || defined(CONFIG_405EP) || defined(CONFIG_405EZ) || defined(CONFIG_405EX) \ || defined(CONFIG_MPC5xxx) || defined(CONFIG_MPC83xx) \ - || defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx) + || defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx) \ + || defined(CONFIG_SYS_SC520) #if defined(CONFIG_CONS_INDEX) && defined(CONFIG_SYS_NS16550_SERIAL) #if (CONFIG_CONS_INDEX==1) return &eserial1_device; diff --git a/cpu/i386/Makefile b/cpu/i386/Makefile index c658c6e..bb0a48f 100644 --- a/cpu/i386/Makefile +++ b/cpu/i386/Makefile @@ -29,7 +29,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(CPU).a
START = start.o start16.o resetvec.o -COBJS = serial.o interrupts.o cpu.o +COBJS = interrupts.o cpu.o
SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c index 2fcc8c3..6dede98 100644 --- a/drivers/serial/ns16550.c +++ b/drivers/serial/ns16550.c @@ -6,6 +6,8 @@
#include <config.h> #include <ns16550.h> +#include <linux/types.h> +#include <asm/io.h>
#define UART_LCRVAL UART_LCR_8N1 /* 8 data, 1 stop, no parity */ #define UART_MCRVAL (UART_MCR_DTR | \ @@ -16,10 +18,26 @@
void NS16550_init (NS16550_t com_port, int baud_divisor) { +#ifdef CONFIG_X86 + outb(0x00, (ulong)&com_port->ier); +#else com_port->ier = 0x00; +#endif #if defined(CONFIG_OMAP) && !defined(CONFIG_OMAP3_ZOOM2) com_port->mdr1 = 0x7; /* mode select reset TL16C750*/ #endif +#ifdef CONFIG_X86 + outb(UART_LCR_BKSE | UART_LCRVAL, (ulong)&com_port->lcr); + outb(0, (ulong)&com_port->dll); + outb(0, (ulong)&com_port->dlm); + outb(UART_LCRVAL, (ulong)&com_port->lcr); + outb(UART_MCRVAL, (ulong)&com_port->mcr); + outb(UART_FCRVAL, (ulong)&com_port->fcr); + outb(UART_LCR_BKSE | UART_LCRVAL, (ulong)&com_port->lcr); + outb(baud_divisor & 0xff, (ulong)&com_port->dll); + outb((baud_divisor >> 8) & 0xff, (ulong)&com_port->dlm); + outb(UART_LCRVAL, (ulong)&com_port->lcr); +#else com_port->lcr = UART_LCR_BKSE | UART_LCRVAL; com_port->dll = 0; com_port->dlm = 0; @@ -30,6 +48,7 @@ void NS16550_init (NS16550_t com_port, int baud_divisor) com_port->dll = baud_divisor & 0xff; com_port->dlm = (baud_divisor >> 8) & 0xff; com_port->lcr = UART_LCRVAL; +#endif #if defined(CONFIG_OMAP) && !defined(CONFIG_OMAP3_ZOOM2) #if defined(CONFIG_APTIX) com_port->mdr1 = 3; /* /13 mode so Aptix 6MHz can hit 115200 */ @@ -42,6 +61,19 @@ void NS16550_init (NS16550_t com_port, int baud_divisor) #ifndef CONFIG_NS16550_MIN_FUNCTIONS void NS16550_reinit (NS16550_t com_port, int baud_divisor) { +#ifdef CONFIG_X86 + outb(0x00, (ulong)&com_port->ier); + outb(UART_LCR_BKSE | UART_LCRVAL, (ulong)&com_port->lcr); + outb(0, (ulong)&com_port->dll); + outb(0, (ulong)&com_port->dlm); + outb(UART_LCRVAL, (ulong)&com_port->lcr); + outb(UART_MCRVAL, (ulong)&com_port->mcr); + outb(UART_FCRVAL, (ulong)&com_port->fcr); + outb(UART_LCR_BKSE, (ulong)&com_port->lcr); + outb(baud_divisor & 0xff, (ulong)&com_port->dll); + outb((baud_divisor >> 8) & 0xff, (ulong)&com_port->dlm); + outb(UART_LCRVAL, (ulong)&com_port->lcr); +#else com_port->ier = 0x00; com_port->lcr = UART_LCR_BKSE | UART_LCRVAL; com_port->dll = 0; @@ -53,18 +85,33 @@ void NS16550_reinit (NS16550_t com_port, int baud_divisor) com_port->dll = baud_divisor & 0xff; com_port->dlm = (baud_divisor >> 8) & 0xff; com_port->lcr = UART_LCRVAL; +#endif } #endif /* CONFIG_NS16550_MIN_FUNCTIONS */
void NS16550_putc (NS16550_t com_port, char c) { +#ifdef CONFIG_X86 + while ((inb((ulong)&com_port->lsr) & UART_LSR_THRE) == 0); + outb(c, (ulong)&com_port->thr); +#else while ((com_port->lsr & UART_LSR_THRE) == 0); com_port->thr = c; +#endif }
#ifndef CONFIG_NS16550_MIN_FUNCTIONS char NS16550_getc (NS16550_t com_port) { +#ifdef CONFIG_X86 + while ((inb((ulong)&com_port->lsr) & UART_LSR_DR) == 0) { +#ifdef CONFIG_USB_TTY + extern void usbtty_poll(void); + usbtty_poll(); +#endif + } + return inb((ulong)&com_port->rbr); +#else while ((com_port->lsr & UART_LSR_DR) == 0) { #ifdef CONFIG_USB_TTY extern void usbtty_poll(void); @@ -72,11 +119,16 @@ char NS16550_getc (NS16550_t com_port) #endif } return (com_port->rbr); +#endif }
int NS16550_tstc (NS16550_t com_port) { +#ifdef CONFIG_X86 + return ((inb((ulong)&com_port->lsr) & UART_LSR_DR) != 0); +#else return ((com_port->lsr & UART_LSR_DR) != 0); +#endif }
#endif /* CONFIG_NS16550_MIN_FUNCTIONS */ diff --git a/include/configs/eNET.h b/include/configs/eNET.h index 6a68bf4..971840f 100644 --- a/include/configs/eNET.h +++ b/include/configs/eNET.h @@ -21,6 +21,7 @@ * MA 02111-1307 USA */
+#include <asm/ibmpc.h> /* * board/config.h - configuration options, board specific */ @@ -55,6 +56,25 @@ #undef CONFIG_HW_WATCHDOG
/*----------------------------------------------------------------------- + * Serial Configuration + */ +#define CONFIG_SERIAL_MULTI +#undef CONFIG_SERIAL_SOFTWARE_FIFO +#define CONFIG_CONS_INDEX 1 +#define CONFIG_SYS_NS16550 +#define CONFIG_SYS_NS16550_SERIAL +#define CONFIG_SYS_NS16550_REG_SIZE 1 +#define CONFIG_SYS_NS16550_CLK 1843200 +#define CONFIG_BAUDRATE 9600 +#define CONFIG_SYS_BAUDRATE_TABLE \ + {300, 600, 1200, 2400, 4800, 9600, 19200, 38400,115200} + +#define CONFIG_SYS_NS16550_COM1 UART0_BASE +#define CONFIG_SYS_NS16550_COM2 UART1_BASE +#define CONFIG_SYS_NS16550_COM3 (0x1000 + UART0_BASE) +#define CONFIG_SYS_NS16550_COM4 (0x1000 + UART1_BASE) + + /*----------------------------------------------------------------------- * Video Configuration */ #undef CONFIG_VIDEO /* No Video Hardware */ @@ -65,8 +85,6 @@ */ #define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 128*1024)
-#define CONFIG_BAUDRATE 9600 - /*----------------------------------------------------------------------- * Command line configuration. */ @@ -123,9 +141,6 @@
#define CONFIG_SYS_HZ 1024 /* incrementer freq: 1kHz */
- /* valid baudrates */ -#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } - /*----------------------------------------------------------------------- * SDRAM Configuration */ diff --git a/include/serial.h b/include/serial.h index 821b583..daaa0c2 100644 --- a/include/serial.h +++ b/include/serial.h @@ -25,7 +25,8 @@ extern struct serial_device * default_serial_console (void); #if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440) || \ defined(CONFIG_405EP) || defined(CONFIG_405EZ) || defined(CONFIG_405EX) || \ defined(CONFIG_MPC5xxx) || defined(CONFIG_MPC83xx) || \ - defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx) + defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx) || \ + defined(CONFIG_SYS_SC520) extern struct serial_device serial0_device; extern struct serial_device serial1_device; #if defined(CONFIG_SYS_NS16550_SERIAL) diff --git a/lib_i386/board.c b/lib_i386/board.c index f3b6348..9becae5 100644 --- a/lib_i386/board.c +++ b/lib_i386/board.c @@ -37,6 +37,7 @@ #include <malloc.h> #include <net.h> #include <ide.h> +#include <serial.h> #include <asm/u-boot-i386.h> #include <elf.h>
@@ -268,6 +269,9 @@ void board_init_r(gd_t *id, ulong ram_start) } show_boot_progress(0x23);
+#ifdef CONFIG_SERIAL_MULTI + serial_initialize(); +#endif /* configure available FLASH banks */ size = flash_init(); display_flash_config(size);