[U-Boot] [PATCH 1/2] Serial support extended up to 6 COMs

Michael Zaidman michael.zaidman at gmail.com
Mon Mar 22 15:24:00 CET 2010


Added support for extra ns16550 chip extending total number of
supported COMs up to 6. This targets the cases when due to the
insufficient number of UART ports on the CPU chip designers are
forced to put additional ns16550 chip on board.

Signed-off-by: Michael Zaidman <michael.zaidman at gmail.com>
---
 drivers/serial/serial.c |  125 +++++++++++++++++++++++++++++++++-------------
 include/serial.h        |    2 +
 2 files changed, 91 insertions(+), 36 deletions(-)

diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c
index dd5f332..0b30ff4 100644
--- a/drivers/serial/serial.c
+++ b/drivers/serial/serial.c
@@ -2,6 +2,29 @@
  * (C) Copyright 2000
  * Rob Taylor, Flying Pig Systems. robt at flyingpig.com.
  *
+ * (C) Copyright 2010
+ * Eastman Kodak Company, <www.kodak.com>
+ * Michael Zaidman, <michael.zaidman at kodak.com>
+ *
+ * Added support for extra ns16550 chip extending total number of
+ * supported COMs to 6. This targets the cases when due to the
+ * insufficient number of UART ports on the CPU chip designers are
+ * forced to put additional ns16550 chip on board. In order to
+ * configure its clock two new CONFIGs have been added:
+ * CONFIG_SYS_NS16550_HI_PORTS_BGN - specifies index of the first
+ *		High COM port, i.e. first port of the extra chip.
+ *		For example: if CPU chip has 2 COMs then its value should
+ *		be configured to 3.
+ *		If no CONFIG_SYS_NS16550_HI_PORTS_BGN was defined all COMs
+ *		will be configured with CONFIG_SYS_NS16550_CLK
+ *
+ * CONFIG_SYS_NS16550_HI_PORTS_CLK - High COMs clock.
+ *
+ * Also in order to add COM5 and COM6 the following configuration
+ * entries should be defined:
+ * CONFIG_SYS_NS16550_COM5,
+ * CONFIG_SYS_NS16550_COM6
+ *
  * See file CREDITS for list of people who contributed to this
  * project.
  *
@@ -22,8 +45,8 @@
  */
 
 #include <common.h>
-
 #include <ns16550.h>
+
 #ifdef CONFIG_NS87308
 #include <ns87308.h>
 #endif
@@ -45,7 +68,7 @@ DECLARE_GLOBAL_DATA_PTR;
 #else
 #error	"No console index specified."
 #endif /* CONFIG_SERIAL_MULTI */
-#elif (CONFIG_CONS_INDEX < 1) || (CONFIG_CONS_INDEX > 4)
+#elif (CONFIG_CONS_INDEX < 1) || (CONFIG_CONS_INDEX > 6)
 #error	"Invalid console index value."
 #endif
 
@@ -57,34 +80,62 @@ DECLARE_GLOBAL_DATA_PTR;
 #error	"Console port 3 defined but not configured."
 #elif CONFIG_CONS_INDEX == 4 && !defined(CONFIG_SYS_NS16550_COM4)
 #error	"Console port 4 defined but not configured."
+#elif CONFIG_CONS_INDEX == 5 && !defined(CONFIG_SYS_NS16550_COM5)
+#error	"Console port 5 defined but not configured."
+#elif CONFIG_CONS_INDEX == 6 && !defined(CONFIG_SYS_NS16550_COM6)
+#error	"Console port 6 defined but not configured."
 #endif
 
 /* Note: The port number specified in the functions is 1 based.
  *	 the array is 0 based.
  */
-static NS16550_t serial_ports[4] = {
+static NS16550_t serial_ports[] = {
 #ifdef CONFIG_SYS_NS16550_COM1
-	(NS16550_t)CONFIG_SYS_NS16550_COM1,
+	(NS16550_t)CONFIG_SYS_NS16550_COM1
 #else
-	NULL,
+	NULL
 #endif
+
 #ifdef CONFIG_SYS_NS16550_COM2
-	(NS16550_t)CONFIG_SYS_NS16550_COM2,
-#else
-	NULL,
+	,(NS16550_t)CONFIG_SYS_NS16550_COM2
+#elif \
+	defined(CONFIG_SYS_NS16550_COM3) || \
+	defined(CONFIG_SYS_NS16550_COM4) || \
+	defined(CONFIG_SYS_NS16550_COM5) || \
+	defined(CONFIG_SYS_NS16550_COM6)
+	,NULL
 #endif
+
 #ifdef CONFIG_SYS_NS16550_COM3
-	(NS16550_t)CONFIG_SYS_NS16550_COM3,
-#else
-	NULL,
+	,(NS16550_t)CONFIG_SYS_NS16550_COM3
+#elif \
+	defined(CONFIG_SYS_NS16550_COM4) || \
+	defined(CONFIG_SYS_NS16550_COM5) || \
+	defined(CONFIG_SYS_NS16550_COM6)
+	,NULL
 #endif
+
 #ifdef CONFIG_SYS_NS16550_COM4
-	(NS16550_t)CONFIG_SYS_NS16550_COM4
-#else
-	NULL
+	,(NS16550_t)CONFIG_SYS_NS16550_COM4
+#elif \
+	defined(CONFIG_SYS_NS16550_COM5) || \
+	defined(CONFIG_SYS_NS16550_COM6)
+	,NULL
+#endif
+
+#ifdef CONFIG_SYS_NS16550_COM5
+	,(NS16550_t)CONFIG_SYS_NS16550_COM5
+#elif defined(CONFIG_SYS_NS16550_COM6)
+	,NULL
+#endif
+
+#ifdef CONFIG_SYS_NS16550_COM6
+	,(NS16550_t)CONFIG_SYS_NS16550_COM6
 #endif
 };
 
+#define MAX_SER_DEV ((sizeof(serial_ports)/sizeof(NS16550_t)))
+
 #define PORT	serial_ports[port-1]
 #if defined(CONFIG_CONS_INDEX)
 #define CONSOLE	(serial_ports[CONFIG_CONS_INDEX-1])
@@ -96,7 +147,7 @@ static NS16550_t serial_ports[4] = {
 #define DECLARE_ESERIAL_FUNCTIONS(port) \
     int  eserial##port##_init (void) {\
 	int clock_divisor; \
-	clock_divisor = calc_divisor(serial_ports[port-1]); \
+	clock_divisor = calc_divisor(port-1); \
 	NS16550_init(serial_ports[port-1], clock_divisor); \
 	return(0);}\
     void eserial##port##_setbrg (void) {\
@@ -123,9 +174,12 @@ static NS16550_t serial_ports[4] = {
 
 #endif /* CONFIG_SERIAL_MULTI */
 
-static int calc_divisor (NS16550_t port)
+static int calc_divisor (int index)
 {
+	ulong clock = CONFIG_SYS_NS16550_CLK;
+
 #ifdef CONFIG_OMAP1510
+	NS16550_t port = serial_ports[index];
 	/* If can't cleanly clock 115200 set div to 1 */
 	if ((CONFIG_SYS_NS16550_CLK == 12000000) && (gd->baudrate == 115200)) {
 		port->osc_12m_sel = OSC_12M_SEL;	/* enable 6.5 * divisor */
@@ -151,35 +205,27 @@ static int calc_divisor (NS16550_t port)
 	 * but we need to round that value by adding 0.5.
 	 * Rounding is especially important at high baud rates.
 	 */
-	return (CONFIG_SYS_NS16550_CLK + (gd->baudrate * (MODE_X_DIV / 2))) /
-		(MODE_X_DIV * gd->baudrate);
+#ifdef CONFIG_SYS_NS16550_HI_PORTS_BGN
+	if ((index + 1) >= CONFIG_SYS_NS16550_HI_PORTS_BGN)
+		clock = CONFIG_SYS_NS16550_HI_PORTS_CLK;
+#endif
+	return (clock + (gd->baudrate * (MODE_X_DIV / 2))) /
+			(MODE_X_DIV * gd->baudrate);
+
 }
 
 #if !defined(CONFIG_SERIAL_MULTI)
 int serial_init (void)
 {
-	int clock_divisor;
+	int i;
 
 #ifdef CONFIG_NS87308
 	initialise_ns87308();
 #endif
 
-#ifdef CONFIG_SYS_NS16550_COM1
-	clock_divisor = calc_divisor(serial_ports[0]);
-	NS16550_init(serial_ports[0], clock_divisor);
-#endif
-#ifdef CONFIG_SYS_NS16550_COM2
-	clock_divisor = calc_divisor(serial_ports[1]);
-	NS16550_init(serial_ports[1], clock_divisor);
-#endif
-#ifdef CONFIG_SYS_NS16550_COM3
-	clock_divisor = calc_divisor(serial_ports[2]);
-	NS16550_init(serial_ports[2], clock_divisor);
-#endif
-#ifdef CONFIG_SYS_NS16550_COM4
-	clock_divisor = calc_divisor(serial_ports[3]);
-	NS16550_init(serial_ports[3], clock_divisor);
-#endif
+	for (i = 0; i < MAX_SER_DEV; i++)
+		if (serial_ports[i] != NULL)
+			NS16550_init(serial_ports[i], calc_divisor(i));
 
 	return (0);
 }
@@ -226,7 +272,7 @@ _serial_setbrg (const int port)
 {
 	int clock_divisor;
 
-	clock_divisor = calc_divisor(PORT);
+	clock_divisor = calc_divisor(port-1);
 	NS16550_reinit(PORT, clock_divisor);
 }
 
@@ -328,4 +374,11 @@ struct serial_device eserial3_device =
 DECLARE_ESERIAL_FUNCTIONS(4);
 struct serial_device eserial4_device =
 	INIT_ESERIAL_STRUCTURE(4,"eserial3","EUART4");
+DECLARE_ESERIAL_FUNCTIONS(5);
+struct serial_device eserial5_device =
+	INIT_ESERIAL_STRUCTURE(5,"eserial4","EUART5");
+DECLARE_ESERIAL_FUNCTIONS(6);
+struct serial_device eserial6_device =
+	INIT_ESERIAL_STRUCTURE(6,"eserial5","EUART6");
 #endif /* CONFIG_SERIAL_MULTI */
+
diff --git a/include/serial.h b/include/serial.h
index f2638ec..be2f8bc 100644
--- a/include/serial.h
+++ b/include/serial.h
@@ -33,6 +33,8 @@ extern struct serial_device eserial1_device;
 extern struct serial_device eserial2_device;
 extern struct serial_device eserial3_device;
 extern struct serial_device eserial4_device;
+extern struct serial_device eserial5_device;
+extern struct serial_device eserial6_device;
 #endif /* CONFIG_SYS_NS16550_SERIAL */
 
 #endif
-- 
1.6.3.3



More information about the U-Boot mailing list