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
62 static struct ofw_compat_data compat_data[] = {
63 {"xlnx,zy7_qspi", 1},
64 {"xlnx,zynq-qspi-1.0", 1},
65 {NULL, 0}
66 };
67
68 struct 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
210 static int zy7_qspi_detach(device_t);
211
212 /* Fill hardware fifo with command and data bytes. */
213 static void
zy7_qspi_write_fifo(struct zy7_qspi_softc * sc,int nbytes)214 zy7_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. */
270 static void
zy7_qspi_read_fifo(struct zy7_qspi_softc * sc)271 zy7_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. */
312 static void
zy7_qspi_abort_transfer(struct zy7_qspi_softc * sc)313 zy7_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
327 static void
zy7_qspi_intr(void * arg)328 zy7_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. */
411 static int
zy7_qspi_init_hw(struct zy7_qspi_softc * sc)412 zy7_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
488 static void
zy7_qspi_add_sysctls(device_t dev)489 zy7_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
514 static int
zy7_qspi_probe(device_t dev)515 zy7_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
529 static int
zy7_qspi_attach(device_t dev)530 zy7_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", DEVICE_UNIT_ANY);
602
603 zy7_qspi_add_sysctls(dev);
604
605 /* Attach spibus driver as a child later when interrupts work. */
606 bus_delayed_attach_children(dev);
607
608 return (0);
609 }
610
611 static int
zy7_qspi_detach(device_t dev)612 zy7_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
651 static phandle_t
zy7_qspi_get_node(device_t bus,device_t dev)652 zy7_qspi_get_node(device_t bus, device_t dev)
653 {
654
655 return (ofw_bus_get_node(bus));
656 }
657
658 static int
zy7_qspi_transfer(device_t dev,device_t child,struct spi_command * cmd)659 zy7_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
727 static 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
742 static driver_t zy7_qspi_driver = {
743 "zy7_qspi",
744 zy7_qspi_methods,
745 sizeof(struct zy7_qspi_softc),
746 };
747
748 DRIVER_MODULE(zy7_qspi, simplebus, zy7_qspi_driver, 0, 0);
749 DRIVER_MODULE(ofw_spibus, zy7_qspi, ofw_spibus_driver, 0, 0);
750 SIMPLEBUS_PNP_INFO(compat_data);
751 MODULE_DEPEND(zy7_qspi, ofw_spibus, 1, 1, 1);
752