[U-Boot-Users] [PATCH] Added support for multiple serial for MPC8XX (resubmit)

Stefano Babic sbabic at denx.de
Wed Jun 6 23:35:16 CEST 2007


The following patch provides support for multiple interface on MPC8xx based 
boards as already provided for other cpus (ppc4xx,MPC5200).

More information in doc/README.serial_multi

In the patch there is also a minor problem solved for the IP860 board 
(CONFIG_IP86x missing), that does not allow u-boot 1.2 to run.

Signed-off-by:	stefano babic <sbabic at denx.de>

diff --git a/board/lwmon/lwmon.c b/board/lwmon/lwmon.c
index 9e8ea2d..096d2e4 100644
--- a/board/lwmon/lwmon.c
+++ b/board/lwmon/lwmon.c
@@ -53,6 +53,9 @@ static void kbd_init (void);
 static int compare_magic (uchar *kbd_data, uchar *str);
 
 
+#define MK_DEV8XX(dev) _MK_DEV8XX(dev)
+#define _MK_DEV8XX(dev) serial_ ## dev ## _device
+
 /*--------------------- Local macros and constants --------------------*/
 #define	_NOT_USED_	0xFFFFFFFF
 
@@ -471,7 +474,7 @@ int board_postclk_init (void)
 
 struct serial_device * default_serial_console (void)
 {
-	return gd->do_mdm_init ? &serial_scc_device : &serial_smc_device;
+	return gd->do_mdm_init ? &MK_DEV8XX(CONFIG_CONS_SCC) : 
&MK_DEV8XX(CONFIG_CONS_SMC);
 }
 
 static void kbd_init (void)
diff --git a/common/serial.c b/common/serial.c
index 13e9f30..6b3a949 100644
--- a/common/serial.c
+++ b/common/serial.c
@@ -33,27 +33,30 @@ static struct serial_device *serial_devi
 static struct serial_device *serial_current = NULL;
 
 #ifndef CONFIG_LWMON
+#define MK_DEV8XX(dev) _MK_DEV8XX(dev)
+#define _MK_DEV8XX(dev) serial_ ## dev ## _device
+
+#define MK_DEV4XX(dev) _MK_DEV4XX(dev)
+#define _MK_DEV4XX(dev) eserial ## dev ## _device
+
 struct serial_device *default_serial_console (void)
 {
-#if defined(CONFIG_8xx_CONS_SMC1) || defined(CONFIG_8xx_CONS_SMC2)
-	return &serial_smc_device;
-#elif defined(CONFIG_8xx_CONS_SCC1) || defined(CONFIG_8xx_CONS_SCC2) \
-   || 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_405EZ) || 
defined(CONFIG_MPC5xxx)
-#if defined(CONFIG_CONS_INDEX) && defined(CFG_NS16550_SERIAL)
-#if (CONFIG_CONS_INDEX==1)
-	return &eserial1_device;
-#elif (CONFIG_CONS_INDEX==2)
-	return &eserial2_device;
-#elif (CONFIG_CONS_INDEX==3)
-	return &eserial3_device;
-#elif (CONFIG_CONS_INDEX==4)
-	return &eserial4_device;
+#if defined(CONFIG_8xx_CONS_SMC1) || defined(CONFIG_8xx_CONS_SMC2) \
+	|| defined(CONFIG_8xx_CONS_SCC1) || defined(CONFIG_8xx_CONS_SCC2) \
+	|| defined(CONFIG_8xx_CONS_SCC3) || defined(CONFIG_8xx_CONS_SCC4)
+
+#if defined CONFIG_CONS_DEV
+	return &MK_DEV8XX(CONFIG_CONS_DEV);
 #else
-#error "Bad CONFIG_CONS_INDEX."
+#error "Bad CONFIG_CONS_DEV."
 #endif
+
+#elif defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440) \
+   || defined(CONFIG_405EP) || defined(CONFIG_405EZ) || 
defined(CONFIG_MPC5xxx)
+
+#if defined(CFG_NS16550_SERIAL) && defined(CONFIG_CONS_INDEX)
+	return &MK_DEV4XX(CONFIG_CONS_INDEX);
+
 #elif defined(CONFIG_UART1_CONSOLE)
 		return &serial1_device;
 #else
@@ -82,12 +85,23 @@ static int serial_register (struct seria
 
 void serial_initialize (void)
 {
-#if defined(CONFIG_8xx_CONS_SMC1) || defined(CONFIG_8xx_CONS_SMC2)
-	serial_register (&serial_smc_device);
+#if defined(CONFIG_8xx_CONS_SMC1)
+	serial_register (&serial_smc1_device);
+#endif
+#if defined(CONFIG_8xx_CONS_SMC2)
+	serial_register (&serial_smc2_device);
+#endif
+#if defined(CONFIG_8xx_CONS_SCC1)
+	serial_register (&serial_scc1_device);
+#endif
+#if defined(CONFIG_8xx_CONS_SCC2)
+	serial_register (&serial_scc2_device);
+#endif
+#if defined(CONFIG_8xx_CONS_SCC3)
+	serial_register (&serial_scc3_device);
 #endif
-#if defined(CONFIG_8xx_CONS_SCC1) || defined(CONFIG_8xx_CONS_SCC2) \
- || defined(CONFIG_8xx_CONS_SCC3) || defined(CONFIG_8xx_CONS_SCC4)
-	serial_register (&serial_scc_device);
+#if defined(CONFIG_8xx_CONS_SCC4)
+	serial_register (&serial_scc4_device);
 #endif
 
 #if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440) \
@@ -227,5 +241,9 @@ void serial_puts (const char *s)
 
 	serial_current->puts (s);
 }
-
+#else 
+void serial_reinit_all (void)
+{
+	serial_init();
+}
 #endif /* CONFIG_SERIAL_MULTI */
diff --git a/cpu/mpc8xx/serial.c b/cpu/mpc8xx/serial.c
index ffc898c..88dca33 100644
--- a/cpu/mpc8xx/serial.c
+++ b/cpu/mpc8xx/serial.c
@@ -31,6 +31,35 @@ DECLARE_GLOBAL_DATA_PTR;
 
 #if !defined(CONFIG_8xx_CONS_NONE)	/* No Console at all */
 
+#define ALIGN(x, a)    (((x) + (a) - 1) & ~((a) - 1))
+
+#ifdef CONFIG_SERIAL_MULTI
+#define SMC1_INDEX	0
+#define SMC2_INDEX	1
+#define SCC1_INDEX	0
+#define SCC2_INDEX	1
+#define SCC3_INDEX	2
+#define SCC4_INDEX	3
+
+struct cpm_parms {
+	unsigned long proff;
+	unsigned long cpm_cr_ch;
+};
+
+struct cpm_parms smc_parms [] = {
+	{PROFF_SMC1,CPM_CR_CH_SMC1},
+	{PROFF_SMC2,CPM_CR_CH_SMC2}
+};
+
+struct cpm_parms scc_parms [] = {
+	{PROFF_SCC1,CPM_CR_CH_SCC1},
+	{PROFF_SCC2,CPM_CR_CH_SCC2},
+	{PROFF_SCC3,CPM_CR_CH_SCC3},
+	{PROFF_SCC4,CPM_CR_CH_SCC4}
+};
+
+#endif /* CONFIG_SERIAL_MULTI */
+
 #if defined(CONFIG_8xx_CONS_SMC1)	/* Console on SMC1 */
 #define	SMC_INDEX	0
 #define PROFF_SMC	PROFF_SMC1
@@ -87,12 +116,25 @@ static void serial_setdivisor(volatile c
 
 #if (defined (CONFIG_8xx_CONS_SMC1) || defined (CONFIG_8xx_CONS_SMC2))
 
+#ifndef CONFIG_SERIAL_MULTI
+#define smc_init	serial_init
+#define	smc_setbrg	serial_setbrg	
+#define	smc_getc	serial_getc	
+#define	smc_tstc	serial_tstc	
+#define	smc_putc	serial_putc
+#define	smc_puts	serial_puts
+#endif
+
 /*
  * Minimal serial functions needed to use one of the SMC ports
  * as serial console interface.
  */
 
-static void smc_setbrg (void)
+#ifdef CONFIG_SERIAL_MULTI
+static void smc_setbrg_dev (unsigned int smc_index)
+#else
+void smc_setbrg (void)
+#endif
 {
 	volatile immap_t *im = (immap_t *)CFG_IMMR;
 	volatile cpm8xx_t *cp = &(im->im_cpm);
@@ -108,7 +150,11 @@ static void smc_setbrg (void)
 	serial_setdivisor(cp);
 }
 
-static int smc_init (void)
+#ifdef CONFIG_SERIAL_MULTI
+static int smc_init_dev (unsigned int smc_index)
+#else
+int smc_init (void)
+#endif
 {
 	volatile immap_t *im = (immap_t *)CFG_IMMR;
 	volatile smc_t *sp;
@@ -122,8 +168,13 @@ static int smc_init (void)
 
 	/* initialize pointers to SMC */
 
+#ifdef CONFIG_SERIAL_MULTI
+	sp = (smc_t *) &(cp->cp_smc[smc_index]);
+	up = (smc_uart_t *) &cp->cp_dparam[smc_parms[smc_index].proff];
+#else
 	sp = (smc_t *) &(cp->cp_smc[SMC_INDEX]);
 	up = (smc_uart_t *) &cp->cp_dparam[PROFF_SMC];
+#endif
 
 	/* Disable transmitter/receiver.
 	*/
@@ -147,35 +198,57 @@ static int smc_init (void)
 	im->im_sdma.sdma_sdmr = 0x00;
 #endif
 
+#ifdef CONFIG_SERIAL_MULTI
+	if (smc_index == SMC1_INDEX) {
+#endif
 #if defined(CONFIG_8xx_CONS_SMC1)
-	/* Use Port B for SMC1 instead of other functions.
-	*/
-	cp->cp_pbpar |=  0x000000c0;
-	cp->cp_pbdir &= ~0x000000c0;
-	cp->cp_pbodr &= ~0x000000c0;
-#else	/* CONFIG_8xx_CONS_SMC2 */
+		/* Use Port B for SMC1 instead of other functions.
+		*/
+		cp->cp_pbpar |=  0x000000c0;
+		cp->cp_pbdir &= ~0x000000c0;
+		cp->cp_pbodr &= ~0x000000c0;
+#endif
+#ifdef CONFIG_SERIAL_MULTI
+	} 
+#endif
+
+#if defined(CONFIG_8xx_CONS_SMC2)
+#ifdef CONFIG_SERIAL_MULTI
+	if (smc_index == SMC2_INDEX) {
+#endif
 # if defined(CONFIG_MPC823) || defined(CONFIG_MPC850)
-	/* Use Port A for SMC2 instead of other functions.
-	*/
-	ip->iop_papar |=  0x00c0;
-	ip->iop_padir &= ~0x00c0;
-	ip->iop_paodr &= ~0x00c0;
+		/* Use Port A for SMC2 instead of other functions.
+		*/
+		ip->iop_papar |=  0x00c0;
+		ip->iop_padir &= ~0x00c0;
+		ip->iop_paodr &= ~0x00c0;
 # else	/* must be a 860 then */
 	/* Use Port B for SMC2 instead of other functions.
 	*/
-	cp->cp_pbpar |=  0x00000c00;
-	cp->cp_pbdir &= ~0x00000c00;
-	cp->cp_pbodr &= ~0x00000c00;
+		cp->cp_pbpar |=  0x00000c00;
+		cp->cp_pbdir &= ~0x00000c00;
+		cp->cp_pbodr &= ~0x00000c00;
 # endif
+#ifdef CONFIG_SERIAL_MULTI
+	} 
+#endif
 #endif
 
 #if defined(CONFIG_FADS) || defined(CONFIG_ADS)
 	/* Enable RS232 */
+#ifdef CONFIG_SERIAL_MULTI
+	if (smc_index == SMC1_INDEX) {
+		*((uint *) BCSR1) &= ~BCSR1_RS232EN_1;
+	} else {
+		*((uint *) BCSR1) &= ~BCSR1_RS232EN_2;
+	}
+#else
 #if defined(CONFIG_8xx_CONS_SMC1)
 	*((uint *) BCSR1) &= ~BCSR1_RS232EN_1;
 #else
 	*((uint *) BCSR1) &= ~BCSR1_RS232EN_2;
 #endif
+#endif  /* CONFIG_SERIAL_MULTI */
 #endif	/* CONFIG_FADS */
 
 #if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC)
@@ -190,8 +263,12 @@ static int smc_init (void)
 #ifdef CFG_ALLOC_DPRAM
 	dpaddr = dpram_alloc_align (sizeof(cbd_t)*2 + 2, 8) ;
 #else
+#ifdef CONFIG_SERIAL_MULTI
+	dpaddr = ALIGN(CPM_SERIAL_BASE+(sizeof(cbd_t)*2+2)*smc_index,8) ;
+#else
 	dpaddr = CPM_SERIAL_BASE ;
 #endif
+#endif
 
 	/* Allocate space for two buffer descriptors in the DP ram.
 	 * For now, this address seems OK, but it may have to
@@ -239,8 +316,12 @@ static int smc_init (void)
 	cp->cp_simode = ((cp->cp_simode & ~0xf000) | 0x7000);
 #else
 	/* Set up the baud rate generator */
+#ifdef CONFIG_SERIAL_MULTI
+	smc_setbrg_dev (smc_index);
+#else
 	smc_setbrg ();
-#endif
+#endif /* CONFIG_SERIAL_MULTI */
+#endif /* CFG_SPC1920_SMC1_CLK4 */
 
 	/* Make the first buffer the only buffer.
 	*/
@@ -258,7 +339,11 @@ static int smc_init (void)
 	while (cp->cp_cpcr & CPM_CR_FLG)  /* wait if cp is busy */
 	  ;
 
+#ifdef CONFIG_SERIAL_MULTI
+	cp->cp_cpcr = mk_cr_cmd(smc_parms[smc_index].cpm_cr_ch, CPM_CR_INIT_TRX) | 
CPM_CR_FLG;
+#else
 	cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC, CPM_CR_INIT_TRX) | CPM_CR_FLG;
+#endif /* CONFIG_SERIAL_MULTI */
 
 	while (cp->cp_cpcr & CPM_CR_FLG)  /* wait if cp is busy */
 	  ;
@@ -270,8 +355,13 @@ static int smc_init (void)
 	return (0);
 }
 
+#ifdef CONFIG_SERIAL_MULTI
 static void
+smc_putc_dev(unsigned int smc_index,const char c)
+#else
+void
 smc_putc(const char c)
+#endif
 {
 	volatile cbd_t		*tbdf;
 	volatile char		*buf;
@@ -284,10 +374,15 @@ smc_putc(const char c)
 		return;
 #endif
 
+#ifdef CONFIG_SERIAL_MULTI
+	if (c == '\n')
+		smc_putc_dev (smc_index,'\r');
+	up = (smc_uart_t *)&cpmp->cp_dparam[smc_parms[smc_index].proff];
+#else
 	if (c == '\n')
 		smc_putc ('\r');
-
 	up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_SMC];
+#endif
 
 	tbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_tbase];
 
@@ -307,16 +402,30 @@ smc_putc(const char c)
 	}
 }
 
+#ifdef CONFIG_SERIAL_MULTI
 static void
+smc_puts_dev (unsigned int smc_index,const char *s)
+#else
+void
 smc_puts (const char *s)
+#endif
 {
 	while (*s) {
+#ifdef CONFIG_SERIAL_MULTI
+		smc_putc_dev (smc_index,*s++);
+#else
 		smc_putc (*s++);
+#endif
 	}
 }
 
+#ifdef CONFIG_SERIAL_MULTI
 static int
+smc_getc_dev(unsigned int smc_index)
+#else
+int
 smc_getc(void)
+#endif
 {
 	volatile cbd_t		*rbdf;
 	volatile unsigned char	*buf;
@@ -325,7 +434,11 @@ smc_getc(void)
 	volatile cpm8xx_t	*cpmp = &(im->im_cpm);
 	unsigned char		c;
 
+#ifdef CONFIG_SERIAL_MULTI
+	up = (smc_uart_t *)&cpmp->cp_dparam[smc_parms[smc_index].proff];
+#else
 	up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_SMC];
+#endif
 
 	rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase];
 
@@ -342,21 +455,119 @@ smc_getc(void)
 	return(c);
 }
 
+#ifdef CONFIG_SERIAL_MULTI
 static int
+smc_tstc_dev(unsigned int smc_index)
+#else
+int
 smc_tstc(void)
+#endif
 {
 	volatile cbd_t		*rbdf;
 	volatile smc_uart_t	*up;
 	volatile immap_t	*im = (immap_t *)CFG_IMMR;
 	volatile cpm8xx_t	*cpmp = &(im->im_cpm);
 
+#ifdef CONFIG_SERIAL_MULTI
+	up = (smc_uart_t *)&cpmp->cp_dparam[smc_parms[smc_index].proff];
+#else
 	up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_SMC];
+#endif
 
 	rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase];
 
 	return(!(rbdf->cbd_sc & BD_SC_EMPTY));
 }
 
+#ifdef CONFIG_SERIAL_MULTI
+int smc1_init(void)
+{
+	return smc_init_dev(SMC1_INDEX);
+}
+
+int smc2_init(void)
+{
+	return smc_init_dev(SMC2_INDEX);
+}
+
+void smc1_setbrg(void)
+{
+	return smc_setbrg_dev(SMC1_INDEX);
+}
+
+
+void smc2_setbrg(void)
+{
+	return smc_setbrg_dev(SMC2_INDEX);
+}
+
+void smc1_putc(const char c)
+{
+	return smc_putc_dev(SMC1_INDEX,c);
+}
+
+void smc2_putc(const char c)
+{
+	return smc_putc_dev(SMC2_INDEX,c);
+}
+
+void smc1_puts(const char *s)
+{
+	return smc_puts_dev(SMC1_INDEX,s);
+}
+
+void smc2_puts(const char *s)
+{
+	return smc_puts_dev(SMC2_INDEX,s);
+}
+
+int smc1_getc(void)
+{
+	return smc_getc_dev(SMC1_INDEX);
+}
+
+int smc2_getc(void)
+{
+	return smc_getc_dev(SMC2_INDEX);
+}
+
+int smc1_tstc(void)
+{
+	return smc_tstc_dev(SMC1_INDEX);
+}
+
+int smc2_tstc(void)
+{
+	return smc_tstc_dev(SMC2_INDEX);
+}
+
+struct serial_device serial_smc1_device =
+{
+	"serial_smc1",
+	"SMC",
+	smc1_init,
+	smc1_setbrg,
+	smc1_getc,
+	smc1_tstc,
+	smc1_putc,
+	smc1_puts,
+};
+
+struct serial_device serial_smc2_device =
+{
+	"serial_smc2",
+	"SMC",
+	smc2_init,
+	smc2_setbrg,
+	smc2_getc,
+	smc2_tstc,
+	smc2_putc,
+	smc2_puts,
+};
+
+
+#else
+
 struct serial_device serial_smc_device =
 {
 	"serial_smc",
@@ -369,13 +580,29 @@ struct serial_device serial_smc_device =
 	smc_puts,
 };
 
+#endif /* CONFIG_SERIAL_MULTI */
+
 #endif /* CONFIG_8xx_CONS_SMC1 || CONFIG_8xx_CONS_SMC2 */
 
 #if defined(CONFIG_8xx_CONS_SCC1) || defined(CONFIG_8xx_CONS_SCC2) || \
     defined(CONFIG_8xx_CONS_SCC3) || defined(CONFIG_8xx_CONS_SCC4)
 
+#ifndef CONFIG_SERIAL_MULTI
+#define scc_init	serial_init
+#define	scc_setbrg	serial_setbrg
+#define	scc_getc	serial_getc
+#define	scc_tstc	serial_tstc
+#define scc_putc	serial_putc
+#define	scc_puts	serial_puts
+#endif
+
+
+#ifdef CONFIG_SERIAL_MULTI
 static void
-scc_setbrg (void)
+scc_setbrg_dev (unsigned int scc_index)
+#else
+void scc_setbrg (void)
+#endif
 {
 	volatile immap_t *im = (immap_t *)CFG_IMMR;
 	volatile cpm8xx_t *cp = &(im->im_cpm);
@@ -386,12 +613,28 @@ scc_setbrg (void)
 	 * Wire BRG1 to SCCx
 	 */
 
+#ifdef CONFIG_SERIAL_MULTI
+	cp->cp_sicr &= ~(0x000000FF << (8 * scc_index));
+#else
 	cp->cp_sicr &= ~(0x000000FF << (8 * SCC_INDEX));
-
+#endif
 	serial_setdivisor(cp);
 }
 
-static int scc_init (void)
+#define SETPORTASCC(ip,scc) do { \
+	ip->iop_papar |=  ((3 << (2 * scc))); \
+	ip->iop_padir &= ~((3 << (2 * scc))); \
+	ip->iop_paodr &= ~((3 << (2 * scc))); \
+	} while (0);
+	
+
+#ifdef CONFIG_SERIAL_MULTI
+static int
+scc_init_dev (unsigned int scc_index)
+#else
+int
+scc_init (void)
+#endif
 {
 	volatile immap_t *im = (immap_t *)CFG_IMMR;
 	volatile scc_t *sp;
@@ -399,14 +642,20 @@ static int scc_init (void)
 	volatile cbd_t *tbdf, *rbdf;
 	volatile cpm8xx_t *cp = &(im->im_cpm);
 	uint	 dpaddr;
+
 #if (SCC_INDEX != 2) || !defined(CONFIG_MPC850)
 	volatile iop8xx_t *ip = (iop8xx_t *)&(im->im_ioport);
 #endif
 
 	/* initialize pointers to SCC */
 
+#ifdef CONFIG_SERIAL_MULTI
+	sp = (scc_t *) &(cp->cp_scc[scc_index]);
+	up = (scc_uart_t *) &cp->cp_dparam[scc_parms[scc_index].proff];
+#else
 	sp = (scc_t *) &(cp->cp_scc[SCC_INDEX]);
 	up = (scc_uart_t *) &cp->cp_dparam[PROFF_SCC];
+#endif
 
 #if defined(CONFIG_LWMON) && defined(CONFIG_8xx_CONS_SCC2)
     {	/* Disable Ethernet, enable Serial */
@@ -428,6 +677,33 @@ static int scc_init (void)
 	*/
 	sp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
 
+#ifdef CONFIG_SERIAL_MULTI
+#if defined(CONFIG_MPC850) 
+	/*
+	 * The MPC850 has SCC3 on Port B
+	 */
+	if (scc_index == 2) {
+		cp->cp_pbpar |=  0x06;
+		cp->cp_pbdir &= ~0x06;
+		cp->cp_pbodr &= ~0x06;
+	} else
+		SETPORTASCC(ip,scc_index);
+
+#elif defined(CONFIG_IP860)
+	/*
+	 * The IP860 has SCC3 and SCC4 on Port D
+	 */
+	if (scc_index > 1) { 
+		ip->iop_pdpar |=  ((3 << (2 * scc_index)));
+	} else 
+		SETPORTASCC(ip,scc_index);
+#else
+	SETPORTASCC(ip,scc_index);
+
+#endif
+
+#else
+
 #if (SCC_INDEX == 2) && defined(CONFIG_MPC850)
 	/*
 	 * The MPC850 has SCC3 on Port B
@@ -449,6 +725,7 @@ static int scc_init (void)
 	 */
 	ip->iop_pdpar |=  ((3 << (2 * SCC_INDEX)));
 #endif
+#endif /* CONFIG_SERIAL_MULTI */
 
 	/* Allocate space for two buffer descriptors in the DP ram.
 	 */
@@ -456,8 +733,12 @@ static int scc_init (void)
 #ifdef CFG_ALLOC_DPRAM
 	dpaddr = dpram_alloc_align (sizeof(cbd_t)*2 + 2, 8) ;
 #else
+#ifdef CONFIG_SERIAL_MULTI
+	dpaddr = ALIGN(CPM_SERIAL2_BASE+(sizeof(cbd_t)*2+2)*scc_index,8) ;
+#else
 	dpaddr = CPM_SERIAL2_BASE ;
 #endif
+#endif
 
 	/* Enable SDMA.
 	*/
@@ -476,7 +757,11 @@ static int scc_init (void)
 
 	/* Set up the baud rate generator.
 	*/
+#ifdef CONFIG_SERIAL_MULTI
+	scc_setbrg_dev (scc_index);
+#else
 	scc_setbrg ();
+#endif
 
 	/* Set up the uart parameters in the parameter ram.
 	*/
@@ -553,8 +838,13 @@ static int scc_init (void)
 	return (0);
 }
 
+#ifdef CONFIG_SERIAL_MULTI
 static void
+scc_putc_dev(unsigned int scc_index,const char c)
+#else
+void
 scc_putc(const char c)
+#endif
 {
 	volatile cbd_t		*tbdf;
 	volatile char		*buf;
@@ -567,10 +857,15 @@ scc_putc(const char c)
 		return;
 #endif
 
+#ifdef CONFIG_SERIAL_MULTI
+	if (c == '\n')
+		scc_putc_dev (scc_index,'\r');
+	up = (scc_uart_t *)&cpmp->cp_dparam[scc_parms[scc_index].proff];
+#else
 	if (c == '\n')
 		scc_putc ('\r');
-
 	up = (scc_uart_t *)&cpmp->cp_dparam[PROFF_SCC];
+#endif
 
 	tbdf = (cbd_t *)&cpmp->cp_dpmem[up->scc_genscc.scc_tbase];
 
@@ -590,16 +885,30 @@ scc_putc(const char c)
 	}
 }
 
+#ifdef CONFIG_SERIAL_MULTI
 static void
+scc_puts_dev (unsigned int scc_index,const char *s)
+#else
+void
 scc_puts (const char *s)
+#endif
 {
 	while (*s) {
+#ifdef CONFIG_SERIAL_MULTI
+		scc_putc_dev (scc_index,*s++);
+#else
 		scc_putc (*s++);
+#endif
 	}
 }
 
+#ifdef CONFIG_SERIAL_MULTI
 static int
+scc_getc_dev(unsigned int scc_index)
+#else
+int
 scc_getc(void)
+#endif
 {
 	volatile cbd_t		*rbdf;
 	volatile unsigned char	*buf;
@@ -608,7 +917,11 @@ scc_getc(void)
 	volatile cpm8xx_t	*cpmp = &(im->im_cpm);
 	unsigned char		c;
 
+#ifdef CONFIG_SERIAL_MULTI
+	up = (scc_uart_t *)&cpmp->cp_dparam[scc_parms[scc_index].proff];
+#else
 	up = (scc_uart_t *)&cpmp->cp_dparam[PROFF_SCC];
+#endif
 
 	rbdf = (cbd_t *)&cpmp->cp_dpmem[up->scc_genscc.scc_rbase];
 
@@ -625,21 +938,209 @@ scc_getc(void)
 	return(c);
 }
 
+#ifdef CONFIG_SERIAL_MULTI
 static int
+scc_tstc_dev(unsigned int scc_index)
+#else
+int
 scc_tstc(void)
+#endif
 {
 	volatile cbd_t		*rbdf;
 	volatile scc_uart_t	*up;
 	volatile immap_t	*im = (immap_t *)CFG_IMMR;
 	volatile cpm8xx_t	*cpmp = &(im->im_cpm);
 
+#ifdef CONFIG_SERIAL_MULTI
+	up = (scc_uart_t *)&cpmp->cp_dparam[scc_parms[scc_index].proff];
+#else
 	up = (scc_uart_t *)&cpmp->cp_dparam[PROFF_SCC];
+#endif
 
 	rbdf = (cbd_t *)&cpmp->cp_dpmem[up->scc_genscc.scc_rbase];
 
 	return(!(rbdf->cbd_sc & BD_SC_EMPTY));
 }
 
+#ifdef CONFIG_SERIAL_MULTI
+int scc1_init(void)
+{
+	return scc_init_dev(SCC1_INDEX);
+}
+
+int scc2_init(void)
+{
+	return scc_init_dev(SCC2_INDEX);
+}
+
+int scc3_init(void)
+{
+	return scc_init_dev(SCC3_INDEX);
+}
+
+int scc4_init(void)
+{
+	return scc_init_dev(SCC4_INDEX);
+}
+
+
+void scc1_setbrg(void)
+{
+	return scc_setbrg_dev(SCC1_INDEX);
+}
+
+void scc2_setbrg(void)
+{
+	return scc_setbrg_dev(SCC2_INDEX);
+}
+
+void scc3_setbrg(void)
+{
+	return scc_setbrg_dev(SCC3_INDEX);
+}
+
+void scc4_setbrg(void)
+{
+	return scc_setbrg_dev(SCC4_INDEX);
+}
+
+
+void scc1_putc(const char c)
+{
+	return scc_putc_dev(SCC1_INDEX,c);
+}
+
+void scc2_putc(const char c)
+{
+	return scc_putc_dev(SCC2_INDEX,c);
+}
+
+void scc3_putc(const char c)
+{
+	return scc_putc_dev(SCC3_INDEX,c);
+}
+
+void scc4_putc(const char c)
+{
+	return scc_putc_dev(SCC4_INDEX,c);
+}
+
+
+void scc1_puts(const char *s)
+{
+	return scc_puts_dev(SCC1_INDEX,s);
+}
+
+void scc2_puts(const char *s)
+{
+	return scc_puts_dev(SCC2_INDEX,s);
+}
+
+void scc3_puts(const char *s)
+{
+	return scc_puts_dev(SCC3_INDEX,s);
+}
+
+void scc4_puts(const char *s)
+{
+	return scc_puts_dev(SCC4_INDEX,s);
+}
+
+
+int scc1_getc(void)
+{
+	return scc_getc_dev(SCC1_INDEX);
+}
+
+int scc2_getc(void)
+{
+	return scc_getc_dev(SCC2_INDEX);
+}
+
+int scc3_getc(void)
+{
+	return scc_getc_dev(SCC3_INDEX);
+}
+
+int scc4_getc(void)
+{
+	return scc_getc_dev(SCC4_INDEX);
+}
+
+
+int scc1_tstc(void)
+{
+	return scc_tstc_dev(SCC1_INDEX);
+}
+
+int scc2_tstc(void)
+{
+	return scc_tstc_dev(SCC2_INDEX);
+}
+
+int scc3_tstc(void)
+{
+	return scc_tstc_dev(SCC3_INDEX);
+}
+
+int scc4_tstc(void)
+{
+	return scc_tstc_dev(SCC4_INDEX);
+}
+
+
+struct serial_device serial_scc1_device =
+{
+	"serial_scc1",
+	"SCC",
+	scc1_init,
+	scc1_setbrg,
+	scc1_getc,
+	scc1_tstc,
+	scc1_putc,
+	scc1_puts,
+};
+
+struct serial_device serial_scc2_device =
+{
+	"serial_scc2",
+	"SCC",
+	scc2_init,
+	scc2_setbrg,
+	scc2_getc,
+	scc2_tstc,
+	scc2_putc,
+	scc2_puts,
+};
+
+struct serial_device serial_scc3_device =
+{
+	"serial_scc3",
+	"SCC",
+	scc3_init,
+	scc3_setbrg,
+	scc3_getc,
+	scc3_tstc,
+	scc3_putc,
+	scc3_puts,
+};
+
+struct serial_device serial_scc4_device =
+{
+	"serial_scc4",
+	"SCC",
+	scc4_init,
+	scc4_setbrg,
+	scc4_getc,
+	scc4_tstc,
+	scc4_putc,
+	scc4_puts,
+};
+
+
+#else
+
+
 struct serial_device serial_scc_device =
 {
 	"serial_scc",
@@ -651,6 +1152,7 @@ struct serial_device serial_scc_device =
 	scc_putc,
 	scc_puts,
 };
+#endif /* CONFIG_SERIAL_MULTI */
 
 #endif	/* CONFIG_8xx_CONS_SCCx */
 
@@ -681,7 +1183,7 @@ kgdb_serial_init(void)
 		i = 2;
 #endif
 	}
-	else if (strcmp(default_serial_console()->ctlr, "SMC") == 0)
+	else if (strcmp(default_serial_console()->ctlr, "SCC") == 0)
 	{
 #if defined(CONFIG_8xx_CONS_SCC1)
 		i = 1;
diff --git a/doc/README.serial_multi b/doc/README.serial_multi
index 40f7815..fe8015d 100644
--- a/doc/README.serial_multi
+++ b/doc/README.serial_multi
@@ -10,21 +10,34 @@ At the moment, the ports must be split o
 Support for hardware handshake has not been implemented yet (but is
 in the works).
 
-*) The default console depends on the keys pressed:
-	- SMC if keys not pressed (modem not enabled)
-	- SCC if keys pressed (modem enabled)
+*) The default console is defined by
+	#define CONFIG_CONS_DEV	<device>,
 
-*) The console can be switched to SCC by any of the following commands:
+	where device is any of smc1, smc2, scc1, scc2, scc3, scc4.
 
-	setenv stdout serial_scc
-	setenv stdin serial_scc
-	setenv stderr serial_scc
+	The devices must be configured by:
+	#define CONFIG_8xx_CONS_SMCx
+		or/and
+	#define CONFIG_8xx_CONS_SCCx
 
-*) The console can be switched to SMC by any of the following commands:
+	where x=1-2 for SMC, 1-4 for SCC.
 
-	setenv stdout serial_smc
-	setenv stdin serial_smc
-	setenv stderr serial_smc
+	Up to 6 serial  interfaces are supported (2 SMCs, 4 SCCs). However,
+	please note that some devices on some CPUs share the same pins
+	and cannot be activated at the same time.
+	
+*) The console can be switched by any of the following commands:
+
+	setenv stdout serial_<device>
+	setenv stdin serial_<device>
+	setenv stderr serial_<device>
+
+	where <device> is one of the registered devices.
+
+	The list of the registered devices is printed by the coninfo command.
+
+	Example: to switch from smc1 to scc3
+	setenv stdout serial_scc3
 
 *) If a file descriptor is set to "serial" then the current serial device
 will be used which, in turn, can be switched by above commands.
@@ -32,7 +45,7 @@ will be used which, in turn, can be swit
 *) The baudrate is the same for all serial devices. But it can be switched
 just after switching the console:
 
-	setenv sout serial_scc; setenv baudrate 38400
+	setenv stdout serial_scc; setenv baudrate 38400
 
 After that press 'enter' at the SCC console. Note that baudrates <38400
 are not allowed on LWMON with watchdog enabled (see CFG_BAUDRATE_TABLE in
diff --git a/include/common.h b/include/common.h
index 3c4b37b..b97c952 100644
--- a/include/common.h
+++ b/include/common.h
@@ -145,18 +145,6 @@ typedef void (interrupt_handler_t)(void
 # endif
 #endif
 
-#ifndef CONFIG_SERIAL_MULTI
-
-#if defined(CONFIG_8xx_CONS_SMC1) || defined(CONFIG_8xx_CONS_SMC2) \
- || defined(CONFIG_8xx_CONS_SCC1) || defined(CONFIG_8xx_CONS_SCC2) \
- || defined(CONFIG_8xx_CONS_SCC3) || defined(CONFIG_8xx_CONS_SCC4)
-
-#define CONFIG_SERIAL_MULTI	1
-
-#endif
-
-#endif /* CONFIG_SERIAL_MULTI */
-
 /*
  * General Purpose Utilities
  */
diff --git a/include/commproc.h b/include/commproc.h
index 12400e3..93675c6 100644
--- a/include/commproc.h
+++ b/include/commproc.h
@@ -74,10 +74,10 @@
 #define CPM_I2C_BASE		0x0820
 #define CPM_SPI_BASE		0x0840
 #define CPM_FEC_BASE		0x0860
-#define CPM_SERIAL2_BASE	0x08E0
 #define CPM_SCC_BASE		0x0900
 #define CPM_POST_BASE		0x0980
 #define CPM_WLKBD_BASE		0x0a00
+#define CPM_SERIAL2_BASE	0x0a10
 
 #endif
 
diff --git a/include/configs/IP860.h b/include/configs/IP860.h
index 0e20e56..3692acb 100644
--- a/include/configs/IP860.h
+++ b/include/configs/IP860.h
@@ -35,10 +35,18 @@
 
 #define CONFIG_MPC860		1	/* This is a MPC860 CPU		*/
 #define CONFIG_IP860		1	/* ...on a IP860 board		*/
+#define CONFIG_IP86x		1
 #define CONFIG_BOARD_EARLY_INIT_F 1	/* Call board_early_init_f	*/
 
-#define	CONFIG_8xx_CONS_SMC1	1	/* Console is on SMC1		*/
-#define CONFIG_BAUDRATE		9600
+
+#define CONFIG_SERIAL_MULTI
+#define	CONFIG_8xx_CONS_SMC1	1	/* First Console is on SMC1	*/
+#define CONFIG_8xx_CONS_SCC2	2
+#define CONFIG_CONS_DEV		smc1
+
+#define CFG_ALLOC_DPRAM
+
+#define CONFIG_BAUDRATE		115200
 #define CONFIG_BOOTDELAY	5	/* autoboot after 5 seconds	*/
 
 #define CONFIG_PREBOOT	"echo;echo Type \"run flash_nfs\" to mount root 
filesystem over NFS;echo" \
diff --git a/include/configs/TQM860L.h b/include/configs/TQM860L.h
index 9be5db1..8b882aa 100644
--- a/include/configs/TQM860L.h
+++ b/include/configs/TQM860L.h
@@ -36,9 +36,11 @@
 #define CONFIG_MPC860		1	/* This is a MPC860 CPU		*/
 #define CONFIG_TQM860L		1	/* ...on a TQM8xxL module	*/
 
+#define CONFIG_SERIAL_MULTI
 #define	CONFIG_8xx_CONS_SMC1	1	/* Console is on SMC1		*/
-#undef	CONFIG_8xx_CONS_SMC2
+#define	CONFIG_8xx_CONS_SMC2	2	/* Console is on SMC2		*/
 #undef	CONFIG_8xx_CONS_NONE
+#define CONFIG_CONS_DEV		smc1
 
 #define CONFIG_BAUDRATE		115200	/* console baudrate = 115kbps	*/
 
@@ -97,6 +99,7 @@
 				CFG_CMD_ELF	| \
 				CFG_CMD_IDE	| \
 				CFG_CMD_NFS	| \
+				CFG_CMD_IMMAP	| \
 				CFG_CMD_SNTP	)
 
 #define CONFIG_NETCONSOLE
@@ -152,6 +155,7 @@
 #define	CFG_GBL_DATA_SIZE	64  /* size in bytes reserved for initial data */
 #define CFG_GBL_DATA_OFFSET	(CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
 #define	CFG_INIT_SP_OFFSET	CFG_GBL_DATA_OFFSET
+#define CFG_ALLOC_DPRAM
 
 /*-----------------------------------------------------------------------
  * Start addresses for the final memory configuration
diff --git a/include/configs/lwmon.h b/include/configs/lwmon.h
index 9b4c004..d2dea14 100644
--- a/include/configs/lwmon.h
+++ b/include/configs/lwmon.h
@@ -60,6 +60,8 @@
 #define CONFIG_SERIAL_MULTI	1
 #define CONFIG_8xx_CONS_SMC2	1	/* Console is on SMC2		*/
 #define CONFIG_8xx_CONS_SCC2	1	/* Console is on SCC2		*/
+#define CONFIG_CONS_SMC		smc2
+#define CONFIG_CONS_SCC		scc2
 
 #define CONFIG_BAUDRATE		115200	/* with watchdog >= 38400 needed */
 
diff --git a/include/serial.h b/include/serial.h
index f7412fd..a4df4b0 100644
--- a/include/serial.h
+++ b/include/serial.h
@@ -19,7 +19,13 @@ struct serial_device {
 };
 
 extern struct serial_device serial_smc_device;
+extern struct serial_device serial_smc1_device;
+extern struct serial_device serial_smc2_device;
 extern struct serial_device serial_scc_device;
+extern struct serial_device serial_scc1_device;
+extern struct serial_device serial_scc2_device;
+extern struct serial_device serial_scc3_device;
+extern struct serial_device serial_scc4_device;
 extern struct serial_device * default_serial_console (void);
 
 #if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440) \


-- 
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80  Email: office at denx.de
=====================================================================




More information about the U-Boot mailing list