1/*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2018 Thomas Skibo <thomasskibo@yahoo.com>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#include <sys/cdefs.h>
30/*
31 * This is a driver for the Quad-SPI Flash Controller in the Xilinx
32 * Zynq-7000 SoC.
33 */
34
35#include <sys/param.h>
36#include <sys/systm.h>
37#include <sys/conf.h>
38#include <sys/kernel.h>
39#include <sys/module.h>
40#include <sys/sysctl.h>
41#include <sys/lock.h>
42#include <sys/mutex.h>
43#include <sys/resource.h>
44#include <sys/rman.h>
45#include <sys/uio.h>
46
47#include <machine/bus.h>
48#include <machine/resource.h>
49#include <machine/stdarg.h>
50
51#include <dev/fdt/fdt_common.h>
52#include <dev/ofw/ofw_bus.h>
53#include <dev/ofw/ofw_bus_subr.h>
54
55#include <dev/spibus/spi.h>
56#include <dev/spibus/spibusvar.h>
57
58#include <dev/flash/mx25lreg.h>
59
60#include "spibus_if.h"
61
62static struct ofw_compat_data compat_data[] = {
63	{"xlnx,zy7_qspi",		1},
64	{"xlnx,zynq-qspi-1.0",		1},
65	{NULL,				0}
66};
67
68struct zy7_qspi_softc {
69	device_t		dev;
70	device_t		child;
71	struct mtx		sc_mtx;
72	struct resource		*mem_res;
73	struct resource		*irq_res;
74	void			*intrhandle;
75
76	uint32_t		cfg_reg_shadow;
77	uint32_t		lqspi_cfg_shadow;
78	uint32_t		spi_clock;
79	uint32_t		ref_clock;
80	unsigned int		spi_clk_real_freq;
81	unsigned int		rx_overflows;
82	unsigned int		tx_underflows;
83	unsigned int		interrupts;
84	unsigned int		stray_ints;
85	struct spi_command	*cmd;
86	int			tx_bytes;	/* tx_cmd_sz + tx_data_sz */
87	int			tx_bytes_sent;
88	int			rx_bytes;	/* rx_cmd_sz + rx_data_sz */
89	int			rx_bytes_rcvd;
90	int			busy;
91	int			is_dual;
92	int			is_stacked;
93	int			is_dio;
94};
95
96#define ZY7_QSPI_DEFAULT_SPI_CLOCK	50000000
97
98#define QSPI_SC_LOCK(sc)		mtx_lock(&(sc)->sc_mtx)
99#define	QSPI_SC_UNLOCK(sc)		mtx_unlock(&(sc)->sc_mtx)
100#define QSPI_SC_LOCK_INIT(sc) \
101	mtx_init(&(sc)->sc_mtx, device_get_nameunit((sc)->dev),	NULL, MTX_DEF)
102#define QSPI_SC_LOCK_DESTROY(sc)	mtx_destroy(&(sc)->sc_mtx)
103#define QSPI_SC_ASSERT_LOCKED(sc)	mtx_assert(&(sc)->sc_mtx, MA_OWNED)
104
105#define RD4(sc, off)		(bus_read_4((sc)->mem_res, (off)))
106#define WR4(sc, off, val)	(bus_write_4((sc)->mem_res, (off), (val)))
107
108/*
109 * QSPI device registers.
110 * Reference: Zynq-7000 All Programmable SoC Technical Reference Manual.
111 * (v1.12.2) July 1, 2018.  Xilinx doc UG585.
112 */
113#define ZY7_QSPI_CONFIG_REG		0x0000
114#define   ZY7_QSPI_CONFIG_IFMODE		(1U << 31)
115#define   ZY7_QSPI_CONFIG_ENDIAN		(1 << 26)
116#define   ZY7_QSPI_CONFIG_HOLDB_DR		(1 << 19)
117#define   ZY7_QSPI_CONFIG_RSVD1			(1 << 17) /* must be 1 */
118#define   ZY7_QSPI_CONFIG_MANSTRT		(1 << 16)
119#define   ZY7_QSPI_CONFIG_MANSTRTEN		(1 << 15)
120#define   ZY7_QSPI_CONFIG_SSFORCE		(1 << 14)
121#define   ZY7_QSPI_CONFIG_PCS			(1 << 10)
122#define   ZY7_QSPI_CONFIG_REF_CLK		(1 << 8)
123#define   ZY7_QSPI_CONFIG_FIFO_WIDTH_MASK	(3 << 6)
124#define   ZY7_QSPI_CONFIG_FIFO_WIDTH32		(3 << 6)
125#define   ZY7_QSPI_CONFIG_BAUD_RATE_DIV_MASK	(7 << 3)
126#define   ZY7_QSPI_CONFIG_BAUD_RATE_DIV_SHIFT	3
127#define   ZY7_QSPI_CONFIG_BAUD_RATE_DIV(x)	((x) << 3) /* divide by 2<<x */
128#define   ZY7_QSPI_CONFIG_CLK_PH		(1 << 2)   /* clock phase */
129#define   ZY7_QSPI_CONFIG_CLK_POL		(1 << 1)   /* clock polarity */
130#define   ZY7_QSPI_CONFIG_MODE_SEL		(1 << 0)   /* master enable */
131
132#define ZY7_QSPI_INTR_STAT_REG		0x0004
133#define ZY7_QSPI_INTR_EN_REG		0x0008
134#define ZY7_QSPI_INTR_DIS_REG		0x000c
135#define ZY7_QSPI_INTR_MASK_REG		0x0010
136#define   ZY7_QSPI_INTR_TX_FIFO_UNDERFLOW	(1 << 6)
137#define   ZY7_QSPI_INTR_RX_FIFO_FULL		(1 << 5)
138#define   ZY7_QSPI_INTR_RX_FIFO_NOT_EMPTY	(1 << 4)
139#define   ZY7_QSPI_INTR_TX_FIFO_FULL		(1 << 3)
140#define   ZY7_QSPI_INTR_TX_FIFO_NOT_FULL	(1 << 2)
141#define   ZY7_QSPI_INTR_RX_OVERFLOW		(1 << 0)
142
143#define ZY7_QSPI_EN_REG			0x0014
144#define   ZY7_SPI_ENABLE			1
145
146#define ZY7_QSPI_DELAY_REG		0x0018
147#define   ZY7_QSPI_DELAY_NSS_MASK		(0xffU << 24)
148#define   ZY7_QSPI_DELAY_NSS_SHIFT		24
149#define   ZY7_QSPI_DELAY_NSS(x)			((x) << 24)
150#define   ZY7_QSPI_DELAY_BTWN_MASK		(0xff << 16)
151#define   ZY7_QSPI_DELAY_BTWN_SHIFT		16
152#define   ZY7_QSPI_DELAY_BTWN(x)		((x) << 16)
153#define   ZY7_QSPI_DELAY_AFTER_MASK		(0xff << 8)
154#define   ZY7_QSPI_DELAY_AFTER_SHIFT		8
155#define   ZY7_QSPI_DELAY_AFTER(x)		((x) << 8)
156#define   ZY7_QSPI_DELAY_INIT_MASK		0xff
157#define   ZY7_QSPI_DELAY_INIT_SHIFT		0
158#define   ZY7_QSPI_DELAY_INIT(x)		(x)
159
160#define ZY7_QSPI_TXD0_REG		0x001c
161#define ZY7_QSPI_RX_DATA_REG		0x0020
162
163#define ZY7_QSPI_SLV_IDLE_CT_REG	0x0024
164#define   ZY7_QSPI_SLV_IDLE_CT_MASK		0xff
165
166#define ZY7_QSPI_TX_THRESH_REG		0x0028
167#define ZY7_QSPI_RX_THRESH_REG		0x002c
168
169#define ZY7_QSPI_GPIO_REG		0x0030
170#define   ZY7_QSPI_GPIO_WP_N			1
171
172#define ZY7_QSPI_LPBK_DLY_ADJ_REG	0x0038
173#define   ZY7_QSPI_LPBK_DLY_ADJ_LPBK_SEL	(1 << 8)
174#define   ZY7_QSPI_LPBK_DLY_ADJ_LPBK_PH		(1 << 7)
175#define   ZY7_QSPI_LPBK_DLY_ADJ_USE_LPBK	(1 << 5)
176#define   ZY7_QSPI_LPBK_DLY_ADJ_DLY1_MASK	(3 << 3)
177#define   ZY7_QSPI_LPBK_DLY_ADJ_DLY1_SHIFT	3
178#define   ZY7_QSPI_LPBK_DLY_ADJ_DLY1(x)		((x) << 3)
179#define   ZY7_QSPI_LPBK_DLY_ADJ_DLY0_MASK	7
180#define   ZY7_QSPI_LPBK_DLY_ADJ_DLY0_SHIFT	0
181#define   ZY7_QSPI_LPBK_DLY_ADJ_DLY0(x)		(x)
182
183#define ZY7_QSPI_TXD1_REG		0x0080
184#define ZY7_QSPI_TXD2_REG		0x0084
185#define ZY7_QSPI_TXD3_REG		0x0088
186
187#define ZY7_QSPI_LQSPI_CFG_REG		0x00a0
188#define   ZY7_QSPI_LQSPI_CFG_LINEAR		(1U << 31)
189#define   ZY7_QSPI_LQSPI_CFG_TWO_MEM		(1 << 30)
190#define   ZY7_QSPI_LQSPI_CFG_SEP_BUS		(1 << 29)
191#define   ZY7_QSPI_LQSPI_CFG_U_PAGE		(1 << 28)
192#define   ZY7_QSPI_LQSPI_CFG_MODE_EN		(1 << 25)
193#define   ZY7_QSPI_LQSPI_CFG_MODE_ON		(1 << 24)
194#define   ZY7_QSPI_LQSPI_CFG_MODE_BITS_MASK	(0xff << 16)
195#define   ZY7_QSPI_LQSPI_CFG_MODE_BITS_SHIFT	16
196#define   ZY7_QSPI_LQSPI_CFG_MODE_BITS(x)	((x) << 16)
197#define   ZY7_QSPI_LQSPI_CFG_DUMMY_BYTES_MASK	(7 << 8)
198#define   ZY7_QSPI_LQSPI_CFG_DUMMY_BYTES_SHIFT	8
199#define   ZY7_QSPI_LQSPI_CFG_DUMMY_BYTES(x)	((x) << 8)
200#define   ZY7_QSPI_LQSPI_CFG_INST_CODE_MASK	0xff
201#define   ZY7_QSPI_LQSPI_CFG_INST_CODE_SHIFT	0
202#define   ZY7_QSPI_LQSPI_CFG_INST_CODE(x)	(x)
203
204#define ZY7_QSPI_LQSPI_STS_REG		0x00a4
205#define   ZY7_QSPI_LQSPI_STS_D_FSM_ERR		(1 << 2)
206#define   ZY7_QSPI_LQSPI_STS_WR_RECVD		(1 << 1)
207
208#define ZY7_QSPI_MOD_ID_REG		0x00fc
209
210static int zy7_qspi_detach(device_t);
211
212/* Fill hardware fifo with command and data bytes. */
213static void
214zy7_qspi_write_fifo(struct zy7_qspi_softc *sc, int nbytes)
215{
216	int n, nvalid;
217	uint32_t data;
218
219	while (nbytes > 0) {
220		nvalid = MIN(4, nbytes);
221		data = 0xffffffff;
222
223		/*
224		 * A hardware bug forces us to wait until the tx fifo is
225		 * empty before writing partial words.  We'll come back
226		 * next tx interrupt.
227		 */
228		if (nvalid < 4 && (RD4(sc, ZY7_QSPI_INTR_STAT_REG) &
229		    ZY7_QSPI_INTR_TX_FIFO_NOT_FULL) == 0)
230			return;
231
232		if (sc->tx_bytes_sent < sc->cmd->tx_cmd_sz) {
233			/* Writing command. */
234			n = MIN(nvalid, sc->cmd->tx_cmd_sz -
235			    sc->tx_bytes_sent);
236			memcpy(&data, (uint8_t *)sc->cmd->tx_cmd +
237			    sc->tx_bytes_sent, n);
238
239			if (nvalid > n) {
240				/* Writing start of data. */
241				memcpy((uint8_t *)&data + n,
242				    sc->cmd->tx_data, nvalid - n);
243			}
244		} else
245			/* Writing data. */
246			memcpy(&data, (uint8_t *)sc->cmd->tx_data +
247			    (sc->tx_bytes_sent - sc->cmd->tx_cmd_sz), nvalid);
248
249		switch (nvalid) {
250		case 1:
251			WR4(sc, ZY7_QSPI_TXD1_REG, data);
252			break;
253		case 2:
254			WR4(sc, ZY7_QSPI_TXD2_REG, data);
255			break;
256		case 3:
257			WR4(sc, ZY7_QSPI_TXD3_REG, data);
258			break;
259		case 4:
260			WR4(sc, ZY7_QSPI_TXD0_REG, data);
261			break;
262		}
263
264		sc->tx_bytes_sent += nvalid;
265		nbytes -= nvalid;
266	}
267}
268
269/* Read hardware fifo data into command response and data buffers. */
270static void
271zy7_qspi_read_fifo(struct zy7_qspi_softc *sc)
272{
273	int n, nbytes;
274	uint32_t data;
275
276	do {
277		data = RD4(sc, ZY7_QSPI_RX_DATA_REG);
278		nbytes = MIN(4, sc->rx_bytes - sc->rx_bytes_rcvd);
279
280		/*
281		 * Last word in non-word-multiple transfer is packed
282		 * non-intuitively.
283		 */
284		if (nbytes < 4)
285			data >>= 8 * (4 - nbytes);
286
287		if (sc->rx_bytes_rcvd < sc->cmd->rx_cmd_sz) {
288			/* Reading command. */
289			n = MIN(nbytes, sc->cmd->rx_cmd_sz -
290			    sc->rx_bytes_rcvd);
291			memcpy((uint8_t *)sc->cmd->rx_cmd + sc->rx_bytes_rcvd,
292			    &data, n);
293			sc->rx_bytes_rcvd += n;
294			nbytes -= n;
295			data >>= 8 * n;
296		}
297
298		if (nbytes > 0) {
299			/* Reading data. */
300			memcpy((uint8_t *)sc->cmd->rx_data +
301			    (sc->rx_bytes_rcvd - sc->cmd->rx_cmd_sz),
302			    &data, nbytes);
303			sc->rx_bytes_rcvd += nbytes;
304		}
305
306	} while (sc->rx_bytes_rcvd < sc->rx_bytes &&
307		 (RD4(sc, ZY7_QSPI_INTR_STAT_REG) &
308		  ZY7_QSPI_INTR_RX_FIFO_NOT_EMPTY) != 0);
309}
310
311/* End a transfer early by draining rx fifo and disabling interrupts. */
312static void
313zy7_qspi_abort_transfer(struct zy7_qspi_softc *sc)
314{
315	/* Drain receive fifo. */
316	while ((RD4(sc, ZY7_QSPI_INTR_STAT_REG) &
317		ZY7_QSPI_INTR_RX_FIFO_NOT_EMPTY) != 0)
318		(void)RD4(sc, ZY7_QSPI_RX_DATA_REG);
319
320	/* Shut down interrupts. */
321	WR4(sc, ZY7_QSPI_INTR_DIS_REG,
322	    ZY7_QSPI_INTR_RX_OVERFLOW |
323	    ZY7_QSPI_INTR_RX_FIFO_NOT_EMPTY |
324	    ZY7_QSPI_INTR_TX_FIFO_NOT_FULL);
325}
326
327static void
328zy7_qspi_intr(void *arg)
329{
330	struct zy7_qspi_softc *sc = (struct zy7_qspi_softc *)arg;
331	uint32_t istatus;
332
333	QSPI_SC_LOCK(sc);
334
335	sc->interrupts++;
336
337	istatus = RD4(sc, ZY7_QSPI_INTR_STAT_REG);
338
339	/* Stray interrupts can happen if a transfer gets interrupted. */
340	if (!sc->busy) {
341		sc->stray_ints++;
342		QSPI_SC_UNLOCK(sc);
343		return;
344	}
345
346	if ((istatus & ZY7_QSPI_INTR_RX_OVERFLOW) != 0) {
347		device_printf(sc->dev, "rx fifo overflow!\n");
348		sc->rx_overflows++;
349
350		/* Clear status bit. */
351		WR4(sc, ZY7_QSPI_INTR_STAT_REG,
352		    ZY7_QSPI_INTR_RX_OVERFLOW);
353	}
354
355	/* Empty receive fifo before any more transmit data is sent. */
356	if (sc->rx_bytes_rcvd < sc->rx_bytes &&
357	    (istatus & ZY7_QSPI_INTR_RX_FIFO_NOT_EMPTY) != 0) {
358		zy7_qspi_read_fifo(sc);
359		if (sc->rx_bytes_rcvd == sc->rx_bytes)
360			/* Disable receive interrupts. */
361			WR4(sc, ZY7_QSPI_INTR_DIS_REG,
362			    ZY7_QSPI_INTR_RX_FIFO_NOT_EMPTY |
363			    ZY7_QSPI_INTR_RX_OVERFLOW);
364	}
365
366	/*
367	 * Transmit underflows aren't really a bug because a hardware
368	 * bug forces us to allow the tx fifo to go empty between full
369	 * and partial fifo writes.  Why bother counting?
370	 */
371	if ((istatus & ZY7_QSPI_INTR_TX_FIFO_UNDERFLOW) != 0) {
372		sc->tx_underflows++;
373
374		/* Clear status bit. */
375		WR4(sc, ZY7_QSPI_INTR_STAT_REG,
376		    ZY7_QSPI_INTR_TX_FIFO_UNDERFLOW);
377	}
378
379	/* Fill transmit fifo. */
380	if (sc->tx_bytes_sent < sc->tx_bytes &&
381	    (istatus & ZY7_QSPI_INTR_TX_FIFO_NOT_FULL) != 0) {
382		zy7_qspi_write_fifo(sc, MIN(240, sc->tx_bytes -
383			sc->tx_bytes_sent));
384
385		if (sc->tx_bytes_sent == sc->tx_bytes) {
386			/*
387			 * Disable transmit FIFO interrupt, enable receive
388			 * FIFO interrupt.
389			 */
390			WR4(sc, ZY7_QSPI_INTR_DIS_REG,
391			    ZY7_QSPI_INTR_TX_FIFO_NOT_FULL);
392			WR4(sc, ZY7_QSPI_INTR_EN_REG,
393			    ZY7_QSPI_INTR_RX_FIFO_NOT_EMPTY);
394		}
395	}
396
397	/* Finished with transfer? */
398	if (sc->tx_bytes_sent == sc->tx_bytes &&
399	    sc->rx_bytes_rcvd == sc->rx_bytes) {
400		/* De-assert CS. */
401		sc->cfg_reg_shadow |= ZY7_QSPI_CONFIG_PCS;
402		WR4(sc, ZY7_QSPI_CONFIG_REG, sc->cfg_reg_shadow);
403
404		wakeup(sc->dev);
405	}
406
407	QSPI_SC_UNLOCK(sc);
408}
409
410/* Initialize hardware. */
411static int
412zy7_qspi_init_hw(struct zy7_qspi_softc *sc)
413{
414	uint32_t baud_div;
415
416	/* Configure LQSPI Config register.  Disable linear mode. */
417	sc->lqspi_cfg_shadow = RD4(sc, ZY7_QSPI_LQSPI_CFG_REG);
418	sc->lqspi_cfg_shadow &= ~(ZY7_QSPI_LQSPI_CFG_LINEAR |
419				  ZY7_QSPI_LQSPI_CFG_TWO_MEM |
420				  ZY7_QSPI_LQSPI_CFG_SEP_BUS);
421	if (sc->is_dual) {
422		sc->lqspi_cfg_shadow |= ZY7_QSPI_LQSPI_CFG_TWO_MEM;
423		if (sc->is_stacked) {
424			sc->lqspi_cfg_shadow &=
425			    ~ZY7_QSPI_LQSPI_CFG_INST_CODE_MASK;
426			sc->lqspi_cfg_shadow |=
427			    ZY7_QSPI_LQSPI_CFG_INST_CODE(sc->is_dio ?
428				CMD_READ_DUAL_IO : CMD_READ_QUAD_OUTPUT);
429		} else
430			sc->lqspi_cfg_shadow |= ZY7_QSPI_LQSPI_CFG_SEP_BUS;
431	}
432	WR4(sc, ZY7_QSPI_LQSPI_CFG_REG, sc->lqspi_cfg_shadow);
433
434	/* Find best clock divider. */
435	baud_div = 0;
436	while ((sc->ref_clock >> (baud_div + 1)) > sc->spi_clock &&
437	       baud_div < 8)
438		baud_div++;
439	if (baud_div >= 8) {
440		device_printf(sc->dev, "cannot configure clock divider: ref=%d"
441		    " spi=%d.\n", sc->ref_clock, sc->spi_clock);
442		return (EINVAL);
443	}
444	sc->spi_clk_real_freq = sc->ref_clock >> (baud_div + 1);
445
446	/*
447	 * If divider is 2 (the max speed), use internal loopback master
448	 * clock for read data.  (See section 12.3.1 in ref man.)
449	 */
450	if (baud_div == 0)
451		WR4(sc, ZY7_QSPI_LPBK_DLY_ADJ_REG,
452		    ZY7_QSPI_LPBK_DLY_ADJ_USE_LPBK |
453		    ZY7_QSPI_LPBK_DLY_ADJ_DLY1(0) |
454		    ZY7_QSPI_LPBK_DLY_ADJ_DLY0(0));
455	else
456		WR4(sc, ZY7_QSPI_LPBK_DLY_ADJ_REG, 0);
457
458	/* Set up configuration register. */
459	sc->cfg_reg_shadow =
460		ZY7_QSPI_CONFIG_IFMODE |
461		ZY7_QSPI_CONFIG_HOLDB_DR |
462		ZY7_QSPI_CONFIG_RSVD1 |
463		ZY7_QSPI_CONFIG_SSFORCE |
464		ZY7_QSPI_CONFIG_PCS |
465		ZY7_QSPI_CONFIG_FIFO_WIDTH32 |
466		ZY7_QSPI_CONFIG_BAUD_RATE_DIV(baud_div) |
467		ZY7_QSPI_CONFIG_MODE_SEL;
468	WR4(sc, ZY7_QSPI_CONFIG_REG, sc->cfg_reg_shadow);
469
470	/*
471	 * Set thresholds.  We must use 1 for tx threshold because there
472	 * is no fifo empty flag and we need one to implement a bug
473	 * workaround.
474	 */
475	WR4(sc, ZY7_QSPI_TX_THRESH_REG, 1);
476	WR4(sc, ZY7_QSPI_RX_THRESH_REG, 1);
477
478	/* Clear and disable all interrupts. */
479	WR4(sc, ZY7_QSPI_INTR_STAT_REG, ~0);
480	WR4(sc, ZY7_QSPI_INTR_DIS_REG, ~0);
481
482	/* Enable SPI. */
483	WR4(sc, ZY7_QSPI_EN_REG, ZY7_SPI_ENABLE);
484
485	return (0);
486}
487
488static void
489zy7_qspi_add_sysctls(device_t dev)
490{
491	struct zy7_qspi_softc *sc = device_get_softc(dev);
492	struct sysctl_ctx_list *ctx;
493	struct sysctl_oid_list *child;
494
495	ctx = device_get_sysctl_ctx(dev);
496	child = SYSCTL_CHILDREN(device_get_sysctl_tree(dev));
497
498	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "spi_clk_real_freq", CTLFLAG_RD,
499	    &sc->spi_clk_real_freq, 0, "SPI clock real frequency");
500
501	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "rx_overflows", CTLFLAG_RD,
502	    &sc->rx_overflows, 0, "RX FIFO overflow events");
503
504	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "tx_underflows", CTLFLAG_RD,
505	    &sc->tx_underflows, 0, "TX FIFO underflow events");
506
507	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "interrupts", CTLFLAG_RD,
508	    &sc->interrupts, 0, "interrupt calls");
509
510	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "stray_ints", CTLFLAG_RD,
511	    &sc->stray_ints, 0, "stray interrupts");
512}
513
514static int
515zy7_qspi_probe(device_t dev)
516{
517
518	if (!ofw_bus_status_okay(dev))
519		return (ENXIO);
520
521	if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
522		return (ENXIO);
523
524	device_set_desc(dev, "Zynq Quad-SPI Flash Controller");
525
526	return (BUS_PROBE_DEFAULT);
527}
528
529static int
530zy7_qspi_attach(device_t dev)
531{
532	struct zy7_qspi_softc *sc;
533	int rid, err;
534	phandle_t node;
535	pcell_t cell;
536
537	sc = device_get_softc(dev);
538	sc->dev = dev;
539
540	QSPI_SC_LOCK_INIT(sc);
541
542	/* Get ref-clock, spi-clock, and other properties. */
543	node = ofw_bus_get_node(dev);
544	if (OF_getprop(node, "ref-clock", &cell, sizeof(cell)) > 0)
545		sc->ref_clock = fdt32_to_cpu(cell);
546	else {
547		device_printf(dev, "must have ref-clock property\n");
548		return (ENXIO);
549	}
550	if (OF_getprop(node, "spi-clock", &cell, sizeof(cell)) > 0)
551		sc->spi_clock = fdt32_to_cpu(cell);
552	else
553		sc->spi_clock = ZY7_QSPI_DEFAULT_SPI_CLOCK;
554	if (OF_getprop(node, "is-stacked", &cell, sizeof(cell)) > 0 &&
555	    fdt32_to_cpu(cell) != 0) {
556		sc->is_dual = 1;
557		sc->is_stacked = 1;
558	} else if (OF_getprop(node, "is-dual", &cell, sizeof(cell)) > 0 &&
559		   fdt32_to_cpu(cell) != 0)
560		sc->is_dual = 1;
561	if (OF_getprop(node, "is-dio", &cell, sizeof(cell)) > 0 &&
562	    fdt32_to_cpu(cell) != 0)
563		sc->is_dio = 1;
564
565	/* Get memory resource. */
566	rid = 0;
567	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
568	    RF_ACTIVE);
569	if (sc->mem_res == NULL) {
570		device_printf(dev, "could not allocate memory resources.\n");
571		zy7_qspi_detach(dev);
572		return (ENOMEM);
573	}
574
575	/* Allocate IRQ. */
576	rid = 0;
577	sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
578	    RF_ACTIVE);
579	if (sc->irq_res == NULL) {
580		device_printf(dev, "could not allocate IRQ resource.\n");
581		zy7_qspi_detach(dev);
582		return (ENOMEM);
583	}
584
585	/* Activate the interrupt. */
586	err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
587	    NULL, zy7_qspi_intr, sc, &sc->intrhandle);
588	if (err) {
589		device_printf(dev, "could not setup IRQ.\n");
590		zy7_qspi_detach(dev);
591		return (err);
592	}
593
594	/* Configure the device. */
595	err = zy7_qspi_init_hw(sc);
596	if (err) {
597		zy7_qspi_detach(dev);
598		return (err);
599	}
600
601	sc->child = device_add_child(dev, "spibus", -1);
602
603	zy7_qspi_add_sysctls(dev);
604
605	/* Attach spibus driver as a child later when interrupts work. */
606	config_intrhook_oneshot((ich_func_t)bus_generic_attach, dev);
607
608	return (0);
609}
610
611static int
612zy7_qspi_detach(device_t dev)
613{
614	struct zy7_qspi_softc *sc = device_get_softc(dev);
615
616	if (device_is_attached(dev))
617		bus_generic_detach(dev);
618
619	/* Delete child bus. */
620	if (sc->child)
621		device_delete_child(dev, sc->child);
622
623	/* Disable hardware. */
624	if (sc->mem_res != NULL) {
625		/* Disable SPI. */
626		WR4(sc, ZY7_QSPI_EN_REG, 0);
627
628		/* Clear and disable all interrupts. */
629		WR4(sc, ZY7_QSPI_INTR_STAT_REG, ~0);
630		WR4(sc, ZY7_QSPI_INTR_DIS_REG, ~0);
631	}
632
633	/* Teardown and release interrupt. */
634	if (sc->irq_res != NULL) {
635		if (sc->intrhandle)
636			bus_teardown_intr(dev, sc->irq_res, sc->intrhandle);
637		bus_release_resource(dev, SYS_RES_IRQ,
638		    rman_get_rid(sc->irq_res), sc->irq_res);
639	}
640
641	/* Release memory resource. */
642	if (sc->mem_res != NULL)
643		bus_release_resource(dev, SYS_RES_MEMORY,
644		    rman_get_rid(sc->mem_res), sc->mem_res);
645
646	QSPI_SC_LOCK_DESTROY(sc);
647
648	return (0);
649}
650
651static phandle_t
652zy7_qspi_get_node(device_t bus, device_t dev)
653{
654
655	return (ofw_bus_get_node(bus));
656}
657
658static int
659zy7_qspi_transfer(device_t dev, device_t child, struct spi_command *cmd)
660{
661	struct zy7_qspi_softc *sc = device_get_softc(dev);
662	int err = 0;
663
664	KASSERT(cmd->tx_cmd_sz == cmd->rx_cmd_sz,
665	    ("TX/RX command sizes should be equal"));
666	KASSERT(cmd->tx_data_sz == cmd->rx_data_sz,
667	    ("TX/RX data sizes should be equal"));
668
669	if (sc->is_dual && cmd->tx_data_sz % 2 != 0) {
670		device_printf(dev, "driver does not support odd byte data "
671		    "transfers in dual mode. (sz=%d)\n", cmd->tx_data_sz);
672		return (EINVAL);
673	}
674
675	QSPI_SC_LOCK(sc);
676
677	/* Wait for controller available. */
678	while (sc->busy != 0) {
679		err = mtx_sleep(dev, &sc->sc_mtx, 0, "zqspi0", 0);
680		if (err) {
681			QSPI_SC_UNLOCK(sc);
682			return (err);
683		}
684	}
685
686	/* Start transfer. */
687	sc->busy = 1;
688	sc->cmd = cmd;
689	sc->tx_bytes = sc->cmd->tx_cmd_sz + sc->cmd->tx_data_sz;
690	sc->tx_bytes_sent = 0;
691	sc->rx_bytes = sc->cmd->rx_cmd_sz + sc->cmd->rx_data_sz;
692	sc->rx_bytes_rcvd = 0;
693
694	/* Enable interrupts.  zy7_qspi_intr() will handle transfer. */
695	WR4(sc, ZY7_QSPI_INTR_EN_REG,
696	    ZY7_QSPI_INTR_TX_FIFO_NOT_FULL |
697	    ZY7_QSPI_INTR_RX_OVERFLOW);
698
699#ifdef SPI_XFER_U_PAGE	/* XXX: future support for stacked memories. */
700	if (sc->is_stacked) {
701		if ((cmd->flags & SPI_XFER_U_PAGE) != 0)
702			sc->lqspi_cfg_shadow |= ZY7_QSPI_LQSPI_CFG_U_PAGE;
703		else
704			sc->lqspi_cfg_shadow &= ~ZY7_QSPI_LQSPI_CFG_U_PAGE;
705		WR4(sc, ZY7_QSPI_LQSPI_CFG_REG, sc->lqspi_cfg_shadow);
706	}
707#endif
708
709	/* Assert CS. */
710	sc->cfg_reg_shadow &= ~ZY7_QSPI_CONFIG_PCS;
711	WR4(sc, ZY7_QSPI_CONFIG_REG, sc->cfg_reg_shadow);
712
713	/* Wait for completion. */
714	err = mtx_sleep(dev, &sc->sc_mtx, 0, "zqspi1", hz * 2);
715	if (err)
716		zy7_qspi_abort_transfer(sc);
717
718	/* Release controller. */
719	sc->busy = 0;
720	wakeup_one(dev);
721
722	QSPI_SC_UNLOCK(sc);
723
724	return (err);
725}
726
727static device_method_t zy7_qspi_methods[] = {
728	/* Device interface */
729	DEVMETHOD(device_probe,		zy7_qspi_probe),
730	DEVMETHOD(device_attach,	zy7_qspi_attach),
731	DEVMETHOD(device_detach,	zy7_qspi_detach),
732
733	/* SPI interface */
734	DEVMETHOD(spibus_transfer,	zy7_qspi_transfer),
735
736	/* ofw_bus interface */
737	DEVMETHOD(ofw_bus_get_node,	zy7_qspi_get_node),
738
739	DEVMETHOD_END
740};
741
742static driver_t zy7_qspi_driver = {
743	"zy7_qspi",
744	zy7_qspi_methods,
745	sizeof(struct zy7_qspi_softc),
746};
747
748DRIVER_MODULE(zy7_qspi, simplebus, zy7_qspi_driver, 0, 0);
749DRIVER_MODULE(ofw_spibus, zy7_qspi, ofw_spibus_driver, 0, 0);
750SIMPLEBUS_PNP_INFO(compat_data);
751MODULE_DEPEND(zy7_qspi, ofw_spibus, 1, 1, 1);
752