
This patch adds the configuration option CONFIG_SYS_SMC_RXBUFLEN. With this option it is possible to allow the receive buffer for the SMC on 82xx to be greater then 1. In case CONFIG_SYS_SMC_RXBUFLEN == 1 or it is not defined this driver works as the old version.
Signed-off-by: Heiko Schocher hs@denx.de --- cpu/mpc8260/serial_smc.c | 94 +++++++++++++++++++++++++++++++--------------- include/configs/mgcoge.h | 1 + 2 files changed, 64 insertions(+), 31 deletions(-)
diff --git a/cpu/mpc8260/serial_smc.c b/cpu/mpc8260/serial_smc.c index a6efa66..6825e2e 100644 --- a/cpu/mpc8260/serial_smc.c +++ b/cpu/mpc8260/serial_smc.c @@ -64,6 +64,18 @@ DECLARE_GLOBAL_DATA_PTR;
#endif
+typedef volatile struct serialbuffer { + cbd_t rxbd; /* Rx BD */ + cbd_t txbd; /* Tx BD */ +#ifdef CONFIG_SYS_SMC_RXBUFLEN + uint rxindex; /* index for next character to read */ + volatile uchar rxbuf[CONFIG_SYS_SMC_RXBUFLEN];/* rx buffers */ +#else + volatile uchar rxbuf[1]; /* rx buffers */ +#endif + volatile uchar txbuf; /* tx buffers */ +} serialbuffer_t; + /* map rs_table index to baud rate generator index */ static unsigned char brg_map[] = { 6, /* BRG7 for SMC1 */ @@ -79,9 +91,9 @@ int serial_init (void) volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR; volatile smc_t *sp; volatile smc_uart_t *up; - volatile cbd_t *tbdf, *rbdf; volatile cpm8260_t *cp = &(im->im_cpm); uint dpaddr; + volatile serialbuffer_t *rtx;
/* initialize pointers to SMC */
@@ -99,17 +111,21 @@ int serial_init (void) * damm: allocating space after the two buffers for rx/tx data */
- dpaddr = m8260_cpm_dpalloc((2 * sizeof (cbd_t)) + 2, 16); + /* allocate + * size of struct serialbuffer with bd rx/tx, buffer rx/tx and rx index + */ + dpaddr = m8260_cpm_dpalloc((sizeof(serialbuffer_t)), 16); + + rtx = (serialbuffer_t *)&im->im_dprambase[dpaddr];
/* Set the physical address of the host memory buffers in * the buffer descriptors. */ - rbdf = (cbd_t *)&im->im_dprambase[dpaddr]; - rbdf->cbd_bufaddr = (uint) (rbdf+2); - rbdf->cbd_sc = 0; - tbdf = rbdf + 1; - tbdf->cbd_bufaddr = ((uint) (rbdf+2)) + 1; - tbdf->cbd_sc = 0; + rtx->rxbd.cbd_bufaddr = (uint) &rtx->rxbuf; + rtx->rxbd.cbd_sc = 0; + + rtx->txbd.cbd_bufaddr = (uint) &rtx->txbuf; + rtx->txbd.cbd_sc = 0;
/* Set up the uart parameters in the parameter ram. */ @@ -142,13 +158,21 @@ int serial_init (void)
/* Make the first buffer the only buffer. */ - tbdf->cbd_sc |= BD_SC_WRAP; - rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP; + rtx->txbd.cbd_sc |= BD_SC_WRAP; + rtx->rxbd.cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP;
+#ifdef CONFIG_SYS_SMC_RXBUFLEN + /* multi-character receive. + */ + up->smc_mrblr = CONFIG_SYS_SMC_RXBUFLEN; + up->smc_maxidl = 10; + rtx->rxindex = 0; +#else /* Single character receive. */ up->smc_mrblr = 1; up->smc_maxidl = 0; +#endif
/* Initialize Tx/Rx parameters. */ @@ -183,27 +207,24 @@ serial_setbrg (void) void serial_putc(const char c) { - volatile cbd_t *tbdf; - volatile char *buf; volatile smc_uart_t *up; volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR; + volatile serialbuffer_t *rtx;
if (c == '\n') serial_putc ('\r');
up = (smc_uart_t *)&(im->im_dprambase[PROFF_SMC]);
- tbdf = (cbd_t *)&im->im_dprambase[up->smc_tbase]; + rtx = (serialbuffer_t *)&im->im_dprambase[up->smc_rbase];
/* Wait for last character to go. */ - buf = (char *)tbdf->cbd_bufaddr; - while (tbdf->cbd_sc & BD_SC_READY) + while (rtx->txbd.cbd_sc & BD_SC_READY & BD_SC_READY) ; - - *buf = c; - tbdf->cbd_datlen = 1; - tbdf->cbd_sc |= BD_SC_READY; + rtx->txbuf = c; + rtx->txbd.cbd_datlen = 1; + rtx->txbd.cbd_sc |= BD_SC_READY; }
void @@ -217,39 +238,50 @@ serial_puts (const char *s) int serial_getc(void) { - volatile cbd_t *rbdf; - volatile unsigned char *buf; volatile smc_uart_t *up; volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR; - unsigned char c; + volatile serialbuffer_t *rtx; + unsigned char c;
up = (smc_uart_t *)&(im->im_dprambase[PROFF_SMC]);
- rbdf = (cbd_t *)&im->im_dprambase[up->smc_rbase]; + rtx = (serialbuffer_t *)&im->im_dprambase[up->smc_rbase];
/* Wait for character to show up. */ - buf = (unsigned char *)rbdf->cbd_bufaddr; - while (rbdf->cbd_sc & BD_SC_EMPTY) + while (rtx->rxbd.cbd_sc & BD_SC_EMPTY) ; - c = *buf; - rbdf->cbd_sc |= BD_SC_EMPTY;
+#ifdef CONFIG_SYS_SMC_RXBUFLEN + /* the characters are read one by one, + * use the rxindex to know the next char to deliver + */ + c = *(unsigned char *) (rtx->rxbd.cbd_bufaddr+rtx->rxindex); + rtx->rxindex++; + + /* check if all char are readout, then make prepare for next receive */ + if (rtx->rxindex >= rtx->rxbd.cbd_datlen) { + rtx->rxindex = 0; + rtx->rxbd.cbd_sc |= BD_SC_EMPTY; + } +#else + c = *(unsigned char *) (rtx->rxbd.cbd_bufaddr); + rtx->rxbd.cbd_sc |= BD_SC_EMPTY; +#endif return(c); }
int serial_tstc() { - volatile cbd_t *rbdf; volatile smc_uart_t *up; volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR; + volatile serialbuffer_t *rtx;
up = (smc_uart_t *)&(im->im_dprambase[PROFF_SMC]); + rtx = (serialbuffer_t *)&im->im_dprambase[up->smc_rbase];
- rbdf = (cbd_t *)&im->im_dprambase[up->smc_rbase]; - - return(!(rbdf->cbd_sc & BD_SC_EMPTY)); + return !(rtx->rxbd.cbd_sc & BD_SC_EMPTY); }
#endif /* CONFIG_CONS_ON_SMC */ diff --git a/include/configs/mgcoge.h b/include/configs/mgcoge.h index 9416a03..ddb06aa 100644 --- a/include/configs/mgcoge.h +++ b/include/configs/mgcoge.h @@ -49,6 +49,7 @@ #undef CONFIG_CONS_ON_SCC /* It's not on SCC */ #undef CONFIG_CONS_NONE /* It's not on external UART */ #define CONFIG_CONS_INDEX 2 /* SMC2 is used for console */ +#define CONFIG_SYS_SMC_RXBUFLEN 16
/* * Select ethernet configuration