xref: /freebsd/sys/arm/mv/a37x0_spi.c (revision 8d30ef92d59567d47a1fee9dc71baf17a555234d)
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);
495