From: Heiko Schocher <hs@denx.de>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 01/31] powerpc: 8xx serial: add configurable SMC Rx buffer len
Date: Wed, 28 Jan 2009 10:38:33 +0100 [thread overview]
Message-ID: <49802799.7090105@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 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
reply other threads:[~2009-01-28 9:38 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=49802799.7090105@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.