arspi.c revision 1.12 1 /* $NetBSD: arspi.c,v 1.12 2019/08/13 17:03:11 tnn 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.12 2019/08/13 17:03:11 tnn 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 memset(&sba, 0, sizeof(sba));
195 sba.sba_controller = &sc->sc_spi;
196 (void) config_found_ia(self, "spibus", &sba, spibus_print);
197 }
198
199 void
200 arspi_interrupts(device_t self)
201 {
202 /*
203 * we never leave polling mode, because, apparently, we
204 * are missing some data about how to drive the SPI in interrupt
205 * mode.
206 */
207 #if 0
208 struct arspi_softc *sc = device_private(self);
209 int s;
210
211 s = splbio();
212 sc->sc_interrupts = true;
213 splx(s);
214 #endif
215 }
216
217 int
218 arspi_intr(void *arg)
219 {
220 struct arspi_softc *sc = arg;
221
222 while (GETREG(sc, ARSPI_REG_CTL) & ARSPI_CTL_BUSY);
223
224 arspi_done(sc, 0);
225
226 return 1;
227 }
228
229 void
230 arspi_poll(struct arspi_softc *sc)
231 {
232
233 while (sc->sc_transfer) {
234 arspi_intr(sc);
235 }
236 }
237
238 int
239 arspi_configure(void *cookie, int slave, int mode, int speed)
240 {
241
242 /*
243 * We don't support the full SPI protocol, and hopefully the
244 * firmware has programmed a reasonable mode already. So
245 * just a couple of quick sanity checks, then bail.
246 */
247 if ((mode != 0) || (slave != 0))
248 return EINVAL;
249
250 return 0;
251 }
252
253 int
254 arspi_transfer(void *cookie, struct spi_transfer *st)
255 {
256 struct arspi_softc *sc = cookie;
257 int rv;
258 int s;
259
260 st->st_busprivate = NULL;
261 if ((rv = arspi_make_job(st)) != 0) {
262 if (st->st_busprivate) {
263 free(st->st_busprivate, M_DEVBUF);
264 st->st_busprivate = NULL;
265 }
266 spi_done(st, rv);
267 return rv;
268 }
269
270 s = splbio();
271 spi_transq_enqueue(&sc->sc_transq, st);
272 if (sc->sc_transfer == NULL) {
273 arspi_sched(sc);
274 if (!sc->sc_interrupts)
275 arspi_poll(sc);
276 }
277 splx(s);
278 return 0;
279 }
280
281 void
282 arspi_sched(struct arspi_softc *sc)
283 {
284 struct spi_transfer *st;
285 struct arspi_job *job;
286 uint32_t ctl, cnt;
287
288 for (;;) {
289 if ((st = sc->sc_transfer) == NULL) {
290 if ((st = spi_transq_first(&sc->sc_transq)) == NULL) {
291 /* no work left to do */
292 break;
293 }
294 spi_transq_dequeue(&sc->sc_transq);
295 sc->sc_transfer = st;
296 }
297
298 arspi_update_job(st);
299 job = st->st_busprivate;
300
301 /* there shouldn't be anything running, but ensure it */
302 do {
303 ctl = GETREG(sc, ARSPI_REG_CTL);
304 } while (ctl & ARSPI_CTL_BUSY);
305 /* clear all of the tx and rx bits */
306 ctl &= ~(ARSPI_CTL_TXCNT_MASK | ARSPI_CTL_RXCNT_MASK);
307
308 if (job->job_flags & JOB_WAIT) {
309 PUTREG(sc, ARSPI_REG_OPCODE, SPIFLASH_CMD_RDSR);
310 /* only the opcode for tx */
311 ctl |= (1 << ARSPI_CTL_TXCNT_SHIFT);
312 /* and one rx byte */
313 ctl |= (1 << ARSPI_CTL_RXCNT_SHIFT);
314 } else if (job->job_flags & JOB_WREN) {
315 PUTREG(sc, ARSPI_REG_OPCODE, SPIFLASH_CMD_WREN);
316 /* just the opcode */
317 ctl |= (1 << ARSPI_CTL_TXCNT_SHIFT);
318 /* no rx bytes */
319 } else {
320 /* set the data */
321 PUTREG(sc, ARSPI_REG_DATA, job->job_data);
322
323 /* set the opcode and the address */
324 PUTREG(sc, ARSPI_REG_OPCODE, job->job_opcode |
325 (job->job_addr << 8));
326
327 /* now set txcnt */
328 cnt = 1; /* opcode */
329 cnt += job->job_addrcnt + job->job_txcnt;
330 ctl |= (cnt << ARSPI_CTL_TXCNT_SHIFT);
331
332 /* now set rxcnt */
333 cnt = job->job_rxcnt;
334 ctl |= (cnt << ARSPI_CTL_RXCNT_SHIFT);
335 }
336
337 /* set the start bit */
338 ctl |= ARSPI_CTL_START;
339
340 PUTREG(sc, ARSPI_REG_CTL, ctl);
341 break;
342 }
343 }
344
345 void
346 arspi_done(struct arspi_softc *sc, int err)
347 {
348 struct spi_transfer *st;
349 struct arspi_job *job;
350
351 if ((st = sc->sc_transfer) != NULL) {
352 job = st->st_busprivate;
353
354 if (job->job_flags & JOB_WAIT) {
355 if (err == 0) {
356 if ((GETREG(sc, ARSPI_REG_DATA) &
357 SPIFLASH_SR_BUSY) == 0) {
358 /* intermediate wait done */
359 job->job_flags &= ~JOB_WAIT;
360 goto done;
361 }
362 }
363 } else if (job->job_flags & JOB_WREN) {
364 if (err == 0) {
365 job->job_flags &= ~JOB_WREN;
366 goto done;
367 }
368 } else if (err == 0) {
369 /*
370 * When breaking up write jobs, we have to wait until
371 * the WIP bit is clear, and we have to separately
372 * send WREN for each chunk. These flags facilitate
373 * that.
374 */
375 if (job->job_flags & JOB_WRITE)
376 job->job_flags |= (JOB_WAIT | JOB_WREN);
377 job->job_data = GETREG(sc, ARSPI_REG_DATA);
378 arspi_finish_job(st);
379 }
380
381 if (err || (job->job_flags & JOB_LAST)) {
382 sc->sc_transfer = NULL;
383 st->st_busprivate = NULL;
384 spi_done(st, err);
385 free(job, M_DEVBUF);
386 }
387 }
388 done:
389 arspi_sched(sc);
390 }
391
392 int
393 arspi_get_byte(struct spi_chunk **chunkp, uint8_t *bytep)
394 {
395 struct spi_chunk *chunk;
396
397 chunk = *chunkp;
398
399 /* skip leading empty (or already consumed) chunks */
400 while (chunk && chunk->chunk_wresid == 0)
401 chunk = chunk->chunk_next;
402
403 if (chunk == NULL) {
404 return ENODATA;
405 }
406
407 /*
408 * chunk must be write only. SPI flash doesn't support
409 * any full duplex operations.
410 */
411 if ((chunk->chunk_rptr) || !(chunk->chunk_wptr)) {
412 return EINVAL;
413 }
414
415 *bytep = *chunk->chunk_wptr;
416 chunk->chunk_wptr++;
417 chunk->chunk_wresid--;
418 chunk->chunk_rresid--;
419 /* clearing wptr and rptr makes sanity checks later easier */
420 if (chunk->chunk_wresid == 0)
421 chunk->chunk_wptr = NULL;
422 if (chunk->chunk_rresid == 0)
423 chunk->chunk_rptr = NULL;
424 while (chunk && chunk->chunk_wresid == 0)
425 chunk = chunk->chunk_next;
426
427 *chunkp = chunk;
428 return 0;
429 }
430
431 int
432 arspi_put_byte(struct spi_chunk **chunkp, uint8_t byte)
433 {
434 struct spi_chunk *chunk;
435
436 chunk = *chunkp;
437
438 /* skip leading empty (or already consumed) chunks */
439 while (chunk && chunk->chunk_rresid == 0)
440 chunk = chunk->chunk_next;
441
442 if (chunk == NULL) {
443 return EOVERFLOW;
444 }
445
446 /*
447 * chunk must be read only. SPI flash doesn't support
448 * any full duplex operations.
449 */
450 if ((chunk->chunk_wptr) || !(chunk->chunk_rptr)) {
451 return EINVAL;
452 }
453
454 *chunk->chunk_rptr = byte;
455 chunk->chunk_rptr++;
456 chunk->chunk_wresid--; /* technically this was done at send time */
457 chunk->chunk_rresid--;
458 while (chunk && chunk->chunk_rresid == 0)
459 chunk = chunk->chunk_next;
460
461 *chunkp = chunk;
462 return 0;
463 }
464
465 int
466 arspi_make_job(struct spi_transfer *st)
467 {
468 struct arspi_job *job;
469 struct spi_chunk *chunk;
470 uint8_t byte;
471 int i, rv;
472
473 job = malloc(sizeof (struct arspi_job), M_DEVBUF, M_ZERO);
474 if (job == NULL) {
475 return ENOMEM;
476 }
477
478 st->st_busprivate = job;
479
480 /* skip any leading empty chunks (should not be any!) */
481 chunk = st->st_chunks;
482
483 /* get transfer opcode */
484 if ((rv = arspi_get_byte(&chunk, &byte)) != 0)
485 return rv;
486
487 job->job_opcode = byte;
488 switch (job->job_opcode) {
489 case SPIFLASH_CMD_WREN:
490 case SPIFLASH_CMD_WRDI:
491 case SPIFLASH_CMD_CHIPERASE:
492 break;
493 case SPIFLASH_CMD_RDJI:
494 job->job_rxcnt = 3;
495 break;
496 case SPIFLASH_CMD_RDSR:
497 job->job_rxcnt = 1;
498 break;
499 case SPIFLASH_CMD_WRSR:
500 /*
501 * is this in data, or in address? stick it in data
502 * for now.
503 */
504 job->job_txcnt = 1;
505 break;
506 case SPIFLASH_CMD_RDID:
507 job->job_addrcnt = 3; /* 3 dummy bytes */
508 job->job_rxcnt = 1;
509 break;
510 case SPIFLASH_CMD_ERASE:
511 job->job_addrcnt = 3;
512 break;
513 case SPIFLASH_CMD_READ:
514 job->job_addrcnt = 3;
515 job->job_flags |= JOB_READ;
516 break;
517 case SPIFLASH_CMD_PROGRAM:
518 job->job_addrcnt = 3;
519 job->job_flags |= JOB_WRITE;
520 break;
521 case SPIFLASH_CMD_READFAST:
522 /*
523 * This is a pain in the arse to support, so we will
524 * rewrite as an ordinary read. But later, after we
525 * obtain the address.
526 */
527 job->job_addrcnt = 3; /* 3 address */
528 job->job_flags |= JOB_READ;
529 break;
530 default:
531 return EINVAL;
532 }
533
534 for (i = 0; i < job->job_addrcnt; i++) {
535 if ((rv = arspi_get_byte(&chunk, &byte)) != 0)
536 return rv;
537 job->job_addr <<= 8;
538 job->job_addr |= byte;
539 }
540
541
542 if (job->job_opcode == SPIFLASH_CMD_READFAST) {
543 /* eat the dummy timing byte */
544 if ((rv = arspi_get_byte(&chunk, &byte)) != 0)
545 return rv;
546 /* rewrite this as a read */
547 job->job_opcode = SPIFLASH_CMD_READ;
548 }
549
550 job->job_chunk = chunk;
551
552 /*
553 * Now quickly check a few other things. Namely, we are not
554 * allowed to have both READ and WRITE.
555 */
556 for (chunk = job->job_chunk; chunk; chunk = chunk->chunk_next) {
557 if (chunk->chunk_wptr) {
558 job->job_wresid += chunk->chunk_wresid;
559 }
560 if (chunk->chunk_rptr) {
561 job->job_rresid += chunk->chunk_rresid;
562 }
563 }
564
565 if (job->job_rresid && job->job_wresid) {
566 return EINVAL;
567 }
568
569 return 0;
570 }
571
572 /*
573 * NB: The Atheros SPI controller runs in little endian mode. So all
574 * data accesses must be swapped appropriately.
575 *
576 * The controller auto-swaps read accesses done through the mapped memory
577 * region, but when using SPI directly, we have to do the right thing to
578 * swap to or from little endian.
579 */
580
581 void
582 arspi_update_job(struct spi_transfer *st)
583 {
584 struct arspi_job *job = st->st_busprivate;
585 uint8_t byte;
586 int i;
587
588 if (job->job_flags & (JOB_WAIT|JOB_WREN))
589 return;
590
591 job->job_rxcnt = 0;
592 job->job_txcnt = 0;
593 job->job_data = 0;
594
595 job->job_txcnt = uimin(job->job_wresid, 4);
596 job->job_rxcnt = uimin(job->job_rresid, 4);
597
598 job->job_wresid -= job->job_txcnt;
599 job->job_rresid -= job->job_rxcnt;
600
601 for (i = 0; i < job->job_txcnt; i++) {
602 arspi_get_byte(&job->job_chunk, &byte);
603 job->job_data |= (byte << (i * 8));
604 }
605
606 if ((!job->job_wresid) && (!job->job_rresid)) {
607 job->job_flags |= JOB_LAST;
608 }
609 }
610
611 void
612 arspi_finish_job(struct spi_transfer *st)
613 {
614 struct arspi_job *job = st->st_busprivate;
615 uint8_t byte;
616 int i;
617
618 job->job_addr += job->job_rxcnt;
619 job->job_addr += job->job_txcnt;
620 for (i = 0; i < job->job_rxcnt; i++) {
621 byte = job->job_data & 0xff;
622 job->job_data >>= 8;
623 arspi_put_byte(&job->job_chunk, byte);
624 }
625 }
626
627