All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 01/31] powerpc: 8xx serial: add configurable SMC Rx buffer len
@ 2009-01-28  9:38 Heiko Schocher
  0 siblings, 0 replies; only message in thread
From: Heiko Schocher @ 2009-01-28  9:38 UTC (permalink / raw)
  To: u-boot

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 8xx 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/mpc8xx/serial.c      |  102 +++++++++++++++++++++++++++++-----------------
 include/configs/mgsuvd.h |    1 +
 2 files changed, 65 insertions(+), 38 deletions(-)

diff --git a/cpu/mpc8xx/serial.c b/cpu/mpc8xx/serial.c
index bd90dcd..cb8c2e5 100644
--- a/cpu/mpc8xx/serial.c
+++ b/cpu/mpc8xx/serial.c
@@ -65,6 +65,18 @@ DECLARE_GLOBAL_DATA_PTR;

 #endif /* CONFIG_8xx_CONS_SCCx */

+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;
+
 static void serial_setdivisor(volatile cpm8xx_t *cp)
 {
 	int divisor=(gd->cpu_clk + 8*gd->baudrate)/16/gd->baudrate;
@@ -113,12 +125,12 @@ static int smc_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 cpm8xx_t *cp = &(im->im_cpm);
 #if (!defined(CONFIG_8xx_CONS_SMC1)) && (defined(CONFIG_MPC823) || defined(CONFIG_MPC850))
 	volatile iop8xx_t *ip = (iop8xx_t *)&(im->im_ioport);
 #endif
 	uint	dpaddr;
+	volatile serialbuffer_t *rtx;

 	/* initialize pointers to SMC */

@@ -194,23 +206,26 @@ static int smc_init (void)
 	 */

 #ifdef CONFIG_SYS_ALLOC_DPRAM
-	dpaddr = dpram_alloc_align (sizeof(cbd_t)*2 + 2, 8) ;
+	/* allocate
+	 * size of struct serialbuffer with bd rx/tx, buffer rx/tx and rx index
+	 */
+	dpaddr = dpram_alloc_align((sizeof(serialbuffer_t)), 8);
 #else
 	dpaddr = CPM_SERIAL_BASE ;
 #endif

+	rtx = (serialbuffer_t *)&cp->cp_dpmem[dpaddr];
 	/* Allocate space for two buffer descriptors in the DP ram.
 	 * For now, this address seems OK, but it may have to
 	 * change with newer versions of the firmware.
 	 * damm: allocating space after the two buffers for rx/tx data
 	 */

-	rbdf = (cbd_t *)&cp->cp_dpmem[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.
 	*/
@@ -256,13 +271,21 @@ static int smc_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.
 	*/
@@ -285,11 +308,10 @@ static int smc_init (void)
 static void
 smc_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 cpm8xx_t	*cpmp = &(im->im_cpm);
+	volatile serialbuffer_t	*rtx;

 #ifdef CONFIG_MODEM_SUPPORT
 	if (gd->be_quiet)
@@ -300,23 +322,18 @@ smc_putc(const char c)
 		smc_putc ('\r');

 	up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_SMC];
-#ifdef CONFIG_SYS_SMC_UCODE_PATCH
-	up = (smc_uart_t *) &cpmp->cp_dpmem[up->smc_rpbase];
-#endif
+ #ifdef CONFIG_SYS_SMC_UCODE_PATCH
+	up = (smc_uart_t *)&cpmp->cp_dpmem[up->smc_rpbase];
+ #endif

-	tbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_tbase];
+	rtx = (serialbuffer_t *)&cpmp->cp_dpmem[up->smc_rbase];

-	/* Wait for last character to go.
-	*/
-
-	buf = (char *)tbdf->cbd_bufaddr;
-
-	*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;
 	__asm__("eieio");

-	while (tbdf->cbd_sc & BD_SC_READY) {
+	while (rtx->txbd.cbd_sc & BD_SC_READY) {
 		WATCHDOG_RESET ();
 		__asm__("eieio");
 	}
@@ -333,49 +350,58 @@ smc_puts (const char *s)
 static int
 smc_getc(void)
 {
-	volatile cbd_t		*rbdf;
-	volatile unsigned char	*buf;
 	volatile smc_uart_t	*up;
 	volatile immap_t	*im = (immap_t *)CONFIG_SYS_IMMR;
 	volatile cpm8xx_t	*cpmp = &(im->im_cpm);
-	unsigned char		c;
+	volatile serialbuffer_t	*rtx;
+	unsigned char  c;

 	up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_SMC];
 #ifdef CONFIG_SYS_SMC_UCODE_PATCH
 	up = (smc_uart_t *) &cpmp->cp_dpmem[up->smc_rpbase];
 #endif
-
-	rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase];
+	rtx = (serialbuffer_t *)&cpmp->cp_dpmem[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)
 		WATCHDOG_RESET ();

-	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);
 }

 static int
 smc_tstc(void)
 {
-	volatile cbd_t		*rbdf;
 	volatile smc_uart_t	*up;
 	volatile immap_t	*im = (immap_t *)CONFIG_SYS_IMMR;
 	volatile cpm8xx_t	*cpmp = &(im->im_cpm);
+	volatile serialbuffer_t	*rtx;

 	up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_SMC];
 #ifdef CONFIG_SYS_SMC_UCODE_PATCH
 	up = (smc_uart_t *) &cpmp->cp_dpmem[up->smc_rpbase];
 #endif

-	rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase];
+	rtx = (serialbuffer_t *)&cpmp->cp_dpmem[up->smc_rbase];

-	return(!(rbdf->cbd_sc & BD_SC_EMPTY));
+	return !(rtx->rxbd.cbd_sc & BD_SC_EMPTY);
 }

 struct serial_device serial_smc_device =
diff --git a/include/configs/mgsuvd.h b/include/configs/mgsuvd.h
index f53b6d3..8f82751 100644
--- a/include/configs/mgsuvd.h
+++ b/include/configs/mgsuvd.h
@@ -44,6 +44,7 @@
 #define CONFIG_SYS_SMC_UCODE_PATCH	1	/* Relocate SMC1 */
 #define CONFIG_SYS_SMC_DPMEM_OFFSET	0x1fc0
 #define CONFIG_8xx_CONS_SMC1	1	/* Console is on SMC1		*/
+#define CONFIG_SYS_SMC_RXBUFLEN		16

 #define CONFIG_SYS_CPM_BOOTCOUNT_ADDR	0x1eb0	/* In case of SMC relocation, the
 					 * default value is not working */
-- 
1.6.0.6

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2009-01-28  9:38 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-01-28  9:38 [U-Boot] [PATCH 01/31] powerpc: 8xx serial: add configurable SMC Rx buffer len Heiko Schocher

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.