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