Commit c92fac91a06c60f874c605e3ca80dd407c1caaa7
Committed by
Wolfgang Denk
1 parent
bced7ccefa
Exists in
master
and in
54 other branches
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
README
... | ... | @@ -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 */ |