arspi.c revision 1.10.36.1 1 /* $NetBSD: arspi.c,v 1.10.36.1 2018/09/06 06:55:37 pgoyette Exp $ */
2
3 /*-
4 * Copyright (c) 2006 Urbana-Champaign Independent Media Center.
5 * Copyright (c) 2006 Garrett D'Amore.
6 * All rights reserved.
7 *
8 * Portions of this code were written by Garrett D'Amore for the
9 * Champaign-Urbana Community Wireless Network Project.
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above
17 * copyright notice, this list of conditions and the following
18 * disclaimer in the documentation and/or other materials provided
19 * with the distribution.
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgements:
22 * This product includes software developed by the Urbana-Champaign
23 * Independent Media Center.
24 * This product includes software developed by Garrett D'Amore.
25 * 4. Urbana-Champaign Independent Media Center's name and Garrett
26 * D'Amore's name may not be used to endorse or promote products
27 * derived from this software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE URBANA-CHAMPAIGN INDEPENDENT
30 * MEDIA CENTER AND GARRETT D'AMORE ``AS IS'' AND ANY EXPRESS OR
31 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
32 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33 * ARE DISCLAIMED. IN NO EVENT SHALL THE URBANA-CHAMPAIGN INDEPENDENT
34 * MEDIA CENTER OR GARRETT D'AMORE BE LIABLE FOR ANY DIRECT, INDIRECT,
35 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
41 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 */
43
44 #include <sys/cdefs.h>
45 __KERNEL_RCSID(0, "$NetBSD: arspi.c,v 1.10.36.1 2018/09/06 06:55:37 pgoyette Exp $");
46
47 #include "locators.h"
48
49 #include <sys/param.h>
50 #include <sys/bus.h>
51 #include <sys/cpu.h>
52 #include <sys/device.h>
53 #include <sys/errno.h>
54 #include <sys/kernel.h>
55 #include <sys/malloc.h>
56 #include <sys/proc.h>
57 #include <sys/systm.h>
58
59 #include <mips/atheros/include/ar5315reg.h>
60 #include <mips/atheros/include/arbusvar.h>
61
62 #include <mips/atheros/dev/arspireg.h>
63
64 #include <dev/spi/spiflash.h>
65 #include <dev/spi/spivar.h>
66
67 /*
68 * This device is intended only to operate with specific SPI flash
69 * parts, and is not a general purpose SPI host. (Or at least if it
70 * is, the Linux and eCos sources do not show how to use it as such.)
71 * And lack of documentation on the Atheros SoCs is less than helpful.
72 *
73 * So for now we just "emulate" enough of the host bus framework to
74 * make the SPI flash drivers happy.
75 */
76
77 struct arspi_job {
78 uint8_t job_opcode;
79 struct spi_chunk *job_chunk;
80 uint32_t job_flags;
81 uint32_t job_addr;
82 uint32_t job_data;
83 int job_rxcnt;
84 int job_txcnt;
85 int job_addrcnt;
86 int job_rresid;
87 int job_wresid;
88 };
89
90 #define JOB_READ 0x1
91 #define JOB_WRITE 0x2
92 #define JOB_LAST 0x4
93 #define JOB_WAIT 0x8 /* job must wait for WIP bits */
94 #define JOB_WREN 0x10 /* WREN needed */
95
96 struct arspi_softc {
97 struct spi_controller sc_spi;
98 void *sc_ih;
99 bool sc_interrupts;
100
101 struct spi_transfer *sc_transfer;
102 struct spi_chunk *sc_wchunk; /* for partial writes */
103 struct spi_transq sc_transq;
104 bus_space_tag_t sc_st;
105 bus_space_handle_t sc_sh;
106 bus_size_t sc_size;
107 };
108
109 #define STATIC
110
111 STATIC int arspi_match(device_t, cfdata_t, void *);
112 STATIC void arspi_attach(device_t, device_t, void *);
113 STATIC void arspi_interrupts(device_t);
114 STATIC int arspi_intr(void *);
115 /* SPI service routines */
116 STATIC int arspi_configure(void *, int, int, int);
117 STATIC int arspi_transfer(void *, struct spi_transfer *);
118 /* internal support */
119 STATIC void arspi_poll(struct arspi_softc *);
120 STATIC void arspi_done(struct arspi_softc *, int);
121 STATIC void arspi_sched(struct arspi_softc *);
122 STATIC int arspi_get_byte(struct spi_chunk **, uint8_t *);
123 STATIC int arspi_put_byte(struct spi_chunk **, uint8_t);
124 STATIC int arspi_make_job(struct spi_transfer *);
125 STATIC void arspi_update_job(struct spi_transfer *);
126 STATIC void arspi_finish_job(struct spi_transfer *);
127
128
129 CFATTACH_DECL_NEW(arspi, sizeof(struct arspi_softc),
130 arspi_match, arspi_attach, NULL, NULL);
131
132 #define GETREG(sc, o) bus_space_read_4(sc->sc_st, sc->sc_sh, o)
133 #define PUTREG(sc, o, v) bus_space_write_4(sc->sc_st, sc->sc_sh, o, v)
134
135 int
136 arspi_match(device_t parent, cfdata_t cf, void *aux)
137 {
138 struct arbus_attach_args *aa = aux;
139
140 if (strcmp(aa->aa_name, cf->cf_name) != 0)
141 return 0;
142 return 1;
143 }
144
145 void
146 arspi_attach(device_t parent, device_t self, void *aux)
147 {
148 struct arspi_softc *sc = device_private(self);
149 struct spibus_attach_args sba;
150 struct arbus_attach_args *aa = aux;
151
152 /*
153 * Map registers.
154 */
155 sc->sc_st = aa->aa_bst;
156 sc->sc_size = aa->aa_size;
157 if (bus_space_map(sc->sc_st, aa->aa_addr, sc->sc_size, 0,
158 &sc->sc_sh) != 0) {
159 printf(": unable to map registers!\n");
160 return;
161 }
162
163 aprint_normal(": Atheros SPI controller\n");
164
165 /*
166 * Initialize SPI controller.
167 */
168 sc->sc_spi.sct_cookie = sc;
169 sc->sc_spi.sct_configure = arspi_configure;
170 sc->sc_spi.sct_transfer = arspi_transfer;
171 sc->sc_spi.sct_nslaves = 1;
172
173
174 /*
175 * Initialize the queue.
176 */
177 spi_transq_init(&sc->sc_transq);
178
179 /*
180 * Enable device interrupts.
181 */
182 sc->sc_ih = arbus_intr_establish(aa->aa_cirq, aa->aa_mirq,
183 arspi_intr, sc);
184 if (sc->sc_ih == NULL) {
185 aprint_error("%s: couldn't establish interrupt\n",
186 device_xname(self));
187 /* just leave it in polled mode */
188 } else
189 config_interrupts(self, arspi_interrupts);
190
191 /*
192 * Initialize and attach bus attach.
193 */
194 sba.sba_controller = &sc->sc_spi;
195 (void) config_found_ia(self, "spibus", &sba, spibus_print);
196 }
197
198 void
199 arspi_interrupts(device_t self)
200 {
201 /*
202 * we never leave polling mode, because, apparently, we
203 * are missing some data about how to drive the SPI in interrupt
204 * mode.
205 */
206 #if 0
207 struct arspi_softc *sc = device_private(self);
208 int s;
209
210 s = splbio();
211 sc->sc_interrupts = true;
212 splx(s);
213 #endif
214 }
215
216 int
217 arspi_intr(void *arg)
218 {
219 struct arspi_softc *sc = arg;
220
221 while (GETREG(sc, ARSPI_REG_CTL) & ARSPI_CTL_BUSY);
222
223 arspi_done(sc, 0);
224
225 return 1;
226 }
227
228 void
229 arspi_poll(struct arspi_softc *sc)
230 {
231
232 while (sc->sc_transfer) {
233 arspi_intr(sc);
234 }
235 }
236
237 int
238 arspi_configure(void *cookie, int slave, int mode, int speed)
239 {
240
241 /*
242 * We don't support the full SPI protocol, and hopefully the
243 * firmware has programmed a reasonable mode already. So
244 * just a couple of quick sanity checks, then bail.
245 */
246 if ((mode != 0) || (slave != 0))
247 return EINVAL;
248
249 return 0;
250 }
251
252 int
253 arspi_transfer(void *cookie, struct spi_transfer *st)
254 {
255 struct arspi_softc *sc = cookie;
256 int rv;
257 int s;
258
259 st->st_busprivate = NULL;
260 if ((rv = arspi_make_job(st)) != 0) {
261 if (st->st_busprivate) {
262 free(st->st_busprivate, M_DEVBUF);
263 st->st_busprivate = NULL;
264 }
265 spi_done(st, rv);
266 return rv;
267 }
268
269 s = splbio();
270 spi_transq_enqueue(&sc->sc_transq, st);
271 if (sc->sc_transfer == NULL) {
272 arspi_sched(sc);
273 if (!sc->sc_interrupts)
274 arspi_poll(sc);
275 }
276 splx(s);
277 return 0;
278 }
279
280 void
281 arspi_sched(struct arspi_softc *sc)
282 {
283 struct spi_transfer *st;
284 struct arspi_job *job;
285 uint32_t ctl, cnt;
286
287 for (;;) {
288 if ((st = sc->sc_transfer) == NULL) {
289 if ((st = spi_transq_first(&sc->sc_transq)) == NULL) {
290 /* no work left to do */
291 break;
292 }
293 spi_transq_dequeue(&sc->sc_transq);
294 sc->sc_transfer = st;
295 }
296
297 arspi_update_job(st);
298 job = st->st_busprivate;
299
300 /* there shouldn't be anything running, but ensure it */
301 do {
302 ctl = GETREG(sc, ARSPI_REG_CTL);
303 } while (ctl & ARSPI_CTL_BUSY);
304 /* clear all of the tx and rx bits */
305 ctl &= ~(ARSPI_CTL_TXCNT_MASK | ARSPI_CTL_RXCNT_MASK);
306
307 if (job->job_flags & JOB_WAIT) {
308 PUTREG(sc, ARSPI_REG_OPCODE, SPIFLASH_CMD_RDSR);
309 /* only the opcode for tx */
310 ctl |= (1 << ARSPI_CTL_TXCNT_SHIFT);
311 /* and one rx byte */
312 ctl |= (1 << ARSPI_CTL_RXCNT_SHIFT);
313 } else if (job->job_flags & JOB_WREN) {
314 PUTREG(sc, ARSPI_REG_OPCODE, SPIFLASH_CMD_WREN);
315 /* just the opcode */
316 ctl |= (1 << ARSPI_CTL_TXCNT_SHIFT);
317 /* no rx bytes */
318 } else {
319 /* set the data */
320 PUTREG(sc, ARSPI_REG_DATA, job->job_data);
321
322 /* set the opcode and the address */
323 PUTREG(sc, ARSPI_REG_OPCODE, job->job_opcode |
324 (job->job_addr << 8));
325
326 /* now set txcnt */
327 cnt = 1; /* opcode */
328 cnt += job->job_addrcnt + job->job_txcnt;
329 ctl |= (cnt << ARSPI_CTL_TXCNT_SHIFT);
330
331 /* now set rxcnt */
332 cnt = job->job_rxcnt;
333 ctl |= (cnt << ARSPI_CTL_RXCNT_SHIFT);
334 }
335
336 /* set the start bit */
337 ctl |= ARSPI_CTL_START;
338
339 PUTREG(sc, ARSPI_REG_CTL, ctl);
340 break;
341 }
342 }
343
344 void
345 arspi_done(struct arspi_softc *sc, int err)
346 {
347 struct spi_transfer *st;
348 struct arspi_job *job;
349
350 if ((st = sc->sc_transfer) != NULL) {
351 job = st->st_busprivate;
352
353 if (job->job_flags & JOB_WAIT) {
354 if (err == 0) {
355 if ((GETREG(sc, ARSPI_REG_DATA) &
356 SPIFLASH_SR_BUSY) == 0) {
357 /* intermediate wait done */
358 job->job_flags &= ~JOB_WAIT;
359 goto done;
360 }
361 }
362 } else if (job->job_flags & JOB_WREN) {
363 if (err == 0) {
364 job->job_flags &= ~JOB_WREN;
365 goto done;
366 }
367 } else if (err == 0) {
368 /*
369 * When breaking up write jobs, we have to wait until
370 * the WIP bit is clear, and we have to separately
371 * send WREN for each chunk. These flags facilitate
372 * that.
373 */
374 if (job->job_flags & JOB_WRITE)
375 job->job_flags |= (JOB_WAIT | JOB_WREN);
376 job->job_data = GETREG(sc, ARSPI_REG_DATA);
377 arspi_finish_job(st);
378 }
379
380 if (err || (job->job_flags & JOB_LAST)) {
381 sc->sc_transfer = NULL;
382 st->st_busprivate = NULL;
383 spi_done(st, err);
384 free(job, M_DEVBUF);
385 }
386 }
387 done:
388 arspi_sched(sc);
389 }
390
391 int
392 arspi_get_byte(struct spi_chunk **chunkp, uint8_t *bytep)
393 {
394 struct spi_chunk *chunk;
395
396 chunk = *chunkp;
397
398 /* skip leading empty (or already consumed) chunks */
399 while (chunk && chunk->chunk_wresid == 0)
400 chunk = chunk->chunk_next;
401
402 if (chunk == NULL) {
403 return ENODATA;
404 }
405
406 /*
407 * chunk must be write only. SPI flash doesn't support
408 * any full duplex operations.
409 */
410 if ((chunk->chunk_rptr) || !(chunk->chunk_wptr)) {
411 return EINVAL;
412 }
413
414 *bytep = *chunk->chunk_wptr;
415 chunk->chunk_wptr++;
416 chunk->chunk_wresid--;
417 chunk->chunk_rresid--;
418 /* clearing wptr and rptr makes sanity checks later easier */
419 if (chunk->chunk_wresid == 0)
420 chunk->chunk_wptr = NULL;
421 if (chunk->chunk_rresid == 0)
422 chunk->chunk_rptr = NULL;
423 while (chunk && chunk->chunk_wresid == 0)
424 chunk = chunk->chunk_next;
425
426 *chunkp = chunk;
427 return 0;
428 }
429
430 int
431 arspi_put_byte(struct spi_chunk **chunkp, uint8_t byte)
432 {
433 struct spi_chunk *chunk;
434
435 chunk = *chunkp;
436
437 /* skip leading empty (or already consumed) chunks */
438 while (chunk && chunk->chunk_rresid == 0)
439 chunk = chunk->chunk_next;
440
441 if (chunk == NULL) {
442 return EOVERFLOW;
443 }
444
445 /*
446 * chunk must be read only. SPI flash doesn't support
447 * any full duplex operations.
448 */
449 if ((chunk->chunk_wptr) || !(chunk->chunk_rptr)) {
450 return EINVAL;
451 }
452
453 *chunk->chunk_rptr = byte;
454 chunk->chunk_rptr++;
455 chunk->chunk_wresid--; /* technically this was done at send time */
456 chunk->chunk_rresid--;
457 while (chunk && chunk->chunk_rresid == 0)
458 chunk = chunk->chunk_next;
459
460 *chunkp = chunk;
461 return 0;
462 }
463
464 int
465 arspi_make_job(struct spi_transfer *st)
466 {
467 struct arspi_job *job;
468 struct spi_chunk *chunk;
469 uint8_t byte;
470 int i, rv;
471
472 job = malloc(sizeof (struct arspi_job), M_DEVBUF, M_ZERO);
473 if (job == NULL) {
474 return ENOMEM;
475 }
476
477 st->st_busprivate = job;
478
479 /* skip any leading empty chunks (should not be any!) */
480 chunk = st->st_chunks;
481
482 /* get transfer opcode */
483 if ((rv = arspi_get_byte(&chunk, &byte)) != 0)
484 return rv;
485
486 job->job_opcode = byte;
487 switch (job->job_opcode) {
488 case SPIFLASH_CMD_WREN:
489 case SPIFLASH_CMD_WRDI:
490 case SPIFLASH_CMD_CHIPERASE:
491 break;
492 case SPIFLASH_CMD_RDJI:
493 job->job_rxcnt = 3;
494 break;
495 case SPIFLASH_CMD_RDSR:
496 job->job_rxcnt = 1;
497 break;
498 case SPIFLASH_CMD_WRSR:
499 /*
500 * is this in data, or in address? stick it in data
501 * for now.
502 */
503 job->job_txcnt = 1;
504 break;
505 case SPIFLASH_CMD_RDID:
506 job->job_addrcnt = 3; /* 3 dummy bytes */
507 job->job_rxcnt = 1;
508 break;
509 case SPIFLASH_CMD_ERASE:
510 job->job_addrcnt = 3;
511 break;
512 case SPIFLASH_CMD_READ:
513 job->job_addrcnt = 3;
514 job->job_flags |= JOB_READ;
515 break;
516 case SPIFLASH_CMD_PROGRAM:
517 job->job_addrcnt = 3;
518 job->job_flags |= JOB_WRITE;
519 break;
520 case SPIFLASH_CMD_READFAST:
521 /*
522 * This is a pain in the arse to support, so we will
523 * rewrite as an ordinary read. But later, after we
524 * obtain the address.
525 */
526 job->job_addrcnt = 3; /* 3 address */
527 job->job_flags |= JOB_READ;
528 break;
529 default:
530 return EINVAL;
531 }
532
533 for (i = 0; i < job->job_addrcnt; i++) {
534 if ((rv = arspi_get_byte(&chunk, &byte)) != 0)
535 return rv;
536 job->job_addr <<= 8;
537 job->job_addr |= byte;
538 }
539
540
541 if (job->job_opcode == SPIFLASH_CMD_READFAST) {
542 /* eat the dummy timing byte */
543 if ((rv = arspi_get_byte(&chunk, &byte)) != 0)
544 return rv;
545 /* rewrite this as a read */
546 job->job_opcode = SPIFLASH_CMD_READ;
547 }
548
549 job->job_chunk = chunk;
550
551 /*
552 * Now quickly check a few other things. Namely, we are not
553 * allowed to have both READ and WRITE.
554 */
555 for (chunk = job->job_chunk; chunk; chunk = chunk->chunk_next) {
556 if (chunk->chunk_wptr) {
557 job->job_wresid += chunk->chunk_wresid;
558 }
559 if (chunk->chunk_rptr) {
560 job->job_rresid += chunk->chunk_rresid;
561 }
562 }
563
564 if (job->job_rresid && job->job_wresid) {
565 return EINVAL;
566 }
567
568 return 0;
569 }
570
571 /*
572 * NB: The Atheros SPI controller runs in little endian mode. So all
573 * data accesses must be swapped appropriately.
574 *
575 * The controller auto-swaps read accesses done through the mapped memory
576 * region, but when using SPI directly, we have to do the right thing to
577 * swap to or from little endian.
578 */
579
580 void
581 arspi_update_job(struct spi_transfer *st)
582 {
583 struct arspi_job *job = st->st_busprivate;
584 uint8_t byte;
585 int i;
586
587 if (job->job_flags & (JOB_WAIT|JOB_WREN))
588 return;
589
590 job->job_rxcnt = 0;
591 job->job_txcnt = 0;
592 job->job_data = 0;
593
594 job->job_txcnt = uimin(job->job_wresid, 4);
595 job->job_rxcnt = uimin(job->job_rresid, 4);
596
597 job->job_wresid -= job->job_txcnt;
598 job->job_rresid -= job->job_rxcnt;
599
600 for (i = 0; i < job->job_txcnt; i++) {
601 arspi_get_byte(&job->job_chunk, &byte);
602 job->job_data |= (byte << (i * 8));
603 }
604
605 if ((!job->job_wresid) && (!job->job_rresid)) {
606 job->job_flags |= JOB_LAST;
607 }
608 }
609
610 void
611 arspi_finish_job(struct spi_transfer *st)
612 {
613 struct arspi_job *job = st->st_busprivate;
614 uint8_t byte;
615 int i;
616
617 job->job_addr += job->job_rxcnt;
618 job->job_addr += job->job_txcnt;
619 for (i = 0; i < job->job_rxcnt; i++) {
620 byte = job->job_data & 0xff;
621 job->job_data >>= 8;
622 arspi_put_byte(&job->job_chunk, byte);
623 }
624 }
625
626