xref: /freebsd/sys/arm/mv/a37x0_spi.c (revision b64c5a0ace59af62eff52bfe110a521dc73c937b)
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/param.h>
27 #include <sys/systm.h>
28 #include <sys/bus.h>
29 #include <sys/kernel.h>
30 #include <sys/module.h>
31 #include <sys/mutex.h>
32 #include <sys/rman.h>
33 
34 #include <machine/bus.h>
35 #include <machine/resource.h>
36 #include <machine/intr.h>
37 
38 #include <dev/ofw/ofw_bus.h>
39 #include <dev/ofw/ofw_bus_subr.h>
40 #include <dev/spibus/spi.h>
41 #include <dev/spibus/spibusvar.h>
42 
43 #include "spibus_if.h"
44 
45 struct a37x0_spi_softc {
46 	device_t		sc_dev;
47 	struct mtx		sc_mtx;
48 	struct resource		*sc_mem_res;
49 	struct resource		*sc_irq_res;
50 	struct spi_command	*sc_cmd;
51 	bus_space_tag_t		sc_bst;
52 	bus_space_handle_t	sc_bsh;
53 	uint32_t		sc_len;
54 	uint32_t		sc_maxfreq;
55 	uint32_t		sc_read;
56 	uint32_t		sc_flags;
57 	uint32_t		sc_written;
58 	void			*sc_intrhand;
59 };
60 
61 #define	A37X0_SPI_WRITE(_sc, _off, _val)		\
62     bus_space_write_4((_sc)->sc_bst, (_sc)->sc_bsh, (_off), (_val))
63 #define	A37X0_SPI_READ(_sc, _off)			\
64     bus_space_read_4((_sc)->sc_bst, (_sc)->sc_bsh, (_off))
65 #define	A37X0_SPI_LOCK(_sc)	mtx_lock(&(_sc)->sc_mtx)
66 #define	A37X0_SPI_UNLOCK(_sc)	mtx_unlock(&(_sc)->sc_mtx)
67 
68 #define	A37X0_SPI_BUSY			(1 << 0)
69 /*
70  * While the A3700 utils from Marvell usually sets the QSF clock to 200MHz,
71  * there is no guarantee that it is correct without the proper clock framework
72  * to retrieve the actual TBG and PLL settings.
73  */
74 #define	A37X0_SPI_CLOCK			200000000	/* QSF Clock 200MHz */
75 
76 #define	A37X0_SPI_CONTROL		0x0
77 #define	 A37X0_SPI_CS_SHIFT		16
78 #define	 A37X0_SPI_CS_MASK		(0xf << A37X0_SPI_CS_SHIFT)
79 #define	A37X0_SPI_CONF			0x4
80 #define	 A37X0_SPI_WFIFO_THRS_SHIFT	28
81 #define	 A37X0_SPI_RFIFO_THRS_SHIFT	24
82 #define	 A37X0_SPI_AUTO_CS_EN		(1 << 20)
83 #define	 A37X0_SPI_DMA_WR_EN		(1 << 19)
84 #define	 A37X0_SPI_DMA_RD_EN		(1 << 18)
85 #define	 A37X0_SPI_FIFO_MODE		(1 << 17)
86 #define	 A37X0_SPI_SRST			(1 << 16)
87 #define	 A37X0_SPI_XFER_START		(1 << 15)
88 #define	 A37X0_SPI_XFER_STOP		(1 << 14)
89 #define	 A37X0_SPI_INSTR_PIN		(1 << 13)
90 #define	 A37X0_SPI_ADDR_PIN		(1 << 12)
91 #define	 A37X0_SPI_DATA_PIN_MASK	0x3
92 #define	 A37X0_SPI_DATA_PIN_SHIFT	10
93 #define	 A37X0_SPI_FIFO_FLUSH		(1 << 9)
94 #define	 A37X0_SPI_RW_EN		(1 << 8)
95 #define	 A37X0_SPI_CLK_POL		(1 << 7)
96 #define	 A37X0_SPI_CLK_PHASE		(1 << 6)
97 #define	 A37X0_SPI_BYTE_LEN		(1 << 5)
98 #define	 A37X0_SPI_PSC_MASK		0x1f
99 #define	A37X0_SPI_DATA_OUT		0x8
100 #define	A37X0_SPI_DATA_IN		0xc
101 #define	A37X0_SPI_INTR_STAT		0x28
102 #define	A37X0_SPI_INTR_MASK		0x2c
103 #define	 A37X0_SPI_RDY			(1 << 1)
104 #define	 A37X0_SPI_XFER_DONE		(1 << 0)
105 
106 static struct ofw_compat_data compat_data[] = {
107 	{ "marvell,armada-3700-spi",	1 },
108 	{ NULL, 0 }
109 };
110 
111 static void a37x0_spi_intr(void *);
112 
113 static int
114 a37x0_spi_wait(struct a37x0_spi_softc *sc, int timeout, uint32_t reg,
115     uint32_t mask)
116 {
117 	int i;
118 
119 	for (i = 0; i < timeout; i++) {
120 		if ((A37X0_SPI_READ(sc, reg) & mask) == 0)
121 			return (0);
122 		DELAY(100);
123 	}
124 
125 	return (ETIMEDOUT);
126 }
127 
128 static int
129 a37x0_spi_probe(device_t dev)
130 {
131 
132 	if (!ofw_bus_status_okay(dev))
133 		return (ENXIO);
134 	if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
135 		return (ENXIO);
136 	device_set_desc(dev, "Armada 37x0 SPI controller");
137 
138 	return (BUS_PROBE_DEFAULT);
139 }
140 
141 static int
142 a37x0_spi_attach(device_t dev)
143 {
144 	int err, rid;
145 	pcell_t maxfreq;
146 	struct a37x0_spi_softc *sc;
147 	uint32_t reg;
148 
149 	sc = device_get_softc(dev);
150 	sc->sc_dev = dev;
151 
152 	rid = 0;
153 	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
154 	    RF_ACTIVE);
155 	if (!sc->sc_mem_res) {
156 		device_printf(dev, "cannot allocate memory window\n");
157 		return (ENXIO);
158 	}
159 
160 	sc->sc_bst = rman_get_bustag(sc->sc_mem_res);
161 	sc->sc_bsh = rman_get_bushandle(sc->sc_mem_res);
162 
163 	rid = 0;
164 	sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
165 	    RF_ACTIVE);
166 	if (!sc->sc_irq_res) {
167 		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
168 		device_printf(dev, "cannot allocate interrupt\n");
169 		return (ENXIO);
170 	}
171 
172 	/* Make sure that no CS is asserted. */
173 	reg = A37X0_SPI_READ(sc, A37X0_SPI_CONTROL);
174 	A37X0_SPI_WRITE(sc, A37X0_SPI_CONTROL, reg & ~A37X0_SPI_CS_MASK);
175 
176 	/* Reset FIFO. */
177 	reg = A37X0_SPI_READ(sc, A37X0_SPI_CONF);
178 	A37X0_SPI_WRITE(sc, A37X0_SPI_CONF, reg | A37X0_SPI_FIFO_FLUSH);
179 	err = a37x0_spi_wait(sc, 20, A37X0_SPI_CONF, A37X0_SPI_FIFO_FLUSH);
180 	if (err != 0) {
181 		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
182 		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
183 		device_printf(dev, "cannot flush the controller fifo.\n");
184 		return (ENXIO);
185 	}
186 
187 	/* Reset the Controller. */
188 	reg = A37X0_SPI_READ(sc, A37X0_SPI_CONF);
189 	A37X0_SPI_WRITE(sc, A37X0_SPI_CONF, reg | A37X0_SPI_SRST);
190 	DELAY(1000);
191 	/* Enable the single byte IO, disable FIFO. */
192 	reg &= ~(A37X0_SPI_FIFO_MODE | A37X0_SPI_BYTE_LEN);
193 	A37X0_SPI_WRITE(sc, A37X0_SPI_CONF, reg);
194 
195 	/* Disable and clear interrupts. */
196 	A37X0_SPI_WRITE(sc, A37X0_SPI_INTR_MASK, 0);
197 	reg = A37X0_SPI_READ(sc, A37X0_SPI_INTR_STAT);
198 	A37X0_SPI_WRITE(sc, A37X0_SPI_INTR_STAT, reg);
199 
200 	/* Hook up our interrupt handler. */
201 	if (bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
202 	    NULL, a37x0_spi_intr, sc, &sc->sc_intrhand)) {
203 		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
204 		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
205 		device_printf(dev, "cannot setup the interrupt handler\n");
206 		return (ENXIO);
207 	}
208 
209 	mtx_init(&sc->sc_mtx, "a37x0_spi", NULL, MTX_DEF);
210 
211 	/* Read the controller max-frequency. */
212 	if (OF_getencprop(ofw_bus_get_node(dev), "spi-max-frequency", &maxfreq,
213 	    sizeof(maxfreq)) == -1)
214 		maxfreq = 0;
215 	sc->sc_maxfreq = maxfreq;
216 
217 	device_add_child(dev, "spibus", DEVICE_UNIT_ANY);
218 
219 	/* Probe and attach the spibus when interrupts are available. */
220 	bus_delayed_attach_children(dev);
221 	return (0);
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