]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm/mv/a37x0_spi.c
THIS BRANCH IS OBSOLETE, PLEASE READ:
[FreeBSD/FreeBSD.git] / sys / arm / mv / a37x0_spi.c
1 /*-
2  * Copyright (c) 2018, 2019 Rubicon Communications, LLC (Netgate)
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  *
24  */
25
26 #include <sys/cdefs.h>
27 __FBSDID("$FreeBSD$");
28
29 #include <sys/param.h>
30 #include <sys/systm.h>
31 #include <sys/bus.h>
32 #include <sys/kernel.h>
33 #include <sys/module.h>
34 #include <sys/mutex.h>
35 #include <sys/rman.h>
36
37 #include <machine/bus.h>
38 #include <machine/resource.h>
39 #include <machine/intr.h>
40
41 #include <dev/ofw/ofw_bus.h>
42 #include <dev/ofw/ofw_bus_subr.h>
43 #include <dev/spibus/spi.h>
44 #include <dev/spibus/spibusvar.h>
45
46 #include "spibus_if.h"
47
48 struct a37x0_spi_softc {
49         device_t                sc_dev;
50         struct mtx              sc_mtx;
51         struct resource         *sc_mem_res;
52         struct resource         *sc_irq_res;
53         struct spi_command      *sc_cmd;
54         bus_space_tag_t         sc_bst;
55         bus_space_handle_t      sc_bsh;
56         uint32_t                sc_len;
57         uint32_t                sc_maxfreq;
58         uint32_t                sc_read;
59         uint32_t                sc_flags;
60         uint32_t                sc_written;
61         void                    *sc_intrhand;
62 };
63
64 #define A37X0_SPI_WRITE(_sc, _off, _val)                \
65     bus_space_write_4((_sc)->sc_bst, (_sc)->sc_bsh, (_off), (_val))
66 #define A37X0_SPI_READ(_sc, _off)                       \
67     bus_space_read_4((_sc)->sc_bst, (_sc)->sc_bsh, (_off))
68 #define A37X0_SPI_LOCK(_sc)     mtx_lock(&(_sc)->sc_mtx)
69 #define A37X0_SPI_UNLOCK(_sc)   mtx_unlock(&(_sc)->sc_mtx)
70
71 #define A37X0_SPI_BUSY                  (1 << 0)
72 /*
73  * While the A3700 utils from Marvell usually sets the QSF clock to 200MHz,
74  * there is no guarantee that it is correct without the proper clock framework
75  * to retrieve the actual TBG and PLL settings.
76  */
77 #define A37X0_SPI_CLOCK                 200000000       /* QSF Clock 200MHz */
78
79 #define A37X0_SPI_CONTROL               0x0
80 #define  A37X0_SPI_CS_SHIFT             16
81 #define  A37X0_SPI_CS_MASK              (0xf << A37X0_SPI_CS_SHIFT)
82 #define A37X0_SPI_CONF                  0x4
83 #define  A37X0_SPI_WFIFO_THRS_SHIFT     28
84 #define  A37X0_SPI_RFIFO_THRS_SHIFT     24
85 #define  A37X0_SPI_AUTO_CS_EN           (1 << 20)
86 #define  A37X0_SPI_DMA_WR_EN            (1 << 19)
87 #define  A37X0_SPI_DMA_RD_EN            (1 << 18)
88 #define  A37X0_SPI_FIFO_MODE            (1 << 17)
89 #define  A37X0_SPI_SRST                 (1 << 16)
90 #define  A37X0_SPI_XFER_START           (1 << 15)
91 #define  A37X0_SPI_XFER_STOP            (1 << 14)
92 #define  A37X0_SPI_INSTR_PIN            (1 << 13)
93 #define  A37X0_SPI_ADDR_PIN             (1 << 12)
94 #define  A37X0_SPI_DATA_PIN_MASK        0x3
95 #define  A37X0_SPI_DATA_PIN_SHIFT       10
96 #define  A37X0_SPI_FIFO_FLUSH           (1 << 9)
97 #define  A37X0_SPI_RW_EN                (1 << 8)
98 #define  A37X0_SPI_CLK_POL              (1 << 7)
99 #define  A37X0_SPI_CLK_PHASE            (1 << 6)
100 #define  A37X0_SPI_BYTE_LEN             (1 << 5)
101 #define  A37X0_SPI_PSC_MASK             0x1f
102 #define A37X0_SPI_DATA_OUT              0x8
103 #define A37X0_SPI_DATA_IN               0xc
104 #define A37X0_SPI_INTR_STAT             0x28
105 #define A37X0_SPI_INTR_MASK             0x2c
106 #define  A37X0_SPI_RDY                  (1 << 1)
107 #define  A37X0_SPI_XFER_DONE            (1 << 0)
108
109 static struct ofw_compat_data compat_data[] = {
110         { "marvell,armada-3700-spi",    1 },
111         { NULL, 0 }
112 };
113
114 static void a37x0_spi_intr(void *);
115
116 static int
117 a37x0_spi_wait(struct a37x0_spi_softc *sc, int timeout, uint32_t reg,
118     uint32_t mask)
119 {
120         int i;
121
122         for (i = 0; i < timeout; i++) {
123                 if ((A37X0_SPI_READ(sc, reg) & mask) == 0)
124                         return (0);
125                 DELAY(100);
126         }
127
128         return (ETIMEDOUT);
129 }
130
131 static int
132 a37x0_spi_probe(device_t dev)
133 {
134
135         if (!ofw_bus_status_okay(dev))
136                 return (ENXIO);
137         if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
138                 return (ENXIO);
139         device_set_desc(dev, "Armada 37x0 SPI controller");
140
141         return (BUS_PROBE_DEFAULT);
142 }
143
144 static int
145 a37x0_spi_attach(device_t dev)
146 {
147         int err, rid;
148         pcell_t maxfreq;
149         struct a37x0_spi_softc *sc;
150         uint32_t reg;
151
152         sc = device_get_softc(dev);
153         sc->sc_dev = dev;
154
155         rid = 0;
156         sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
157             RF_ACTIVE);
158         if (!sc->sc_mem_res) {
159                 device_printf(dev, "cannot allocate memory window\n");
160                 return (ENXIO);
161         }
162
163         sc->sc_bst = rman_get_bustag(sc->sc_mem_res);
164         sc->sc_bsh = rman_get_bushandle(sc->sc_mem_res);
165
166         rid = 0;
167         sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
168             RF_ACTIVE);
169         if (!sc->sc_irq_res) {
170                 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
171                 device_printf(dev, "cannot allocate interrupt\n");
172                 return (ENXIO);
173         }
174
175         /* Make sure that no CS is asserted. */
176         reg = A37X0_SPI_READ(sc, A37X0_SPI_CONTROL);
177         A37X0_SPI_WRITE(sc, A37X0_SPI_CONTROL, reg & ~A37X0_SPI_CS_MASK);
178
179         /* Reset FIFO. */
180         reg = A37X0_SPI_READ(sc, A37X0_SPI_CONF);
181         A37X0_SPI_WRITE(sc, A37X0_SPI_CONF, reg | A37X0_SPI_FIFO_FLUSH);
182         err = a37x0_spi_wait(sc, 20, A37X0_SPI_CONF, A37X0_SPI_FIFO_FLUSH);
183         if (err != 0) {
184                 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
185                 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
186                 device_printf(dev, "cannot flush the controller fifo.\n");
187                 return (ENXIO);
188         }
189
190         /* Reset the Controller. */
191         reg = A37X0_SPI_READ(sc, A37X0_SPI_CONF);
192         A37X0_SPI_WRITE(sc, A37X0_SPI_CONF, reg | A37X0_SPI_SRST);
193         DELAY(1000);
194         /* Enable the single byte IO, disable FIFO. */
195         reg &= ~(A37X0_SPI_FIFO_MODE | A37X0_SPI_BYTE_LEN);
196         A37X0_SPI_WRITE(sc, A37X0_SPI_CONF, reg);
197
198         /* Disable and clear interrupts. */
199         A37X0_SPI_WRITE(sc, A37X0_SPI_INTR_MASK, 0);
200         reg = A37X0_SPI_READ(sc, A37X0_SPI_INTR_STAT);
201         A37X0_SPI_WRITE(sc, A37X0_SPI_INTR_STAT, reg);
202
203         /* Hook up our interrupt handler. */
204         if (bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
205             NULL, a37x0_spi_intr, sc, &sc->sc_intrhand)) {
206                 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
207                 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
208                 device_printf(dev, "cannot setup the interrupt handler\n");
209                 return (ENXIO);
210         }
211
212         mtx_init(&sc->sc_mtx, "a37x0_spi", NULL, MTX_DEF);
213
214         /* Read the controller max-frequency. */
215         if (OF_getencprop(ofw_bus_get_node(dev), "spi-max-frequency", &maxfreq,
216             sizeof(maxfreq)) == -1)
217                 maxfreq = 0;
218         sc->sc_maxfreq = maxfreq;
219
220         device_add_child(dev, "spibus", -1);
221
222         /* Probe and attach the spibus when interrupts are available. */
223         return (bus_delayed_attach_children(dev));
224 }
225
226 static int
227 a37x0_spi_detach(device_t dev)
228 {
229         int err;
230         struct a37x0_spi_softc *sc;
231
232         if ((err = device_delete_children(dev)) != 0)
233                 return (err);
234         sc = device_get_softc(dev);
235         mtx_destroy(&sc->sc_mtx);
236         if (sc->sc_intrhand)
237                 bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intrhand);
238         if (sc->sc_irq_res)
239                 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
240         if (sc->sc_mem_res)
241                 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
242
243         return (0);
244 }
245
246 static __inline void
247 a37x0_spi_rx_byte(struct a37x0_spi_softc *sc)
248 {
249         struct spi_command *cmd;
250         uint32_t read;
251         uint8_t *p;
252
253         if (sc->sc_read == sc->sc_len)
254                 return;
255         cmd = sc->sc_cmd;
256         p = (uint8_t *)cmd->rx_cmd;
257         read = sc->sc_read++;
258         if (read >= cmd->rx_cmd_sz) {
259                 p = (uint8_t *)cmd->rx_data;
260                 read -= cmd->rx_cmd_sz;
261         }
262         p[read] = A37X0_SPI_READ(sc, A37X0_SPI_DATA_IN) & 0xff;
263 }
264
265 static __inline void
266 a37x0_spi_tx_byte(struct a37x0_spi_softc *sc)
267 {
268         struct spi_command *cmd;
269         uint32_t written;
270         uint8_t *p;
271
272         if (sc->sc_written == sc->sc_len)
273                 return;
274         cmd = sc->sc_cmd;
275         p = (uint8_t *)cmd->tx_cmd;
276         written = sc->sc_written++;
277         if (written >= cmd->tx_cmd_sz) {
278                 p = (uint8_t *)cmd->tx_data;
279                 written -= cmd->tx_cmd_sz;
280         }
281         A37X0_SPI_WRITE(sc, A37X0_SPI_DATA_OUT, p[written]);
282 }
283
284 static __inline void
285 a37x0_spi_set_clock(struct a37x0_spi_softc *sc, uint32_t clock)
286 {
287         uint32_t psc, reg;
288
289         if (sc->sc_maxfreq > 0 && clock > sc->sc_maxfreq)
290                 clock = sc->sc_maxfreq;
291         psc = A37X0_SPI_CLOCK / clock;
292         if ((A37X0_SPI_CLOCK % clock) > 0)
293                 psc++;
294         reg = A37X0_SPI_READ(sc, A37X0_SPI_CONF);
295         reg &= ~A37X0_SPI_PSC_MASK;
296         reg |= psc & A37X0_SPI_PSC_MASK;
297         A37X0_SPI_WRITE(sc, A37X0_SPI_CONF, reg);
298 }
299
300 static __inline void
301 a37x0_spi_set_pins(struct a37x0_spi_softc *sc, uint32_t npins)
302 {
303         uint32_t reg;
304
305         /* Sets single, dual or quad SPI mode. */
306         reg = A37X0_SPI_READ(sc, A37X0_SPI_CONF);
307         reg &= ~(A37X0_SPI_DATA_PIN_MASK << A37X0_SPI_DATA_PIN_SHIFT);
308         reg |= (npins / 2) << A37X0_SPI_DATA_PIN_SHIFT;
309         reg |= A37X0_SPI_INSTR_PIN | A37X0_SPI_ADDR_PIN;
310         A37X0_SPI_WRITE(sc, A37X0_SPI_CONF, reg);
311 }
312
313 static __inline void
314 a37x0_spi_set_mode(struct a37x0_spi_softc *sc, uint32_t mode)
315 {
316         uint32_t reg;
317
318         reg = A37X0_SPI_READ(sc, A37X0_SPI_CONF);
319         switch (mode) {
320         case 0:
321                 reg &= ~(A37X0_SPI_CLK_PHASE | A37X0_SPI_CLK_POL);
322                 break;
323         case 1:
324                 reg &= ~A37X0_SPI_CLK_POL;
325                 reg |= A37X0_SPI_CLK_PHASE;
326                 break;
327         case 2:
328                 reg &= ~A37X0_SPI_CLK_PHASE;
329                 reg |= A37X0_SPI_CLK_POL;
330                 break;
331         case 3:
332                 reg |= (A37X0_SPI_CLK_PHASE | A37X0_SPI_CLK_POL);
333                 break;
334         }
335         A37X0_SPI_WRITE(sc, A37X0_SPI_CONF, reg);
336 }
337
338 static void
339 a37x0_spi_intr(void *arg)
340 {
341         struct a37x0_spi_softc *sc;
342         uint32_t status;
343
344         sc = (struct a37x0_spi_softc *)arg;
345         A37X0_SPI_LOCK(sc);
346
347         /* Filter stray interrupts. */
348         if ((sc->sc_flags & A37X0_SPI_BUSY) == 0) {
349                 A37X0_SPI_UNLOCK(sc);
350                 return;
351         }
352
353         status = A37X0_SPI_READ(sc, A37X0_SPI_INTR_STAT);
354         if (status & A37X0_SPI_XFER_DONE)
355                 a37x0_spi_rx_byte(sc);
356
357         /* Clear the interrupt status. */
358         A37X0_SPI_WRITE(sc, A37X0_SPI_INTR_STAT, status);
359
360         /* Check for end of transfer. */
361         if (sc->sc_written == sc->sc_len && sc->sc_read == sc->sc_len)
362                 wakeup(sc->sc_dev);
363         else
364                 a37x0_spi_tx_byte(sc);
365
366         A37X0_SPI_UNLOCK(sc);
367 }
368
369 static int
370 a37x0_spi_transfer(device_t dev, device_t child, struct spi_command *cmd)
371 {
372         int timeout;
373         struct a37x0_spi_softc *sc;
374         uint32_t clock, cs, mode, reg;
375
376         KASSERT(cmd->tx_cmd_sz == cmd->rx_cmd_sz,
377             ("TX/RX command sizes should be equal"));
378         KASSERT(cmd->tx_data_sz == cmd->rx_data_sz,
379             ("TX/RX data sizes should be equal"));
380
381         /* Get the proper data for this child. */
382         spibus_get_cs(child, &cs);
383         cs &= ~SPIBUS_CS_HIGH;
384         if (cs > 3) {
385                 device_printf(dev,
386                     "Invalid CS %d requested by %s\n", cs,
387                     device_get_nameunit(child));
388                 return (EINVAL);
389         }
390         spibus_get_clock(child, &clock);
391         if (clock == 0) {
392                 device_printf(dev,
393                     "Invalid clock %uHz requested by %s\n", clock,
394                     device_get_nameunit(child));
395                 return (EINVAL);
396         }
397         spibus_get_mode(child, &mode);
398         if (mode > 3) {
399                 device_printf(dev,
400                     "Invalid mode %u requested by %s\n", mode,
401                     device_get_nameunit(child));
402                 return (EINVAL);
403         }
404
405         sc = device_get_softc(dev);
406         A37X0_SPI_LOCK(sc);
407
408         /* Wait until the controller is free. */
409         while (sc->sc_flags & A37X0_SPI_BUSY)
410                 mtx_sleep(dev, &sc->sc_mtx, 0, "a37x0_spi", 0);
411
412         /* Now we have control over SPI controller. */
413         sc->sc_flags = A37X0_SPI_BUSY;
414
415         /* Set transfer mode and clock. */
416         a37x0_spi_set_mode(sc, mode);
417         a37x0_spi_set_pins(sc, 1);
418         a37x0_spi_set_clock(sc, clock);
419
420         /* Set CS. */
421         A37X0_SPI_WRITE(sc, A37X0_SPI_CONTROL, 1 << (A37X0_SPI_CS_SHIFT + cs));
422
423         /* Save a pointer to the SPI command. */
424         sc->sc_cmd = cmd;
425         sc->sc_read = 0;
426         sc->sc_written = 0;
427         sc->sc_len = cmd->tx_cmd_sz + cmd->tx_data_sz;
428
429         /* Clear interrupts. */
430         reg = A37X0_SPI_READ(sc, A37X0_SPI_INTR_STAT);
431         A37X0_SPI_WRITE(sc, A37X0_SPI_INTR_STAT, reg);
432
433         while ((sc->sc_len - sc->sc_written) > 0) {
434                 /*
435                  * Write to start the transmission and read the byte
436                  * back when ready.
437                  */
438                 a37x0_spi_tx_byte(sc);
439                 timeout = 1000;
440                 while (--timeout > 0) {
441                         reg = A37X0_SPI_READ(sc, A37X0_SPI_CONTROL);
442                         if (reg & A37X0_SPI_XFER_DONE)
443                                 break;
444                         DELAY(1);
445                 }
446                 if (timeout == 0)
447                         break;
448                 a37x0_spi_rx_byte(sc);
449         }
450
451         /* Stop the controller. */
452         reg = A37X0_SPI_READ(sc, A37X0_SPI_CONTROL);
453         A37X0_SPI_WRITE(sc, A37X0_SPI_CONTROL, reg & ~A37X0_SPI_CS_MASK);
454         A37X0_SPI_WRITE(sc, A37X0_SPI_INTR_MASK, 0);
455
456         /* Release the controller and wakeup the next thread waiting for it. */
457         sc->sc_flags = 0;
458         wakeup_one(dev);
459         A37X0_SPI_UNLOCK(sc);
460
461         return ((timeout == 0) ? EIO : 0);
462 }
463
464 static phandle_t
465 a37x0_spi_get_node(device_t bus, device_t dev)
466 {
467
468         return (ofw_bus_get_node(bus));
469 }
470
471 static device_method_t a37x0_spi_methods[] = {
472         /* Device interface */
473         DEVMETHOD(device_probe,         a37x0_spi_probe),
474         DEVMETHOD(device_attach,        a37x0_spi_attach),
475         DEVMETHOD(device_detach,        a37x0_spi_detach),
476
477         /* SPI interface */
478         DEVMETHOD(spibus_transfer,      a37x0_spi_transfer),
479
480         /* ofw_bus interface */
481         DEVMETHOD(ofw_bus_get_node,     a37x0_spi_get_node),
482
483         DEVMETHOD_END
484 };
485
486 static devclass_t a37x0_spi_devclass;
487
488 static driver_t a37x0_spi_driver = {
489         "spi",
490         a37x0_spi_methods,
491         sizeof(struct a37x0_spi_softc),
492 };
493
494 DRIVER_MODULE(a37x0_spi, simplebus, a37x0_spi_driver, a37x0_spi_devclass, 0, 0);