Add support for CONFIG_SERIAL_MULTI on MPC5xxx
authorWolfgang Denk <wd@fifi.denx.de>
Fri, 16 Jun 2006 15:04:45 +0000 (17:04 +0200)
committerWolfgang Denk <wd@fifi.denx.de>
Fri, 16 Jun 2006 15:04:45 +0000 (17:04 +0200)
Patch by Martin Krause, 8 Jun 2006

This patch supports two serial consoles on boards with
a MPC5xxx CPU. The console can be switched at runtime
by setting stdin, stdout and stderr to the desired serial
interface (serial0 or serial1). The PSCs to be used as
console port are definded by CONFIG_PSC_CONSOLE
and CONFIG_PSC_CONSOLE2.
See README.serial_multi for details.

CHANGELOG
common/serial.c
cpu/mpc5xxx/serial.c
doc/README.serial_multi
include/serial.h

index af8df174d9fcdfb8279ed984a80784852d1f2572..dd73e0bef3803cebe23a685aeac2ee705a00b95c 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,17 @@
 Changes since U-Boot 1.1.4:
 ======================================================================
 
+* Add support for CONFIG_SERIAL_MULTI on MPC5xxx
+  Patch by Martin Krause, 8 Jun 2006
+
+  This patch supports two serial consoles on boards with
+  a MPC5xxx CPU. The console can be switched at runtime
+  by setting stdin, stdout and stderr to the desired serial
+  interface (serial0 or serial1). The PSCs to be used as
+  console port are definded by CONFIG_PSC_CONSOLE
+  and CONFIG_PSC_CONSOLE2.
+  See README.serial_multi for details.
+
 * Bugfix in I2C initialisation on S3C2400.
   If the bus is blocked because of a previously interrupted
   transfer, up to eleven clocks are generated on the I2CSCL
index 2acbd08b16d2c09c4f70c63e9894867ed0feba9c..7b29951708425663894ceac7c0cf98c895f40911 100644 (file)
@@ -41,7 +41,7 @@ struct serial_device *default_serial_console (void)
    || defined(CONFIG_8xx_CONS_SCC3) || defined(CONFIG_8xx_CONS_SCC4)
        return &serial_scc_device;
 #elif defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440) \
-   || defined(CONFIG_405EP)
+   || defined(CONFIG_405EP) || defined(CONFIG_MPC5xxx)
        return &serial0_device;
 #else
 #error No default console
@@ -75,7 +75,7 @@ void serial_initialize (void)
 #endif
 
 #if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440) \
- || defined(CONFIG_405EP)
+ || defined(CONFIG_405EP) || defined(CONFIG_MPC5xxx)
        serial_register(&serial0_device);
        serial_register(&serial1_device);
 #endif
index cacb9f057335c855145d185dab1e0cf7e3a9811e..6cb523d3c7bf5428d03497341d11906e93d50bcf 100644 (file)
@@ -23,6 +23,9 @@
  * Hacked for MPC8260 by Murray.Jensen@cmst.csiro.au, 19-Oct-00, with
  * changes based on the file arch/ppc/mbxboot/m8260_tty.c from the
  * Linux/PPC sources (m8260_tty.c had no copyright info in it).
+ *
+ * Martin Krause, 8 Jun 2006
+ * Added CONFIG_SERIAL_MULTI support
  */
 
 /*
 #include <common.h>
 #include <mpc5xxx.h>
 
+#if defined (CONFIG_SERIAL_MULTI)
+#include <serial.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 #if defined(CONFIG_PSC_CONSOLE)
@@ -55,9 +62,41 @@ DECLARE_GLOBAL_DATA_PTR;
 #error CONFIG_PSC_CONSOLE must be in 1 ... 6
 #endif
 
+#if defined(CONFIG_SERIAL_MULTI) && !defined(CONFIG_PSC_CONSOLE2)
+#error you must define CONFIG_PSC_CONSOLE2 if CONFIG_SERIAL_MULTI is set
+#endif
+
+#if defined(CONFIG_SERIAL_MULTI)
+#if CONFIG_PSC_CONSOLE2 == 1
+#define PSC_BASE2 MPC5XXX_PSC1
+#elif CONFIG_PSC_CONSOLE2 == 2
+#define PSC_BASE2 MPC5XXX_PSC2
+#elif CONFIG_PSC_CONSOLE2 == 3
+#define PSC_BASE2 MPC5XXX_PSC3
+#elif defined(CONFIG_MGT5100)
+#error CONFIG_PSC_CONSOLE2 must be in 1, 2 or 3
+#elif CONFIG_PSC_CONSOLE2 == 4
+#define PSC_BASE2 MPC5XXX_PSC4
+#elif CONFIG_PSC_CONSOLE2 == 5
+#define PSC_BASE2 MPC5XXX_PSC5
+#elif CONFIG_PSC_CONSOLE2 == 6
+#define PSC_BASE2 MPC5XXX_PSC6
+#else
+#error CONFIG_PSC_CONSOLE2 must be in 1 ... 6
+#endif
+#endif /* CONFIG_SERIAL_MULTI */
+
+#if defined(CONFIG_SERIAL_MULTI)
+int serial_init_dev (unsigned long dev_base)
+#else
 int serial_init (void)
+#endif
 {
+#if defined(CONFIG_SERIAL_MULTI)
+       volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
+#else
        volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
+#endif
        unsigned long baseclk;
        int div;
 
@@ -100,13 +139,24 @@ int serial_init (void)
        return (0);
 }
 
-void
-serial_putc(const char c)
+#if defined(CONFIG_SERIAL_MULTI)
+void serial_putc_dev (unsigned long dev_base, const char c)
+#else
+void serial_putc(const char c)
+#endif
 {
+#if defined(CONFIG_SERIAL_MULTI)
+       volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
+#else
        volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
+#endif
 
        if (c == '\n')
+#if defined(CONFIG_SERIAL_MULTI)
+               serial_putc_dev (dev_base, '\r');
+#else
                serial_putc('\r');
+#endif
 
        /* Wait for last character to go. */
        while (!(psc->psc_status & PSC_SR_TXEMP))
@@ -115,18 +165,32 @@ serial_putc(const char c)
        psc->psc_buffer_8 = c;
 }
 
-void
-serial_puts (const char *s)
+#if defined(CONFIG_SERIAL_MULTI)
+void serial_puts_dev (unsigned long dev_base, const char *s)
+#else
+void serial_puts (const char *s)
+#endif
 {
        while (*s) {
+#if defined(CONFIG_SERIAL_MULTI)
+               serial_putc_dev (dev_base, *s++);
+#else
                serial_putc (*s++);
+#endif
        }
 }
 
-int
-serial_getc(void)
+#if defined(CONFIG_SERIAL_MULTI)
+int serial_getc_dev (unsigned long dev_base)
+#else
+int serial_getc(void)
+#endif
 {
+#if defined(CONFIG_SERIAL_MULTI)
+       volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
+#else
        volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
+#endif
 
        /* Wait for a character to arrive. */
        while (!(psc->psc_status & PSC_SR_RXRDY))
@@ -135,18 +199,32 @@ serial_getc(void)
        return psc->psc_buffer_8;
 }
 
-int
-serial_tstc(void)
+#if defined(CONFIG_SERIAL_MULTI)
+int serial_tstc_dev (unsigned long dev_base)
+#else
+int serial_tstc(void)
+#endif
 {
+#if defined(CONFIG_SERIAL_MULTI)
+       volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
+#else
        volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
+#endif
 
        return (psc->psc_status & PSC_SR_RXRDY);
 }
 
-void
-serial_setbrg(void)
+#if defined(CONFIG_SERIAL_MULTI)
+void serial_setbrg_dev (unsigned long dev_base)
+#else
+void serial_setbrg(void)
+#endif
 {
+#if defined(CONFIG_SERIAL_MULTI)
+       volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
+#else
        volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
+#endif
        unsigned long baseclk, div;
 
 #if defined(CONFIG_MGT5100)
@@ -160,4 +238,87 @@ serial_setbrg(void)
        psc->ctur = (div >> 8) & 0xFF;
        psc->ctlr =  div & 0xff;
 }
+
+#if defined(CONFIG_SERIAL_MULTI)
+int serial0_init(void)
+{
+       return (serial_init_dev(PSC_BASE));
+}
+
+int serial1_init(void)
+{
+       return (serial_init_dev(PSC_BASE2));
+}
+void serial0_setbrg (void)
+{
+       serial_setbrg_dev(PSC_BASE);
+}
+void serial1_setbrg (void)
+{
+       serial_setbrg_dev(PSC_BASE2);
+}
+
+void serial0_putc(const char c)
+{
+       serial_putc_dev(PSC_BASE,c);
+}
+
+void serial1_putc(const char c)
+{
+       serial_putc_dev(PSC_BASE2, c);
+}
+void serial0_puts(const char *s)
+{
+       serial_puts_dev(PSC_BASE, s);
+}
+
+void serial1_puts(const char *s)
+{
+       serial_puts_dev(PSC_BASE2, s);
+}
+
+int serial0_getc(void)
+{
+       return(serial_getc_dev(PSC_BASE));
+}
+
+int serial1_getc(void)
+{
+       return(serial_getc_dev(PSC_BASE2));
+}
+int serial0_tstc(void)
+{
+       return (serial_tstc_dev(PSC_BASE));
+}
+
+int serial1_tstc(void)
+{
+       return (serial_tstc_dev(PSC_BASE2));
+}
+
+struct serial_device serial0_device =
+{
+       "serial0",
+       "UART0",
+       serial0_init,
+       serial0_setbrg,
+       serial0_getc,
+       serial0_tstc,
+       serial0_putc,
+       serial0_puts,
+};
+
+struct serial_device serial1_device =
+{
+       "serial1",
+       "UART1",
+       serial1_init,
+       serial1_setbrg,
+       serial1_getc,
+       serial1_tstc,
+       serial1_putc,
+       serial1_puts,
+};
+#endif /* CONFIG_SERIAL_MULTI */
+
 #endif /* CONFIG_PSC_CONSOLE */
index a8d48fc4d99258e58e17a166b365c93fba2f99fd..40f78159f59f40432cf863a5c6912d15a06a89e6 100644 (file)
@@ -52,3 +52,29 @@ PPC4XX Specific
        setenv stdout serial0
        setenv stderr serial0
        setenv stdin serial0
+
+MPC5xxx Specific
+================
+
+Up to two PSCs can be used as console.
+
+Support for hardware handshake has not been implemented yet.
+
+*) The first (default) console port is defined by:
+       #define CONFIG_PSC_CONSOLE <PSC number>
+
+*) The second (alternative) console port is defined by:
+       #define CONFIG_PSC_CONSOLE2 <PSC number>
+
+*) Commands to switch to the second console:
+       setenv stdout serial1
+       setenv stderr serial1
+       setenv stdin serial1
+
+*) Commands to switch to the first console:
+       setenv stdout serial0
+       setenv stderr serial0
+       setenv stdin serial0
+
+*) If a file descriptor is set to "serial" then the
+   current serial device will be used.
index c8abb72e1fddf7b031905df4ec12f0e93ce202d3..8c7b1c26c13ba03684e5dbd214267dcbc7508e3d 100644 (file)
@@ -23,7 +23,7 @@ extern struct serial_device serial_scc_device;
 extern struct serial_device * default_serial_console (void);
 
 #if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440) \
-   || defined(CONFIG_405EP)
+   || defined(CONFIG_405EP) || defined(CONFIG_MPC5xxx)
 extern struct serial_device serial0_device;
 extern struct serial_device serial1_device;
 #endif