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

Stefano Babic sbabic at denx.de
Tue Jun 5 14:47:34 CEST 2007


The following patch allows to have more than one serial interface on the 
MPC8xx based boards and to switch among them.
It is possible to switch any of SMC1/2 or SCC1-4.

This feature was already available for ppc4xx boards.

To switch the console, it is enough to set:

	setenv stdout <serial_device>

,where serial_device is one of the devices reported by the "coninfo" command .

To enable this feature,it is required to set in your board config file the 
switch CONFIG_SERIAL_MULTI and then all required serial interfaces you need 
(CONFIG_8xx_CONS_SMCx,CONFIG_8xx_CONS_SCCx). 

The default console is set via the CONFIG_CONS_INDEX switch. Its range is 1-6 
(SMC1...SCC4).


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.


diff --git a/common/serial.c b/common/serial.c
index 13e9f30..44ab4cc 100644
--- a/common/serial.c
+++ b/common/serial.c
@@ -36,10 +36,30 @@ static struct serial_device *serial_curr
 struct serial_device *default_serial_console (void)
 {
 #if defined(CONFIG_8xx_CONS_SMC1) || defined(CONFIG_8xx_CONS_SMC2)
-	return &serial_smc_device;
+#if (CONFIG_CONS_INDEX==2)
+	return &serial_smc2_device;
+#else
+	return &serial_smc1_device;
+#endif
 #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;
+#if defined(CONFIG_CONS_INDEX)
+#if (CONFIG_CONS_INDEX==3)
+	return &serial_scc1_device;
+#endif
+#if (CONFIG_CONS_INDEX==4)
+	return &serial_scc2_device;
+#endif
+#if (CONFIG_CONS_INDEX==5)
+	return &serial_scc3_device;
+#endif
+#if (CONFIG_CONS_INDEX==6)
+	return &serial_scc4_device;
+#endif
+#else
+#error "Bad CONFIG_CONS_INDEX."
+#endif
+
 #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)
@@ -82,12 +102,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) \
diff --git a/cpu/mpc8xx/serial.c b/cpu/mpc8xx/serial.c
index ffc898c..269fd44 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
@@ -92,7 +121,11 @@ static void serial_setdivisor(volatile c
  * as serial console interface.
  */
 
+#ifdef CONFIG_SERIAL_MULTI
+static void smc_setbrg_dev (unsigned int smc_index)
+#else
 static void smc_setbrg (void)
+#endif
 {
 	volatile immap_t *im = (immap_t *)CFG_IMMR;
 	volatile cpm8xx_t *cp = &(im->im_cpm);
@@ -108,7 +141,11 @@ static void smc_setbrg (void)
 	serial_setdivisor(cp);
 }
 
+#ifdef CONFIG_SERIAL_MULTI
+static int smc_init_dev (unsigned int smc_index)
+#else
 static int smc_init (void)
+#endif
 {
 	volatile immap_t *im = (immap_t *)CFG_IMMR;
 	volatile smc_t *sp;
@@ -122,8 +159,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 +189,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 +254,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 +307,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 +330,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 */
 	  ;
@@ -271,7 +347,11 @@ static int smc_init (void)
 }
 
 static void
+#ifdef CONFIG_SERIAL_MULTI
+smc_putc_dev(unsigned int smc_index,const char c)
+#else
 smc_putc(const char c)
+#endif
 {
 	volatile cbd_t		*tbdf;
 	volatile char		*buf;
@@ -284,10 +364,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];
 
@@ -308,15 +393,27 @@ smc_putc(const char c)
 }
 
 static void
+#ifdef CONFIG_SERIAL_MULTI
+smc_puts_dev (unsigned int smc_index,const char *s)
+#else
 smc_puts (const char *s)
+#endif
 {
 	while (*s) {
+#ifdef CONFIG_SERIAL_MULTI
+		smc_putc_dev (smc_index,*s++);
+#else
 		smc_putc (*s++);
+#endif
 	}
 }
 
 static int
+#ifdef CONFIG_SERIAL_MULTI
+smc_getc_dev(unsigned int smc_index)
+#else
 smc_getc(void)
+#endif
 {
 	volatile cbd_t		*rbdf;
 	volatile unsigned char	*buf;
@@ -325,7 +422,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];
 
@@ -343,20 +444,117 @@ smc_getc(void)
 }
 
 static int
+#ifdef CONFIG_SERIAL_MULTI
+smc_tstc_dev(unsigned int smc_index)
+#else
 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 +567,19 @@ 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)
 
 static void
+#ifdef CONFIG_SERIAL_MULTI
+scc_setbrg_dev (unsigned int scc_index)
+#else
 scc_setbrg (void)
+#endif
 {
 	volatile immap_t *im = (immap_t *)CFG_IMMR;
 	volatile cpm8xx_t *cp = &(im->im_cpm);
@@ -386,12 +590,27 @@ 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);
+	
+
+static int
+#ifdef CONFIG_SERIAL_MULTI
+scc_init_dev (unsigned int scc_index)
+#else
+scc_init (void)
+#endif
 {
 	volatile immap_t *im = (immap_t *)CFG_IMMR;
 	volatile scc_t *sp;
@@ -399,14 +618,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 +653,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 +701,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 +709,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 +733,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.
 	*/
@@ -554,7 +815,11 @@ static int scc_init (void)
 }
 
 static void
+#ifdef CONFIG_SERIAL_MULTI
+scc_putc_dev(unsigned int scc_index,const char c)
+#else
 scc_putc(const char c)
+#endif
 {
 	volatile cbd_t		*tbdf;
 	volatile char		*buf;
@@ -567,10 +832,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];
 
@@ -591,15 +861,27 @@ scc_putc(const char c)
 }
 
 static void
+#ifdef CONFIG_SERIAL_MULTI
+scc_puts_dev (unsigned int scc_index,const char *s)
+#else
 scc_puts (const char *s)
+#endif
 {
 	while (*s) {
+#ifdef CONFIG_SERIAL_MULTI
+		scc_putc_dev (scc_index,*s++);
+#else
 		scc_putc (*s++);
+#endif
 	}
 }
 
 static int
+#ifdef CONFIG_SERIAL_MULTI
+scc_getc_dev(unsigned int scc_index)
+#else
 scc_getc(void)
+#endif
 {
 	volatile cbd_t		*rbdf;
 	volatile unsigned char	*buf;
@@ -608,7 +890,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];
 
@@ -626,20 +912,207 @@ scc_getc(void)
 }
 
 static int
+#ifdef CONFIG_SERIAL_MULTI
+scc_tstc_dev(unsigned int scc_index)
+#else
 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 +1124,7 @@ struct serial_device serial_scc_device =
 	scc_putc,
 	scc_puts,
 };
+#endif /* CONFIG_SERIAL_MULTI */
 
 #endif	/* CONFIG_8xx_CONS_SCCx */
 
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..9084a45 100644
--- a/include/configs/IP860.h
+++ b/include/configs/IP860.h
@@ -35,10 +35,17 @@
 
 #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_INDEX	1
+#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..4912ad0 100644
--- a/include/configs/TQM860L.h
+++ b/include/configs/TQM860L.h
@@ -36,8 +36,10 @@
 #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_SMC2 */
 #undef	CONFIG_8xx_CONS_NONE
 
 #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/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