All of lore.kernel.org
 help / color / mirror / Atom feed
From: Heiko Schocher <hs@denx.de>
To: u-boot@lists.denx.de
Subject: [U-Boot] 8xx serial, smc: add configurable SMC Rx buffer len
Date: Tue, 10 Feb 2009 09:31:47 +0100	[thread overview]
Message-ID: <49913B73.2070502@denx.de> (raw)

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 this driver works as the
old version.

When defining CONFIG_SYS_SMC_RXBUFLEN also
CONFIG_SYS_MAXIDLE must be defined to setup the maximum
idle timeout for the SMC.

Signed-off-by: Heiko Schocher <hs@denx.de>
---
 README              |    2 +-
 cpu/mpc8xx/serial.c |   94 +++++++++++++++++++++++++++++++--------------------
 2 files changed, 58 insertions(+), 38 deletions(-)

diff --git a/README b/README
index fbdccb0..c17f646 100644
--- a/README
+++ b/README
@@ -487,7 +487,7 @@ The following options need to be configured:
 - Console Rx buffer length
 		With CONFIG_SYS_SMC_RXBUFLEN it is possible to define
 		the maximum receive buffer length for the SMC.
-		This option is actual only for 82xx possible.
+		This option is actual only for 82xx and 8xx possible.
 		If using CONFIG_SYS_SMC_RXBUFLEN also CONFIG_SYS_MAXIDLE
 		must be defined, to setup the maximum idle timeout for
 		the SMC.
diff --git a/cpu/mpc8xx/serial.c b/cpu/mpc8xx/serial.c
index bd90dcd..972f190 100644
--- a/cpu/mpc8xx/serial.c
+++ b/cpu/mpc8xx/serial.c
@@ -65,6 +65,23 @@ DECLARE_GLOBAL_DATA_PTR;

 #endif /* CONFIG_8xx_CONS_SCCx */

+#if !defined(CONFIG_SYS_SMC_RXBUFLEN)
+#define CONFIG_SYS_SMC_RXBUFLEN	1
+#define CONFIG_SYS_MAXIDLE	0
+#else
+#if !defined(CONFIG_SYS_MAXIDLE)
+#error "you must define CONFIG_SYS_MAXIDLE"
+#endif
+#endif
+
+typedef volatile struct serialbuffer {
+	cbd_t	rxbd;		/* Rx BD */
+	cbd_t	txbd;		/* Tx BD */
+	uint	rxindex;	/* index for next character to read */
+	volatile uchar	rxbuf[CONFIG_SYS_SMC_RXBUFLEN];/* rx buffers */
+	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 +130,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 +211,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 +276,13 @@ 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;

-	/* Single character receive.
-	*/
-	up->smc_mrblr = 1;
-	up->smc_maxidl = 0;
+	/* single/multi character receive. */
+	up->smc_mrblr = CONFIG_SYS_SMC_RXBUFLEN;
+	up->smc_maxidl = CONFIG_SYS_MAXIDLE;
+	rtx->rxindex = 0;

 	/* Initialize Tx/Rx parameters.
 	*/
@@ -285,11 +305,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)
@@ -304,19 +323,16 @@ smc_putc(const char c)
 	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 +349,53 @@ 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;
+	/* 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;
+	}
 	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 =
-- 
1.6.0.6

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

             reply	other threads:[~2009-02-10  8:31 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-02-10  8:31 Heiko Schocher [this message]
2009-02-11 22:18 ` [U-Boot] 8xx serial, smc: add configurable SMC Rx buffer len Wolfgang Denk

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=49913B73.2070502@denx.de \
    --to=hs@denx.de \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.