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

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) \

Hi Stefano,
in message 200706051447.35025.sbabic@denx.de you wrote:
First, your SIgned-off-by: line is missing.
Second:
#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
I really dislike this mess of #ifdef's
Maybe we can use something more readable like
#define CONFIG_CONS_DEV smc1 or #define CONFIG_CONS_DEV scc3
in the board config file, and then add a little CPP trickery like that to common/serial.c:
#define MK_DEV(dev) _MK_DEV(dev) #define _MK_DEV(dev) serial_ ## dev ## _device
Then we can replace this whole block of unreadble code by something like
return MK_DEV(CONFIG_CONS_DEV);
What do you think?
Best regards,
Wolfgang Denk

On Tuesday 05 June 2007 15:53, Wolfgang Denk wrote:
Hi Stefano,
in message 200706051447.35025.sbabic@denx.de you wrote:
First, your SIgned-off-by: line is missing.
Sorry, I will add it.
I really dislike this mess of #ifdef's
I agree with you and I inserted this code against my will :)
However, I didn't want to have two different coding styles with different meaning inside the same file. In fact, some lines later the whole mess of #ifdef was already inserted for the ppc4xx architecture using CONFIG_CONS_INDEX to switch among the interfaces.
I didn't want to change this part because this would break all ppc4xx boards that are not part of the U-Boot tree. So I preferred to add a lot of #ifdef using the same CONFIG defines as in ppc4xx instead of creating a new one.
However, you are right and if we add in future this feature for additional CPUs the code will become absolutely unreadable.
I will resend the patch with the modifications for the mpc8xx, without touching ppc4xx part. This would not break any custom board.
Regards, stefano

Dear Stefano,
in message 200706052139.16320.sbabic@denx.de you wrote:
I really dislike this mess of #ifdef's
I agree with you and I inserted this code against my will :)
;-)
However, I didn't want to have two different coding styles with different meaning inside the same file. In fact, some lines later the whole mess of #ifdef was already inserted for the ppc4xx architecture using CONFIG_CONS_INDEX to switch among the interfaces.
Please feel free to clean this up the same was as I suggested. I'm sure Stefan Roese will ACK such a change.
We should get rid of all this CONFIG_CONS_INDEX stuff.
I didn't want to change this part because this would break all ppc4xx boards that are not part of the U-Boot tree. So I preferred to add a lot of #ifdef using the same CONFIG defines as in ppc4xx instead of creating a new one.
I'm afraid I don't understand what you mean. Usually we don't care about boards that are not part of the U-Boot tree.
I will resend the patch with the modifications for the mpc8xx, without touching ppc4xx part. This would not break any custom board.
Please feel free to fix it for the existing 4xx boards as well. I'd really appreciate this, and I even volunteer to test it on a few of them.
Best regards,
Wolfgang Denk

Hi Stefano,
On Wednesday 06 June 2007, Wolfgang Denk wrote:
However, I didn't want to have two different coding styles with different meaning inside the same file. In fact, some lines later the whole mess of #ifdef was already inserted for the ppc4xx architecture using CONFIG_CONS_INDEX to switch among the interfaces.
Please feel free to clean this up the same was as I suggested. I'm sure Stefan Roese will ACK such a change.
We should get rid of all this CONFIG_CONS_INDEX stuff.
Yes, please. I'll be happy to test on 4xx hardware, if you have a patch removing this maze. Thanks.
I didn't want to change this part because this would break all ppc4xx boards that are not part of the U-Boot tree. So I preferred to add a lot of #ifdef using the same CONFIG defines as in ppc4xx instead of creating a new one.
I'm afraid I don't understand what you mean. Usually we don't care about boards that are not part of the U-Boot tree.
Right. It's impossible to support the non official board ports. Sometimes we have to make changes that *can* break inofficial code.
I will resend the patch with the modifications for the mpc8xx, without touching ppc4xx part. This would not break any custom board.
Please feel free to fix it for the existing 4xx boards as well. I'd really appreciate this, and I even volunteer to test it on a few of them.
No need to. I'll do it.
Best regards, Stefan
===================================================================== 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@denx.de =====================================================================

On Wednesday 06 June 2007 01:49, Wolfgang Denk wrote:
We should get rid of all this CONFIG_CONS_INDEX stuff.
CONFIG_CONS_INDEX has a useful meaning inside the NS16550 driver, so I do not drop it. I removed only the mess inside common/serial.c in the same way as you suggested for the mpc8xx.
Please feel free to fix it for the existing 4xx boards as well. I'd really appreciate this, and I even volunteer to test it on a few of them.
If I am not wrong, only the mcc200 board for ppc4xx needs multiple serial interfaces and uses the NS16550 driver, requiring some testing.
The PPC5200 based boards (the only other architecture using multiple serials) do not use the NS16450 and they rely on the PSC driver, configured by the CONFIG_UART1_CONSOLE (and I do not change this mechanism).
I have also noted that CONFIG_SERIAL_MULTI is always on for the mpc8xx (set implicitely by include/common.h and not by the board config file), even if there was no full support to have multiple serial interfaces. I think this gave us the nice feature to have in a easy way one SMC and one SCC and to switch between them (but not two SMCs or multiple SCCs), but now with full support for multiple interfaces I think this behavior is wrong and I removed it (it breaks all mpc8xx boards requiring to configure the default console). Multiple interfaces must be enabled setting explicitely CONFIG_SERIAL_MULTI in their config file. And at the moment, there is no board where more that one CONFIG_8xx_CONS_XXX is set.
Regards, stefano babic

Hi Stefano,
On Wednesday 06 June 2007, Stefano Babic wrote:
On Wednesday 06 June 2007 01:49, Wolfgang Denk wrote:
We should get rid of all this CONFIG_CONS_INDEX stuff.
CONFIG_CONS_INDEX has a useful meaning inside the NS16550 driver, so I do not drop it. I removed only the mess inside common/serial.c in the same way as you suggested for the mpc8xx.
Please feel free to fix it for the existing 4xx boards as well. I'd really appreciate this, and I even volunteer to test it on a few of them.
If I am not wrong, only the mcc200 board for ppc4xx needs multiple serial interfaces and uses the NS16550 driver, requiring some testing.
mcc200 is not PPC4xx but MPC5200. All 4xx boards use the serial driver cpu/ppc4xx/serial.c.
And lot's of the 4xx boards use multiple serial ports (CONFIG_SERIAL_MULTI).
Viele Grüße, Stefan
===================================================================== 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@denx.de =====================================================================

On Wednesday 06 June 2007 15:13, Stefan Roese wrote:
mcc200 is not PPC4xx but MPC5200. All 4xx boards use the serial driver cpu/ppc4xx/serial.c.
You're right, I wanted here list boards not belonging to ppc4xx architecture but using CONFIG_SERIAL_MULTI.
Regards, stefano

In message 200706061503.02268.sbabic@denx.de you wrote:
I have also noted that CONFIG_SERIAL_MULTI is always on for the mpc8xx (set implicitely by include/common.h and not by the board config file), even if there was no full support to have multiple serial interfaces. I think this gave us the nice feature to have in a easy way one SMC and one SCC and to switch between them (but not two SMCs or multiple SCCs), but now with full support for multiple interfaces I think this behavior is wrong and I removed it (it breaks all mpc8xx boards requiring to configure the default console). Multiple interfaces must be enabled setting explicitely CONFIG_SERIAL_MULTI in their config file. And at the moment, there is no board where more that one CONFIG_8xx_CONS_XXX is set.
You probably have broken the lwmon board, where a second serial port may be used for a modem remote control interface.
Best regards,
Wolfgang Denk

On Wednesday 06 June 2007 15:55, Wolfgang Denk wrote:
You probably have broken the lwmon board, where a second serial port may be used for a modem remote control interface.
You are right, really I patched default_serial_console() in lwmon.c, too.
Regards, stefano

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@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) \

Hi Stefano,
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@denx.de
I am not able to apply this patch, it seems it got mangled by your mailer. Can you please repost as an inline attachment?
Apart from that, does anyone expect problems if I apply that to the repository?
Thanks Detlev

Detlev Zundel wrote:
Hi Stefano,
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@denx.de
I am not able to apply this patch, it seems it got mangled by your mailer. Can you please repost as an inline attachment?
Apart from that, does anyone expect problems if I apply that to the repository?
It does not compile for MPC823. Stefano, could you please build it for TQM823L as well. To fix it, I changed in cpu/mpc8xx/serial.c:
#if (!defined(CONFIG_8xx_CONS_SMC1)) && (defined(CONFIG_MPC823) || defined(CONFIG_MPC850)) volatile iop8xx_t *ip = (iop8xx_t *)&(im->im_ioport); #endif
into
#if defined(CONFIG_8xx_CONS_SMC2) && (defined(CONFIG_MPC823) || defined(CONFIG_MPC850)) volatile iop8xx_t *ip = (iop8xx_t *)&(im->im_ioport); #endif
Furthermore, to get reduce the #ifdef mess, I would use another method to handle compile and run time selection of the serial port. Instead of:
#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; #endif #ifdef CONFIG_SERIAL_MULTI } #endif
you could simple write:
if (smc_index == SMC1_INDEX) { /* Use Port B for SMC1 instead of other functions. */ cp->cp_pbpar |= 0x000000c0; cp->cp_pbdir &= ~0x000000c0; cp->cp_pbodr &= ~0x000000c0; }
For the static case, just define smc_index somewhere in a header file:
#ifndef CONFIG_SERIAL_MULTI #if defined(CONFIG_8xx_CONS_SMC1) #define smc_index SMC1_INDEX #elif defined(CONFIG_8xx_CONS_SMC2) #define smc_index SMC2_INDEX #endif
The optimizer will then eliminate the unused code. This makes the code much more readable, apart from checking the syntax.
Any comments?
Wolfgang.

On Friday 15 June 2007 21:38, Wolfgang Grandegger wrote:
#if defined(CONFIG_8xx_CONS_SMC2) && (defined(CONFIG_MPC823) || defined(CONFIG_MPC850)) volatile iop8xx_t *ip = (iop8xx_t *)&(im->im_ioport); #endif
I see, on MPC823 the port for SMC2 is not configured if both SMCs are used :(.
you could simple write:
if (smc_index == SMC1_INDEX) { /* Use Port B for SMC1 instead of other functions. */ cp->cp_pbpar |= 0x000000c0; cp->cp_pbdir &= ~0x000000c0; cp->cp_pbodr &= ~0x000000c0; }
You are right, but my intention was to assure the highest backward compatibility, because I am aware that a lot of boards are currently using this driver. Changes as you suggest have a (small) impact on the runtime behavior, because, to clean up the code, parameter values as PROFF_SMC,CPM_CR_CH_SMC must be taken from the structure I fill in. I could simplify other parts of code as allocating the buffers from DPRAM from:
#ifdef CONFIG_SERIAL_MULTI dpaddr=ALIGN(CPM_SERIAL_BASE+(sizeof(cbd_t)*2+2)*smc_index,8); #else dpaddr=CPM_SERIAL_BASE; #endif
into simply: dpaddr=ALIGN(CPM_SERIAL_BASE+(sizeof(cbd_t)*2+2)*smc_index,8);
Theoretically, no problem, there is enough place in DPRAM to do this. To be really sure, it should be tested on all boards :(. I know, we are talking about small changes but I gave compatibility the highest priority doing this job.
Now if CONFIG_SERIAL_MULTI is not set, we have (quite) the same driver as in the past.
However, I agree with you that this makes code less readable :(.
stefano

In message 200706171531.33232.sbabic@denx.de you wrote:
Theoretically, no problem, there is enough place in DPRAM to do this. To be
Are you sure that there is enough room? Even if microcode is loaded?
Best regards,
Wolfgang Denk

Stefano Babic wrote:
On Friday 15 June 2007 21:38, Wolfgang Grandegger wrote:
#if defined(CONFIG_8xx_CONS_SMC2) && (defined(CONFIG_MPC823) || defined(CONFIG_MPC850)) volatile iop8xx_t *ip = (iop8xx_t *)&(im->im_ioport); #endif
I see, on MPC823 the port for SMC2 is not configured if both SMCs are used :(.
you could simple write:
if (smc_index == SMC1_INDEX) { /* Use Port B for SMC1 instead of other functions. */ cp->cp_pbpar |= 0x000000c0; cp->cp_pbdir &= ~0x000000c0; cp->cp_pbodr &= ~0x000000c0; }
You are right, but my intention was to assure the highest backward compatibility, because I am aware that a lot of boards are currently using this driver. Changes as you suggest have a (small) impact on the runtime behavior, because, to clean up the code, parameter values as PROFF_SMC,CPM_CR_CH_SMC must be taken from the structure I fill in. I could simplify other parts of code as allocating the buffers from DPRAM from:
#ifdef CONFIG_SERIAL_MULTI dpaddr=ALIGN(CPM_SERIAL_BASE+(sizeof(cbd_t)*2+2)*smc_index,8); #else dpaddr=CPM_SERIAL_BASE; #endif
into simply: dpaddr=ALIGN(CPM_SERIAL_BASE+(sizeof(cbd_t)*2+2)*smc_index,8);
Theoretically, no problem, there is enough place in DPRAM to do this. To be really sure, it should be tested on all boards :(.
I did not propose to use more DPRAM space, but writing the driver in a way, that it can handle both, the compile and run-time selection with less #ifdef's.
I know, we are talking about small changes but I gave compatibility the highest priority doing this job.
Now if CONFIG_SERIAL_MULTI is not set, we have (quite) the same driver as in the past.
However, I agree with you that this makes code less readable :(.
If we go on like that, U-Boot code becomes more and more unreadable. To improve code quality, take the risk. Nevertheless, I think what is really missing is a clever device interface.
Wolfgang.

On Friday 15 June 2007 18:03, Detlev Zundel wrote:
I am not able to apply this patch, it seems it got mangled by your mailer. Can you please repost as an inline attachment?
I supposed I did, but my mailer probably disagreed with me :)
I will send the patch again.
Apart from that, does anyone expect problems if I apply that to the repository?
I compiled all ppc boards with the MAKEALL script and I fixed small compiling problems. I protected all changed code with the CONFIG_SERIAL_MULTI switch and this should assure a high backward compatibility.
However, I see Wolfgang G. reported a problem on TQM823L and I will check it.
stefano
participants (5)
-
Detlev Zundel
-
Stefan Roese
-
Stefano Babic
-
Wolfgang Denk
-
Wolfgang Grandegger