]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm/mv/a37x0_spi.c
Create new wrapper function: bus_delayed_attach_children()
[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         bus_delayed_attach_children(dev);
224
225         return (0);
226 }
227
228 static int
229 a37x0_spi_detach(device_t dev)
230 {
231         int err;
232         struct a37x0_spi_softc *sc;
233
234         if ((err = device_delete_children(dev)) != 0)
235                 return (err);
236         sc = device_get_softc(dev);
237         mtx_destroy(&sc->sc_mtx);
238         if (sc->sc_intrhand)
239                 bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intrhand);
240         if (sc->sc_irq_res)
241                 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
242         if (sc->sc_mem_res)
243                 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
244
245         return (0);
246 }
247
248 static __inline void
249 a37x0_spi_rx_byte(struct a37x0_spi_softc *sc)
250 {
251         struct spi_command *cmd;
252         uint32_t read;
253         uint8_t *p;
254
255         if (sc->sc_read == sc->sc_len)
256                 return;
257         cmd = sc->sc_cmd;
258         p = (uint8_t *)cmd->rx_cmd;
259         read = sc->sc_read++;
260         if (read >= cmd->rx_cmd_sz) {
261                 p = (uint8_t *)cmd->rx_data;
262                 read -= cmd->rx_cmd_sz;
263         }
264         p[read] = A37X0_SPI_READ(sc, A37X0_SPI_DATA_IN) & 0xff;
265 }
266
267 static __inline void
268 a37x0_spi_tx_byte(struct a37x0_spi_softc *sc)
269 {
270         struct spi_command *cmd;
271         uint32_t written;
272         uint8_t *p;
273
274         if (sc->sc_written == sc->sc_len)
275                 return;
276         cmd = sc->sc_cmd;
277         p = (uint8_t *)cmd->tx_cmd;
278         written = sc->sc_written++;
279         if (written >= cmd->tx_cmd_sz) {
280                 p = (uint8_t *)cmd->tx_data;
281                 written -= cmd->tx_cmd_sz;
282         }
283         A37X0_SPI_WRITE(sc, A37X0_SPI_DATA_OUT, p[written]);
284 }
285
286 static __inline void
287 a37x0_spi_set_clock(struct a37x0_spi_softc *sc, uint32_t clock)
288 {
289         uint32_t psc, reg;
290
291         if (sc->sc_maxfreq > 0 && clock > sc->sc_maxfreq)
292                 clock = sc->sc_maxfreq;
293         psc = A37X0_SPI_CLOCK / clock;
294         if ((A37X0_SPI_CLOCK % clock) > 0)
295                 psc++;
296         reg = A37X0_SPI_READ(sc, A37X0_SPI_CONF);
297         reg &= ~A37X0_SPI_PSC_MASK;
298         reg |= psc & A37X0_SPI_PSC_MASK;
299         A37X0_SPI_WRITE(sc, A37X0_SPI_CONF, reg);
300 }
301
302 static __inline void
303 a37x0_spi_set_pins(struct a37x0_spi_softc *sc, uint32_t npins)
304 {
305         uint32_t reg;
306
307         /* Sets single, dual or quad SPI mode. */
308         reg = A37X0_SPI_READ(sc, A37X0_SPI_CONF);
309         reg &= ~(A37X0_SPI_DATA_PIN_MASK << A37X0_SPI_DATA_PIN_SHIFT);
310         reg |= (npins / 2) << A37X0_SPI_DATA_PIN_SHIFT;
311         reg |= A37X0_SPI_INSTR_PIN | A37X0_SPI_ADDR_PIN;
312         A37X0_SPI_WRITE(sc, A37X0_SPI_CONF, reg);
313 }
314
315 static __inline void
316 a37x0_spi_set_mode(struct a37x0_spi_softc *sc, uint32_t mode)
317 {
318         uint32_t reg;
319
320         reg = A37X0_SPI_READ(sc, A37X0_SPI_CONF);
321         switch (mode) {
322         case 0:
323                 reg &= ~(A37X0_SPI_CLK_PHASE | A37X0_SPI_CLK_POL);
324                 break;
325         case 1:
326                 reg &= ~A37X0_SPI_CLK_POL;
327                 reg |= A37X0_SPI_CLK_PHASE;
328                 break;
329         case 2:
330                 reg &= ~A37X0_SPI_CLK_PHASE;
331                 reg |= A37X0_SPI_CLK_POL;
332                 break;
333         case 3:
334                 reg |= (A37X0_SPI_CLK_PHASE | A37X0_SPI_CLK_POL);
335                 break;
336         }
337         A37X0_SPI_WRITE(sc, A37X0_SPI_CONF, reg);
338 }
339
340 static void
341 a37x0_spi_intr(void *arg)
342 {
343         struct a37x0_spi_softc *sc;
344         uint32_t status;
345
346         sc = (struct a37x0_spi_softc *)arg;
347         A37X0_SPI_LOCK(sc);
348
349         /* Filter stray interrupts. */
350         if ((sc->sc_flags & A37X0_SPI_BUSY) == 0) {
351                 A37X0_SPI_UNLOCK(sc);
352                 return;
353         }
354
355         status = A37X0_SPI_READ(sc, A37X0_SPI_INTR_STAT);
356         if (status & A37X0_SPI_XFER_DONE)
357                 a37x0_spi_rx_byte(sc);
358
359         /* Clear the interrupt status. */
360         A37X0_SPI_WRITE(sc, A37X0_SPI_INTR_STAT, status);
361
362         /* Check for end of transfer. */
363         if (sc->sc_written == sc->sc_len && sc->sc_read == sc->sc_len)
364                 wakeup(sc->sc_dev);
365         else
366                 a37x0_spi_tx_byte(sc);
367
368         A37X0_SPI_UNLOCK(sc);
369 }
370
371 static int
372 a37x0_spi_transfer(device_t dev, device_t child, struct spi_command *cmd)
373 {
374         int timeout;
375         struct a37x0_spi_softc *sc;
376         uint32_t clock, cs, mode, reg;
377
378         KASSERT(cmd->tx_cmd_sz == cmd->rx_cmd_sz,
379             ("TX/RX command sizes should be equal"));
380         KASSERT(cmd->tx_data_sz == cmd->rx_data_sz,
381             ("TX/RX data sizes should be equal"));
382
383         /* Get the proper data for this child. */
384         spibus_get_cs(child, &cs);
385         cs &= ~SPIBUS_CS_HIGH;
386         if (cs > 3) {
387                 device_printf(dev,
388                     "Invalid CS %d requested by %s\n", cs,
389                     device_get_nameunit(child));
390                 return (EINVAL);
391         }
392         spibus_get_clock(child, &clock);
393         if (clock == 0) {
394                 device_printf(dev,
395                     "Invalid clock %uHz requested by %s\n", clock,
396                     device_get_nameunit(child));
397                 return (EINVAL);
398         }
399         spibus_get_mode(child, &mode);
400         if (mode > 3) {
401                 device_printf(dev,
402                     "Invalid mode %u requested by %s\n", mode,
403                     device_get_nameunit(child));
404                 return (EINVAL);
405         }
406
407         sc = device_get_softc(dev);
408         A37X0_SPI_LOCK(sc);
409
410         /* Wait until the controller is free. */
411         while (sc->sc_flags & A37X0_SPI_BUSY)
412                 mtx_sleep(dev, &sc->sc_mtx, 0, "a37x0_spi", 0);
413
414         /* Now we have control over SPI controller. */
415         sc->sc_flags = A37X0_SPI_BUSY;
416
417         /* Set transfer mode and clock. */
418         a37x0_spi_set_mode(sc, mode);
419         a37x0_spi_set_pins(sc, 1);
420         a37x0_spi_set_clock(sc, clock);
421
422         /* Set CS. */
423         A37X0_SPI_WRITE(sc, A37X0_SPI_CONTROL, 1 << (A37X0_SPI_CS_SHIFT + cs));
424
425         /* Save a pointer to the SPI command. */
426         sc->sc_cmd = cmd;
427         sc->sc_read = 0;
428         sc->sc_written = 0;
429         sc->sc_len = cmd->tx_cmd_sz + cmd->tx_data_sz;
430
431         /* Clear interrupts. */
432         reg = A37X0_SPI_READ(sc, A37X0_SPI_INTR_STAT);
433         A37X0_SPI_WRITE(sc, A37X0_SPI_INTR_STAT, reg);
434
435         while ((sc->sc_len - sc->sc_written) > 0) {
436                 /*
437                  * Write to start the transmission and read the byte
438                  * back when ready.
439                  */
440                 a37x0_spi_tx_byte(sc);
441                 timeout = 1000;
442                 while (--timeout > 0) {
443                         reg = A37X0_SPI_READ(sc, A37X0_SPI_CONTROL);
444                         if (reg & A37X0_SPI_XFER_DONE)
445                                 break;
446                         DELAY(1);
447                 }
448                 if (timeout == 0)
449                         break;
450                 a37x0_spi_rx_byte(sc);
451         }
452
453         /* Stop the controller. */
454         reg = A37X0_SPI_READ(sc, A37X0_SPI_CONTROL);
455         A37X0_SPI_WRITE(sc, A37X0_SPI_CONTROL, reg & ~A37X0_SPI_CS_MASK);
456         A37X0_SPI_WRITE(sc, A37X0_SPI_INTR_MASK, 0);
457
458         /* Release the controller and wakeup the next thread waiting for it. */
459         sc->sc_flags = 0;
460         wakeup_one(dev);
461         A37X0_SPI_UNLOCK(sc);
462
463         return ((timeout == 0) ? EIO : 0);
464 }
465
466 static phandle_t
467 a37x0_spi_get_node(device_t bus, device_t dev)
468 {
469
470         return (ofw_bus_get_node(bus));
471 }
472
473 static device_method_t a37x0_spi_methods[] = {
474         /* Device interface */
475         DEVMETHOD(device_probe,         a37x0_spi_probe),
476         DEVMETHOD(device_attach,        a37x0_spi_attach),
477         DEVMETHOD(device_detach,        a37x0_spi_detach),
478
479         /* SPI interface */
480         DEVMETHOD(spibus_transfer,      a37x0_spi_transfer),
481
482         /* ofw_bus interface */
483         DEVMETHOD(ofw_bus_get_node,     a37x0_spi_get_node),
484
485         DEVMETHOD_END
486 };
487
488 static devclass_t a37x0_spi_devclass;
489
490 static driver_t a37x0_spi_driver = {
491         "spi",
492         a37x0_spi_methods,
493         sizeof(struct a37x0_spi_softc),
494 };
495
496 DRIVER_MODULE(a37x0_spi, simplebus, a37x0_spi_driver, a37x0_spi_devclass, 0, 0);