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