Commit c92fac91a06c60f874c605e3ca80dd407c1caaa7

Authored by Heiko Schocher
Committed by Wolfgang Denk
1 parent bced7ccefa

82xx serial, smc: add configurable SMC Rx buffer len

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

Showing 2 changed files with 68 additions and 37 deletions Side-by-side Diff

... ... @@ -484,6 +484,14 @@
484 484 CONFIG_SYS_BAUDRATE_TABLE, see below.
485 485 CONFIG_SYS_BRGCLK_PRESCALE, baudrate prescale
486 486  
  487 +- Console Rx buffer length
  488 + With CONFIG_SYS_SMC_RXBUFLEN it is possible to define
  489 + the maximum receive buffer length for the SMC.
  490 + This option is actual only for 82xx possible.
  491 + If using CONFIG_SYS_SMC_RXBUFLEN also CONFIG_SYS_MAXIDLE
  492 + must be defined, to setup the maximum idle timeout for
  493 + the SMC.
  494 +
487 495 - Interrupt driven serial port input:
488 496 CONFIG_SERIAL_SOFTWARE_FIFO
489 497  
cpu/mpc8260/serial_smc.c
... ... @@ -64,6 +64,23 @@
64 64  
65 65 #endif
66 66  
  67 +#if !defined(CONFIG_SYS_SMC_RXBUFLEN)
  68 +#define CONFIG_SYS_SMC_RXBUFLEN 1
  69 +#define CONFIG_SYS_MAXIDLE 0
  70 +#else
  71 +#if !defined(CONFIG_SYS_MAXIDLE)
  72 +#error "you must define CONFIG_SYS_MAXIDLE"
  73 +#endif
  74 +#endif
  75 +
  76 +typedef volatile struct serialbuffer {
  77 + cbd_t rxbd; /* Rx BD */
  78 + cbd_t txbd; /* Tx BD */
  79 + uint rxindex; /* index for next character to read */
  80 + volatile uchar rxbuf[CONFIG_SYS_SMC_RXBUFLEN];/* rx buffers */
  81 + volatile uchar txbuf; /* tx buffers */
  82 +} serialbuffer_t;
  83 +
67 84 /* map rs_table index to baud rate generator index */
68 85 static unsigned char brg_map[] = {
69 86 6, /* BRG7 for SMC1 */
70 87  
... ... @@ -79,9 +96,9 @@
79 96 volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
80 97 volatile smc_t *sp;
81 98 volatile smc_uart_t *up;
82   - volatile cbd_t *tbdf, *rbdf;
83 99 volatile cpm8260_t *cp = &(im->im_cpm);
84 100 uint dpaddr;
  101 + volatile serialbuffer_t *rtx;
85 102  
86 103 /* initialize pointers to SMC */
87 104  
88 105  
89 106  
90 107  
... ... @@ -99,18 +116,22 @@
99 116 * damm: allocating space after the two buffers for rx/tx data
100 117 */
101 118  
102   - dpaddr = m8260_cpm_dpalloc((2 * sizeof (cbd_t)) + 2, 16);
  119 + /* allocate size of struct serialbuffer with bd rx/tx,
  120 + * buffer rx/tx and rx index
  121 + */
  122 + dpaddr = m8260_cpm_dpalloc((sizeof(serialbuffer_t)), 16);
103 123  
  124 + rtx = (serialbuffer_t *)&im->im_dprambase[dpaddr];
  125 +
104 126 /* Set the physical address of the host memory buffers in
105 127 * the buffer descriptors.
106 128 */
107   - rbdf = (cbd_t *)&im->im_dprambase[dpaddr];
108   - rbdf->cbd_bufaddr = (uint) (rbdf+2);
109   - rbdf->cbd_sc = 0;
110   - tbdf = rbdf + 1;
111   - tbdf->cbd_bufaddr = ((uint) (rbdf+2)) + 1;
112   - tbdf->cbd_sc = 0;
  129 + rtx->rxbd.cbd_bufaddr = (uint) &rtx->rxbuf;
  130 + rtx->rxbd.cbd_sc = 0;
113 131  
  132 + rtx->txbd.cbd_bufaddr = (uint) &rtx->txbuf;
  133 + rtx->txbd.cbd_sc = 0;
  134 +
114 135 /* Set up the uart parameters in the parameter ram.
115 136 */
116 137 up->smc_rbase = dpaddr;
117 138  
... ... @@ -142,13 +163,13 @@
142 163  
143 164 /* Make the first buffer the only buffer.
144 165 */
145   - tbdf->cbd_sc |= BD_SC_WRAP;
146   - rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP;
  166 + rtx->txbd.cbd_sc |= BD_SC_WRAP;
  167 + rtx->rxbd.cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP;
147 168  
148   - /* Single character receive.
149   - */
150   - up->smc_mrblr = 1;
151   - up->smc_maxidl = 0;
  169 + /* single/multi character receive. */
  170 + up->smc_mrblr = CONFIG_SYS_SMC_RXBUFLEN;
  171 + up->smc_maxidl = CONFIG_SYS_MAXIDLE;
  172 + rtx->rxindex = 0;
152 173  
153 174 /* Initialize Tx/Rx parameters.
154 175 */
155 176  
156 177  
157 178  
158 179  
... ... @@ -183,27 +204,23 @@
183 204 void
184 205 serial_putc(const char c)
185 206 {
186   - volatile cbd_t *tbdf;
187   - volatile char *buf;
188 207 volatile smc_uart_t *up;
189 208 volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
  209 + volatile serialbuffer_t *rtx;
190 210  
191 211 if (c == '\n')
192 212 serial_putc ('\r');
193 213  
194 214 up = (smc_uart_t *)&(im->im_dprambase[PROFF_SMC]);
195 215  
196   - tbdf = (cbd_t *)&im->im_dprambase[up->smc_tbase];
  216 + rtx = (serialbuffer_t *)&im->im_dprambase[up->smc_rbase];
197 217  
198   - /* Wait for last character to go.
199   - */
200   - buf = (char *)tbdf->cbd_bufaddr;
201   - while (tbdf->cbd_sc & BD_SC_READY)
  218 + /* Wait for last character to go. */
  219 + while (rtx->txbd.cbd_sc & BD_SC_READY & BD_SC_READY)
202 220 ;
203   -
204   - *buf = c;
205   - tbdf->cbd_datlen = 1;
206   - tbdf->cbd_sc |= BD_SC_READY;
  221 + rtx->txbuf = c;
  222 + rtx->txbd.cbd_datlen = 1;
  223 + rtx->txbd.cbd_sc |= BD_SC_READY;
207 224 }
208 225  
209 226 void
210 227  
211 228  
212 229  
213 230  
214 231  
215 232  
216 233  
217 234  
218 235  
... ... @@ -217,39 +234,45 @@
217 234 int
218 235 serial_getc(void)
219 236 {
220   - volatile cbd_t *rbdf;
221   - volatile unsigned char *buf;
222 237 volatile smc_uart_t *up;
223 238 volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
224   - unsigned char c;
  239 + volatile serialbuffer_t *rtx;
  240 + unsigned char c;
225 241  
226 242 up = (smc_uart_t *)&(im->im_dprambase[PROFF_SMC]);
227 243  
228   - rbdf = (cbd_t *)&im->im_dprambase[up->smc_rbase];
  244 + rtx = (serialbuffer_t *)&im->im_dprambase[up->smc_rbase];
229 245  
230 246 /* Wait for character to show up.
231 247 */
232   - buf = (unsigned char *)rbdf->cbd_bufaddr;
233   - while (rbdf->cbd_sc & BD_SC_EMPTY)
  248 + while (rtx->rxbd.cbd_sc & BD_SC_EMPTY)
234 249 ;
235   - c = *buf;
236   - rbdf->cbd_sc |= BD_SC_EMPTY;
237 250  
  251 + /* the characters are read one by one,
  252 + * use the rxindex to know the next char to deliver
  253 + */
  254 + c = *(unsigned char *) (rtx->rxbd.cbd_bufaddr + rtx->rxindex);
  255 + rtx->rxindex++;
  256 +
  257 + /* check if all char are readout, then make prepare for next receive */
  258 + if (rtx->rxindex >= rtx->rxbd.cbd_datlen) {
  259 + rtx->rxindex = 0;
  260 + rtx->rxbd.cbd_sc |= BD_SC_EMPTY;
  261 + }
238 262 return(c);
239 263 }
240 264  
241 265 int
242 266 serial_tstc()
243 267 {
244   - volatile cbd_t *rbdf;
245 268 volatile smc_uart_t *up;
246 269 volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
  270 + volatile serialbuffer_t *rtx;
247 271  
248 272 up = (smc_uart_t *)&(im->im_dprambase[PROFF_SMC]);
  273 + rtx = (serialbuffer_t *)&im->im_dprambase[up->smc_rbase];
249 274  
250   - rbdf = (cbd_t *)&im->im_dprambase[up->smc_rbase];
251   -
252   - return(!(rbdf->cbd_sc & BD_SC_EMPTY));
  275 + return !(rtx->rxbd.cbd_sc & BD_SC_EMPTY);
253 276 }
254 277  
255 278 #endif /* CONFIG_CONS_ON_SMC */