2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2018 Thomas Skibo <thomasskibo@yahoo.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
33 * This is a driver for the Quad-SPI Flash Controller in the Xilinx
37 #include <sys/param.h>
38 #include <sys/systm.h>
40 #include <sys/kernel.h>
41 #include <sys/module.h>
42 #include <sys/sysctl.h>
44 #include <sys/mutex.h>
45 #include <sys/resource.h>
49 #include <machine/bus.h>
50 #include <machine/resource.h>
51 #include <machine/stdarg.h>
53 #include <dev/fdt/fdt_common.h>
54 #include <dev/ofw/ofw_bus.h>
55 #include <dev/ofw/ofw_bus_subr.h>
57 #include <dev/spibus/spi.h>
58 #include <dev/spibus/spibusvar.h>
60 #include <dev/flash/mx25lreg.h>
62 #include "spibus_if.h"
64 static struct ofw_compat_data compat_data[] = {
66 {"xlnx,zynq-qspi-1.0", 1},
70 struct zy7_qspi_softc {
74 struct resource *mem_res;
75 struct resource *irq_res;
78 uint32_t cfg_reg_shadow;
79 uint32_t lqspi_cfg_shadow;
82 unsigned int spi_clk_real_freq;
83 unsigned int rx_overflows;
84 unsigned int tx_underflows;
85 unsigned int interrupts;
86 unsigned int stray_ints;
87 struct spi_command *cmd;
88 int tx_bytes; /* tx_cmd_sz + tx_data_sz */
90 int rx_bytes; /* rx_cmd_sz + rx_data_sz */
98 #define ZY7_QSPI_DEFAULT_SPI_CLOCK 50000000
100 #define QSPI_SC_LOCK(sc) mtx_lock(&(sc)->sc_mtx)
101 #define QSPI_SC_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx)
102 #define QSPI_SC_LOCK_INIT(sc) \
103 mtx_init(&(sc)->sc_mtx, device_get_nameunit((sc)->dev), NULL, MTX_DEF)
104 #define QSPI_SC_LOCK_DESTROY(sc) mtx_destroy(&(sc)->sc_mtx)
105 #define QSPI_SC_ASSERT_LOCKED(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED)
107 #define RD4(sc, off) (bus_read_4((sc)->mem_res, (off)))
108 #define WR4(sc, off, val) (bus_write_4((sc)->mem_res, (off), (val)))
111 * QSPI device registers.
112 * Reference: Zynq-7000 All Programmable SoC Technical Reference Manual.
113 * (v1.12.2) July 1, 2018. Xilinx doc UG585.
115 #define ZY7_QSPI_CONFIG_REG 0x0000
116 #define ZY7_QSPI_CONFIG_IFMODE (1U << 31)
117 #define ZY7_QSPI_CONFIG_ENDIAN (1 << 26)
118 #define ZY7_QSPI_CONFIG_HOLDB_DR (1 << 19)
119 #define ZY7_QSPI_CONFIG_RSVD1 (1 << 17) /* must be 1 */
120 #define ZY7_QSPI_CONFIG_MANSTRT (1 << 16)
121 #define ZY7_QSPI_CONFIG_MANSTRTEN (1 << 15)
122 #define ZY7_QSPI_CONFIG_SSFORCE (1 << 14)
123 #define ZY7_QSPI_CONFIG_PCS (1 << 10)
124 #define ZY7_QSPI_CONFIG_REF_CLK (1 << 8)
125 #define ZY7_QSPI_CONFIG_FIFO_WIDTH_MASK (3 << 6)
126 #define ZY7_QSPI_CONFIG_FIFO_WIDTH32 (3 << 6)
127 #define ZY7_QSPI_CONFIG_BAUD_RATE_DIV_MASK (7 << 3)
128 #define ZY7_QSPI_CONFIG_BAUD_RATE_DIV_SHIFT 3
129 #define ZY7_QSPI_CONFIG_BAUD_RATE_DIV(x) ((x) << 3) /* divide by 2<<x */
130 #define ZY7_QSPI_CONFIG_CLK_PH (1 << 2) /* clock phase */
131 #define ZY7_QSPI_CONFIG_CLK_POL (1 << 1) /* clock polarity */
132 #define ZY7_QSPI_CONFIG_MODE_SEL (1 << 0) /* master enable */
134 #define ZY7_QSPI_INTR_STAT_REG 0x0004
135 #define ZY7_QSPI_INTR_EN_REG 0x0008
136 #define ZY7_QSPI_INTR_DIS_REG 0x000c
137 #define ZY7_QSPI_INTR_MASK_REG 0x0010
138 #define ZY7_QSPI_INTR_TX_FIFO_UNDERFLOW (1 << 6)
139 #define ZY7_QSPI_INTR_RX_FIFO_FULL (1 << 5)
140 #define ZY7_QSPI_INTR_RX_FIFO_NOT_EMPTY (1 << 4)
141 #define ZY7_QSPI_INTR_TX_FIFO_FULL (1 << 3)
142 #define ZY7_QSPI_INTR_TX_FIFO_NOT_FULL (1 << 2)
143 #define ZY7_QSPI_INTR_RX_OVERFLOW (1 << 0)
145 #define ZY7_QSPI_EN_REG 0x0014
146 #define ZY7_SPI_ENABLE 1
148 #define ZY7_QSPI_DELAY_REG 0x0018
149 #define ZY7_QSPI_DELAY_NSS_MASK (0xffU << 24)
150 #define ZY7_QSPI_DELAY_NSS_SHIFT 24
151 #define ZY7_QSPI_DELAY_NSS(x) ((x) << 24)
152 #define ZY7_QSPI_DELAY_BTWN_MASK (0xff << 16)
153 #define ZY7_QSPI_DELAY_BTWN_SHIFT 16
154 #define ZY7_QSPI_DELAY_BTWN(x) ((x) << 16)
155 #define ZY7_QSPI_DELAY_AFTER_MASK (0xff << 8)
156 #define ZY7_QSPI_DELAY_AFTER_SHIFT 8
157 #define ZY7_QSPI_DELAY_AFTER(x) ((x) << 8)
158 #define ZY7_QSPI_DELAY_INIT_MASK 0xff
159 #define ZY7_QSPI_DELAY_INIT_SHIFT 0
160 #define ZY7_QSPI_DELAY_INIT(x) (x)
162 #define ZY7_QSPI_TXD0_REG 0x001c
163 #define ZY7_QSPI_RX_DATA_REG 0x0020
165 #define ZY7_QSPI_SLV_IDLE_CT_REG 0x0024
166 #define ZY7_QSPI_SLV_IDLE_CT_MASK 0xff
168 #define ZY7_QSPI_TX_THRESH_REG 0x0028
169 #define ZY7_QSPI_RX_THRESH_REG 0x002c
171 #define ZY7_QSPI_GPIO_REG 0x0030
172 #define ZY7_QSPI_GPIO_WP_N 1
174 #define ZY7_QSPI_LPBK_DLY_ADJ_REG 0x0038
175 #define ZY7_QSPI_LPBK_DLY_ADJ_LPBK_SEL (1 << 8)
176 #define ZY7_QSPI_LPBK_DLY_ADJ_LPBK_PH (1 << 7)
177 #define ZY7_QSPI_LPBK_DLY_ADJ_USE_LPBK (1 << 5)
178 #define ZY7_QSPI_LPBK_DLY_ADJ_DLY1_MASK (3 << 3)
179 #define ZY7_QSPI_LPBK_DLY_ADJ_DLY1_SHIFT 3
180 #define ZY7_QSPI_LPBK_DLY_ADJ_DLY1(x) ((x) << 3)
181 #define ZY7_QSPI_LPBK_DLY_ADJ_DLY0_MASK 7
182 #define ZY7_QSPI_LPBK_DLY_ADJ_DLY0_SHIFT 0
183 #define ZY7_QSPI_LPBK_DLY_ADJ_DLY0(x) (x)
185 #define ZY7_QSPI_TXD1_REG 0x0080
186 #define ZY7_QSPI_TXD2_REG 0x0084
187 #define ZY7_QSPI_TXD3_REG 0x0088
189 #define ZY7_QSPI_LQSPI_CFG_REG 0x00a0
190 #define ZY7_QSPI_LQSPI_CFG_LINEAR (1U << 31)
191 #define ZY7_QSPI_LQSPI_CFG_TWO_MEM (1 << 30)
192 #define ZY7_QSPI_LQSPI_CFG_SEP_BUS (1 << 29)
193 #define ZY7_QSPI_LQSPI_CFG_U_PAGE (1 << 28)
194 #define ZY7_QSPI_LQSPI_CFG_MODE_EN (1 << 25)
195 #define ZY7_QSPI_LQSPI_CFG_MODE_ON (1 << 24)
196 #define ZY7_QSPI_LQSPI_CFG_MODE_BITS_MASK (0xff << 16)
197 #define ZY7_QSPI_LQSPI_CFG_MODE_BITS_SHIFT 16
198 #define ZY7_QSPI_LQSPI_CFG_MODE_BITS(x) ((x) << 16)
199 #define ZY7_QSPI_LQSPI_CFG_DUMMY_BYTES_MASK (7 << 8)
200 #define ZY7_QSPI_LQSPI_CFG_DUMMY_BYTES_SHIFT 8
201 #define ZY7_QSPI_LQSPI_CFG_DUMMY_BYTES(x) ((x) << 8)
202 #define ZY7_QSPI_LQSPI_CFG_INST_CODE_MASK 0xff
203 #define ZY7_QSPI_LQSPI_CFG_INST_CODE_SHIFT 0
204 #define ZY7_QSPI_LQSPI_CFG_INST_CODE(x) (x)
206 #define ZY7_QSPI_LQSPI_STS_REG 0x00a4
207 #define ZY7_QSPI_LQSPI_STS_D_FSM_ERR (1 << 2)
208 #define ZY7_QSPI_LQSPI_STS_WR_RECVD (1 << 1)
210 #define ZY7_QSPI_MOD_ID_REG 0x00fc
212 static int zy7_qspi_detach(device_t);
214 /* Fill hardware fifo with command and data bytes. */
216 zy7_qspi_write_fifo(struct zy7_qspi_softc *sc, int nbytes)
222 nvalid = MIN(4, nbytes);
226 * A hardware bug forces us to wait until the tx fifo is
227 * empty before writing partial words. We'll come back
230 if (nvalid < 4 && (RD4(sc, ZY7_QSPI_INTR_STAT_REG) &
231 ZY7_QSPI_INTR_TX_FIFO_NOT_FULL) == 0)
234 if (sc->tx_bytes_sent < sc->cmd->tx_cmd_sz) {
235 /* Writing command. */
236 n = MIN(nvalid, sc->cmd->tx_cmd_sz -
238 memcpy(&data, (uint8_t *)sc->cmd->tx_cmd +
239 sc->tx_bytes_sent, n);
242 /* Writing start of data. */
243 memcpy((uint8_t *)&data + n,
244 sc->cmd->tx_data, nvalid - n);
248 memcpy(&data, (uint8_t *)sc->cmd->tx_data +
249 (sc->tx_bytes_sent - sc->cmd->tx_cmd_sz), nvalid);
253 WR4(sc, ZY7_QSPI_TXD1_REG, data);
256 WR4(sc, ZY7_QSPI_TXD2_REG, data);
259 WR4(sc, ZY7_QSPI_TXD3_REG, data);
262 WR4(sc, ZY7_QSPI_TXD0_REG, data);
266 sc->tx_bytes_sent += nvalid;
272 /* Read hardware fifo data into command response and data buffers. */
274 zy7_qspi_read_fifo(struct zy7_qspi_softc *sc)
280 data = RD4(sc, ZY7_QSPI_RX_DATA_REG);
281 nbytes = MIN(4, sc->rx_bytes - sc->rx_bytes_rcvd);
284 * Last word in non-word-multiple transfer is packed
288 data >>= 8 * (4 - nbytes);
290 if (sc->rx_bytes_rcvd < sc->cmd->rx_cmd_sz) {
291 /* Reading command. */
292 n = MIN(nbytes, sc->cmd->rx_cmd_sz -
294 memcpy((uint8_t *)sc->cmd->rx_cmd + sc->rx_bytes_rcvd,
296 sc->rx_bytes_rcvd += n;
303 memcpy((uint8_t *)sc->cmd->rx_data +
304 (sc->rx_bytes_rcvd - sc->cmd->rx_cmd_sz),
306 sc->rx_bytes_rcvd += nbytes;
309 } while (sc->rx_bytes_rcvd < sc->rx_bytes &&
310 (RD4(sc, ZY7_QSPI_INTR_STAT_REG) &
311 ZY7_QSPI_INTR_RX_FIFO_NOT_EMPTY) != 0);
314 /* End a transfer early by draining rx fifo and disabling interrupts. */
316 zy7_qspi_abort_transfer(struct zy7_qspi_softc *sc)
318 /* Drain receive fifo. */
319 while ((RD4(sc, ZY7_QSPI_INTR_STAT_REG) &
320 ZY7_QSPI_INTR_RX_FIFO_NOT_EMPTY) != 0)
321 (void)RD4(sc, ZY7_QSPI_RX_DATA_REG);
323 /* Shut down interrupts. */
324 WR4(sc, ZY7_QSPI_INTR_DIS_REG,
325 ZY7_QSPI_INTR_RX_OVERFLOW |
326 ZY7_QSPI_INTR_RX_FIFO_NOT_EMPTY |
327 ZY7_QSPI_INTR_TX_FIFO_NOT_FULL);
332 zy7_qspi_intr(void *arg)
334 struct zy7_qspi_softc *sc = (struct zy7_qspi_softc *)arg;
341 istatus = RD4(sc, ZY7_QSPI_INTR_STAT_REG);
343 /* Stray interrupts can happen if a transfer gets interrupted. */
350 if ((istatus & ZY7_QSPI_INTR_RX_OVERFLOW) != 0) {
351 device_printf(sc->dev, "rx fifo overflow!\n");
354 /* Clear status bit. */
355 WR4(sc, ZY7_QSPI_INTR_STAT_REG,
356 ZY7_QSPI_INTR_RX_OVERFLOW);
359 /* Empty receive fifo before any more transmit data is sent. */
360 if (sc->rx_bytes_rcvd < sc->rx_bytes &&
361 (istatus & ZY7_QSPI_INTR_RX_FIFO_NOT_EMPTY) != 0) {
362 zy7_qspi_read_fifo(sc);
363 if (sc->rx_bytes_rcvd == sc->rx_bytes)
364 /* Disable receive interrupts. */
365 WR4(sc, ZY7_QSPI_INTR_DIS_REG,
366 ZY7_QSPI_INTR_RX_FIFO_NOT_EMPTY |
367 ZY7_QSPI_INTR_RX_OVERFLOW);
371 * Transmit underflows aren't really a bug because a hardware
372 * bug forces us to allow the tx fifo to go empty between full
373 * and partial fifo writes. Why bother counting?
375 if ((istatus & ZY7_QSPI_INTR_TX_FIFO_UNDERFLOW) != 0) {
378 /* Clear status bit. */
379 WR4(sc, ZY7_QSPI_INTR_STAT_REG,
380 ZY7_QSPI_INTR_TX_FIFO_UNDERFLOW);
383 /* Fill transmit fifo. */
384 if (sc->tx_bytes_sent < sc->tx_bytes &&
385 (istatus & ZY7_QSPI_INTR_TX_FIFO_NOT_FULL) != 0) {
386 zy7_qspi_write_fifo(sc, MIN(240, sc->tx_bytes -
389 if (sc->tx_bytes_sent == sc->tx_bytes) {
391 * Disable transmit FIFO interrupt, enable receive
394 WR4(sc, ZY7_QSPI_INTR_DIS_REG,
395 ZY7_QSPI_INTR_TX_FIFO_NOT_FULL);
396 WR4(sc, ZY7_QSPI_INTR_EN_REG,
397 ZY7_QSPI_INTR_RX_FIFO_NOT_EMPTY);
401 /* Finished with transfer? */
402 if (sc->tx_bytes_sent == sc->tx_bytes &&
403 sc->rx_bytes_rcvd == sc->rx_bytes) {
406 sc->cfg_reg_shadow |= ZY7_QSPI_CONFIG_PCS;
407 WR4(sc, ZY7_QSPI_CONFIG_REG, sc->cfg_reg_shadow);
415 /* Initialize hardware. */
417 zy7_qspi_init_hw(struct zy7_qspi_softc *sc)
421 /* Configure LQSPI Config register. Disable linear mode. */
422 sc->lqspi_cfg_shadow = RD4(sc, ZY7_QSPI_LQSPI_CFG_REG);
423 sc->lqspi_cfg_shadow &= ~(ZY7_QSPI_LQSPI_CFG_LINEAR |
424 ZY7_QSPI_LQSPI_CFG_TWO_MEM |
425 ZY7_QSPI_LQSPI_CFG_SEP_BUS);
427 sc->lqspi_cfg_shadow |= ZY7_QSPI_LQSPI_CFG_TWO_MEM;
428 if (sc->is_stacked) {
429 sc->lqspi_cfg_shadow &=
430 ~ZY7_QSPI_LQSPI_CFG_INST_CODE_MASK;
431 sc->lqspi_cfg_shadow |=
432 ZY7_QSPI_LQSPI_CFG_INST_CODE(sc->is_dio ?
433 CMD_READ_DUAL_IO : CMD_READ_QUAD_OUTPUT);
435 sc->lqspi_cfg_shadow |= ZY7_QSPI_LQSPI_CFG_SEP_BUS;
437 WR4(sc, ZY7_QSPI_LQSPI_CFG_REG, sc->lqspi_cfg_shadow);
439 /* Find best clock divider. */
441 while ((sc->ref_clock >> (baud_div + 1)) > sc->spi_clock &&
445 device_printf(sc->dev, "cannot configure clock divider: ref=%d"
446 " spi=%d.\n", sc->ref_clock, sc->spi_clock);
449 sc->spi_clk_real_freq = sc->ref_clock >> (baud_div + 1);
452 * If divider is 2 (the max speed), use internal loopback master
453 * clock for read data. (See section 12.3.1 in ref man.)
456 WR4(sc, ZY7_QSPI_LPBK_DLY_ADJ_REG,
457 ZY7_QSPI_LPBK_DLY_ADJ_USE_LPBK |
458 ZY7_QSPI_LPBK_DLY_ADJ_DLY1(0) |
459 ZY7_QSPI_LPBK_DLY_ADJ_DLY0(0));
461 WR4(sc, ZY7_QSPI_LPBK_DLY_ADJ_REG, 0);
463 /* Set up configuration register. */
465 ZY7_QSPI_CONFIG_IFMODE |
466 ZY7_QSPI_CONFIG_HOLDB_DR |
467 ZY7_QSPI_CONFIG_RSVD1 |
468 ZY7_QSPI_CONFIG_SSFORCE |
469 ZY7_QSPI_CONFIG_PCS |
470 ZY7_QSPI_CONFIG_FIFO_WIDTH32 |
471 ZY7_QSPI_CONFIG_BAUD_RATE_DIV(baud_div) |
472 ZY7_QSPI_CONFIG_MODE_SEL;
473 WR4(sc, ZY7_QSPI_CONFIG_REG, sc->cfg_reg_shadow);
476 * Set thresholds. We must use 1 for tx threshold because there
477 * is no fifo empty flag and we need one to implement a bug
480 WR4(sc, ZY7_QSPI_TX_THRESH_REG, 1);
481 WR4(sc, ZY7_QSPI_RX_THRESH_REG, 1);
483 /* Clear and disable all interrupts. */
484 WR4(sc, ZY7_QSPI_INTR_STAT_REG, ~0);
485 WR4(sc, ZY7_QSPI_INTR_DIS_REG, ~0);
488 WR4(sc, ZY7_QSPI_EN_REG, ZY7_SPI_ENABLE);
495 zy7_qspi_add_sysctls(device_t dev)
497 struct zy7_qspi_softc *sc = device_get_softc(dev);
498 struct sysctl_ctx_list *ctx;
499 struct sysctl_oid_list *child;
501 ctx = device_get_sysctl_ctx(dev);
502 child = SYSCTL_CHILDREN(device_get_sysctl_tree(dev));
504 SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "spi_clk_real_freq", CTLFLAG_RD,
505 &sc->spi_clk_real_freq, 0, "SPI clock real frequency");
507 SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "rx_overflows", CTLFLAG_RD,
508 &sc->rx_overflows, 0, "RX FIFO overflow events");
510 SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "tx_underflows", CTLFLAG_RD,
511 &sc->tx_underflows, 0, "TX FIFO underflow events");
513 SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "interrupts", CTLFLAG_RD,
514 &sc->interrupts, 0, "interrupt calls");
516 SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "stray_ints", CTLFLAG_RD,
517 &sc->stray_ints, 0, "stray interrupts");
522 zy7_qspi_probe(device_t dev)
525 if (!ofw_bus_status_okay(dev))
528 if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
531 device_set_desc(dev, "Zynq Quad-SPI Flash Controller");
533 return (BUS_PROBE_DEFAULT);
538 zy7_qspi_attach(device_t dev)
540 struct zy7_qspi_softc *sc;
545 sc = device_get_softc(dev);
548 QSPI_SC_LOCK_INIT(sc);
550 /* Get ref-clock, spi-clock, and other properties. */
551 node = ofw_bus_get_node(dev);
552 if (OF_getprop(node, "ref-clock", &cell, sizeof(cell)) > 0)
553 sc->ref_clock = fdt32_to_cpu(cell);
555 device_printf(dev, "must have ref-clock property\n");
558 if (OF_getprop(node, "spi-clock", &cell, sizeof(cell)) > 0)
559 sc->spi_clock = fdt32_to_cpu(cell);
561 sc->spi_clock = ZY7_QSPI_DEFAULT_SPI_CLOCK;
562 if (OF_getprop(node, "is-stacked", &cell, sizeof(cell)) > 0 &&
563 fdt32_to_cpu(cell) != 0) {
566 } else if (OF_getprop(node, "is-dual", &cell, sizeof(cell)) > 0 &&
567 fdt32_to_cpu(cell) != 0)
569 if (OF_getprop(node, "is-dio", &cell, sizeof(cell)) > 0 &&
570 fdt32_to_cpu(cell) != 0)
573 /* Get memory resource. */
575 sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
577 if (sc->mem_res == NULL) {
578 device_printf(dev, "could not allocate memory resources.\n");
579 zy7_qspi_detach(dev);
585 sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
587 if (sc->irq_res == NULL) {
588 device_printf(dev, "could not allocate IRQ resource.\n");
589 zy7_qspi_detach(dev);
593 /* Activate the interrupt. */
594 err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
595 NULL, zy7_qspi_intr, sc, &sc->intrhandle);
597 device_printf(dev, "could not setup IRQ.\n");
598 zy7_qspi_detach(dev);
602 /* Configure the device. */
603 err = zy7_qspi_init_hw(sc);
605 zy7_qspi_detach(dev);
609 sc->child = device_add_child(dev, "spibus", -1);
611 zy7_qspi_add_sysctls(dev);
613 /* Attach spibus driver as a child later when interrupts work. */
614 config_intrhook_oneshot((ich_func_t)bus_generic_attach, dev);
620 zy7_qspi_detach(device_t dev)
622 struct zy7_qspi_softc *sc = device_get_softc(dev);
624 if (device_is_attached(dev))
625 bus_generic_detach(dev);
627 /* Delete child bus. */
629 device_delete_child(dev, sc->child);
631 /* Disable hardware. */
632 if (sc->mem_res != NULL) {
634 WR4(sc, ZY7_QSPI_EN_REG, 0);
636 /* Clear and disable all interrupts. */
637 WR4(sc, ZY7_QSPI_INTR_STAT_REG, ~0);
638 WR4(sc, ZY7_QSPI_INTR_DIS_REG, ~0);
641 /* Teardown and release interrupt. */
642 if (sc->irq_res != NULL) {
644 bus_teardown_intr(dev, sc->irq_res, sc->intrhandle);
645 bus_release_resource(dev, SYS_RES_IRQ,
646 rman_get_rid(sc->irq_res), sc->irq_res);
649 /* Release memory resource. */
650 if (sc->mem_res != NULL)
651 bus_release_resource(dev, SYS_RES_MEMORY,
652 rman_get_rid(sc->mem_res), sc->mem_res);
654 QSPI_SC_LOCK_DESTROY(sc);
661 zy7_qspi_get_node(device_t bus, device_t dev)
664 return (ofw_bus_get_node(bus));
669 zy7_qspi_transfer(device_t dev, device_t child, struct spi_command *cmd)
671 struct zy7_qspi_softc *sc = device_get_softc(dev);
674 KASSERT(cmd->tx_cmd_sz == cmd->rx_cmd_sz,
675 ("TX/RX command sizes should be equal"));
676 KASSERT(cmd->tx_data_sz == cmd->rx_data_sz,
677 ("TX/RX data sizes should be equal"));
679 if (sc->is_dual && cmd->tx_data_sz % 2 != 0) {
680 device_printf(dev, "driver does not support odd byte data "
681 "transfers in dual mode. (sz=%d)\n", cmd->tx_data_sz);
687 /* Wait for controller available. */
688 while (sc->busy != 0) {
689 err = mtx_sleep(dev, &sc->sc_mtx, 0, "zqspi0", 0);
696 /* Start transfer. */
699 sc->tx_bytes = sc->cmd->tx_cmd_sz + sc->cmd->tx_data_sz;
700 sc->tx_bytes_sent = 0;
701 sc->rx_bytes = sc->cmd->rx_cmd_sz + sc->cmd->rx_data_sz;
702 sc->rx_bytes_rcvd = 0;
704 /* Enable interrupts. zy7_qspi_intr() will handle transfer. */
705 WR4(sc, ZY7_QSPI_INTR_EN_REG,
706 ZY7_QSPI_INTR_TX_FIFO_NOT_FULL |
707 ZY7_QSPI_INTR_RX_OVERFLOW);
709 #ifdef SPI_XFER_U_PAGE /* XXX: future support for stacked memories. */
710 if (sc->is_stacked) {
711 if ((cmd->flags & SPI_XFER_U_PAGE) != 0)
712 sc->lqspi_cfg_shadow |= ZY7_QSPI_LQSPI_CFG_U_PAGE;
714 sc->lqspi_cfg_shadow &= ~ZY7_QSPI_LQSPI_CFG_U_PAGE;
715 WR4(sc, ZY7_QSPI_LQSPI_CFG_REG, sc->lqspi_cfg_shadow);
720 sc->cfg_reg_shadow &= ~ZY7_QSPI_CONFIG_PCS;
721 WR4(sc, ZY7_QSPI_CONFIG_REG, sc->cfg_reg_shadow);
723 /* Wait for completion. */
724 err = mtx_sleep(dev, &sc->sc_mtx, 0, "zqspi1", hz * 2);
726 zy7_qspi_abort_transfer(sc);
728 /* Release controller. */
737 static device_method_t zy7_qspi_methods[] = {
738 /* Device interface */
739 DEVMETHOD(device_probe, zy7_qspi_probe),
740 DEVMETHOD(device_attach, zy7_qspi_attach),
741 DEVMETHOD(device_detach, zy7_qspi_detach),
744 DEVMETHOD(spibus_transfer, zy7_qspi_transfer),
746 /* ofw_bus interface */
747 DEVMETHOD(ofw_bus_get_node, zy7_qspi_get_node),
753 static driver_t zy7_qspi_driver = {
756 sizeof(struct zy7_qspi_softc),
758 static devclass_t zy7_qspi_devclass;
760 DRIVER_MODULE(zy7_qspi, simplebus, zy7_qspi_driver, zy7_qspi_devclass, 0, 0);
761 DRIVER_MODULE(ofw_spibus, zy7_qspi, ofw_spibus_driver, ofw_spibus_devclass, 0, 0);
762 SIMPLEBUS_PNP_INFO(compat_data);
763 MODULE_DEPEND(zy7_qspi, ofw_spibus, 1, 1, 1);