]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm/xilinx/zy7_qspi.c
Merge bmake-20201117
[FreeBSD/FreeBSD.git] / sys / arm / xilinx / zy7_qspi.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
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 __FBSDID("$FreeBSD$");
31
32 /*
33  * This is a driver for the Quad-SPI Flash Controller in the Xilinx
34  * Zynq-7000 SoC.
35  */
36
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/conf.h>
40 #include <sys/kernel.h>
41 #include <sys/module.h>
42 #include <sys/sysctl.h>
43 #include <sys/lock.h>
44 #include <sys/mutex.h>
45 #include <sys/resource.h>
46 #include <sys/rman.h>
47 #include <sys/uio.h>
48
49 #include <machine/bus.h>
50 #include <machine/resource.h>
51 #include <machine/stdarg.h>
52
53 #include <dev/fdt/fdt_common.h>
54 #include <dev/ofw/ofw_bus.h>
55 #include <dev/ofw/ofw_bus_subr.h>
56
57 #include <dev/spibus/spi.h>
58 #include <dev/spibus/spibusvar.h>
59
60 #include <dev/flash/mx25lreg.h>
61
62 #include "spibus_if.h"
63
64 static struct ofw_compat_data compat_data[] = {
65         {"xlnx,zy7_qspi",               1},
66         {"xlnx,zynq-qspi-1.0",          1},
67         {NULL,                          0}
68 };
69
70 struct zy7_qspi_softc {
71         device_t                dev;
72         device_t                child;
73         struct mtx              sc_mtx;
74         struct resource         *mem_res;
75         struct resource         *irq_res;
76         void                    *intrhandle;
77
78         uint32_t                cfg_reg_shadow;
79         uint32_t                lqspi_cfg_shadow;
80         uint32_t                spi_clock;
81         uint32_t                ref_clock;
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 */
89         int                     tx_bytes_sent;
90         int                     rx_bytes;       /* rx_cmd_sz + rx_data_sz */
91         int                     rx_bytes_rcvd;
92         int                     busy;
93         int                     is_dual;
94         int                     is_stacked;
95         int                     is_dio;
96 };
97
98 #define ZY7_QSPI_DEFAULT_SPI_CLOCK      50000000
99
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)
106
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)))
109
110 /*
111  * QSPI device registers.
112  * Reference: Zynq-7000 All Programmable SoC Technical Reference Manual.
113  * (v1.12.2) July 1, 2018.  Xilinx doc UG585.
114  */
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 */
133
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)
144
145 #define ZY7_QSPI_EN_REG                 0x0014
146 #define   ZY7_SPI_ENABLE                        1
147
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)
161
162 #define ZY7_QSPI_TXD0_REG               0x001c
163 #define ZY7_QSPI_RX_DATA_REG            0x0020
164
165 #define ZY7_QSPI_SLV_IDLE_CT_REG        0x0024
166 #define   ZY7_QSPI_SLV_IDLE_CT_MASK             0xff
167
168 #define ZY7_QSPI_TX_THRESH_REG          0x0028
169 #define ZY7_QSPI_RX_THRESH_REG          0x002c
170
171 #define ZY7_QSPI_GPIO_REG               0x0030
172 #define   ZY7_QSPI_GPIO_WP_N                    1
173
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)
184
185 #define ZY7_QSPI_TXD1_REG               0x0080
186 #define ZY7_QSPI_TXD2_REG               0x0084
187 #define ZY7_QSPI_TXD3_REG               0x0088
188
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)
205
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)
209
210 #define ZY7_QSPI_MOD_ID_REG             0x00fc
211
212 static int zy7_qspi_detach(device_t);
213
214 /* Fill hardware fifo with command and data bytes. */
215 static void
216 zy7_qspi_write_fifo(struct zy7_qspi_softc *sc, int nbytes)
217 {
218         int n, nvalid;
219         uint32_t data;
220
221         while (nbytes > 0) {
222                 nvalid = MIN(4, nbytes);
223                 data = 0xffffffff;
224
225                 /*
226                  * A hardware bug forces us to wait until the tx fifo is
227                  * empty before writing partial words.  We'll come back
228                  * next tx interrupt.
229                  */
230                 if (nvalid < 4 && (RD4(sc, ZY7_QSPI_INTR_STAT_REG) &
231                     ZY7_QSPI_INTR_TX_FIFO_NOT_FULL) == 0)
232                         return;
233
234                 if (sc->tx_bytes_sent < sc->cmd->tx_cmd_sz) {
235                         /* Writing command. */
236                         n = MIN(nvalid, sc->cmd->tx_cmd_sz -
237                             sc->tx_bytes_sent);
238                         memcpy(&data, (uint8_t *)sc->cmd->tx_cmd +
239                             sc->tx_bytes_sent, n);
240
241                         if (nvalid > n) {
242                                 /* Writing start of data. */
243                                 memcpy((uint8_t *)&data + n,
244                                     sc->cmd->tx_data, nvalid - n);
245                         }
246                 } else
247                         /* Writing data. */
248                         memcpy(&data, (uint8_t *)sc->cmd->tx_data +
249                             (sc->tx_bytes_sent - sc->cmd->tx_cmd_sz), nvalid);
250
251                 switch (nvalid) {
252                 case 1:
253                         WR4(sc, ZY7_QSPI_TXD1_REG, data);
254                         break;
255                 case 2:
256                         WR4(sc, ZY7_QSPI_TXD2_REG, data);
257                         break;
258                 case 3:
259                         WR4(sc, ZY7_QSPI_TXD3_REG, data);
260                         break;
261                 case 4:
262                         WR4(sc, ZY7_QSPI_TXD0_REG, data);
263                         break;
264                 }
265
266                 sc->tx_bytes_sent += nvalid;
267                 nbytes -= nvalid;
268         }
269 }
270
271 /* Read hardware fifo data into command response and data buffers. */
272 static void
273 zy7_qspi_read_fifo(struct zy7_qspi_softc *sc)
274 {
275         int n, nbytes;
276         uint32_t data;
277
278         do {
279                 data = RD4(sc, ZY7_QSPI_RX_DATA_REG);
280                 nbytes = MIN(4, sc->rx_bytes - sc->rx_bytes_rcvd);
281
282                 /*
283                  * Last word in non-word-multiple transfer is packed
284                  * non-intuitively.
285                  */
286                 if (nbytes < 4)
287                         data >>= 8 * (4 - nbytes);
288
289                 if (sc->rx_bytes_rcvd < sc->cmd->rx_cmd_sz) {
290                         /* Reading command. */
291                         n = MIN(nbytes, sc->cmd->rx_cmd_sz -
292                             sc->rx_bytes_rcvd);
293                         memcpy((uint8_t *)sc->cmd->rx_cmd + sc->rx_bytes_rcvd,
294                             &data, n);
295                         sc->rx_bytes_rcvd += n;
296                         nbytes -= n;
297                         data >>= 8 * n;
298                 }
299
300                 if (nbytes > 0) {
301                         /* Reading data. */
302                         memcpy((uint8_t *)sc->cmd->rx_data +
303                             (sc->rx_bytes_rcvd - sc->cmd->rx_cmd_sz),
304                             &data, nbytes);
305                         sc->rx_bytes_rcvd += nbytes;
306                 }
307
308         } while (sc->rx_bytes_rcvd < sc->rx_bytes &&
309                  (RD4(sc, ZY7_QSPI_INTR_STAT_REG) &
310                   ZY7_QSPI_INTR_RX_FIFO_NOT_EMPTY) != 0);
311 }
312
313 /* End a transfer early by draining rx fifo and disabling interrupts. */
314 static void
315 zy7_qspi_abort_transfer(struct zy7_qspi_softc *sc)
316 {
317         /* Drain receive fifo. */
318         while ((RD4(sc, ZY7_QSPI_INTR_STAT_REG) &
319                 ZY7_QSPI_INTR_RX_FIFO_NOT_EMPTY) != 0)
320                 (void)RD4(sc, ZY7_QSPI_RX_DATA_REG);
321
322         /* Shut down interrupts. */
323         WR4(sc, ZY7_QSPI_INTR_DIS_REG,
324             ZY7_QSPI_INTR_RX_OVERFLOW |
325             ZY7_QSPI_INTR_RX_FIFO_NOT_EMPTY |
326             ZY7_QSPI_INTR_TX_FIFO_NOT_FULL);
327 }
328
329 static void
330 zy7_qspi_intr(void *arg)
331 {
332         struct zy7_qspi_softc *sc = (struct zy7_qspi_softc *)arg;
333         uint32_t istatus;
334
335         QSPI_SC_LOCK(sc);
336
337         sc->interrupts++;
338
339         istatus = RD4(sc, ZY7_QSPI_INTR_STAT_REG);
340
341         /* Stray interrupts can happen if a transfer gets interrupted. */
342         if (!sc->busy) {
343                 sc->stray_ints++;
344                 QSPI_SC_UNLOCK(sc);
345                 return;
346         }
347
348         if ((istatus & ZY7_QSPI_INTR_RX_OVERFLOW) != 0) {
349                 device_printf(sc->dev, "rx fifo overflow!\n");
350                 sc->rx_overflows++;
351
352                 /* Clear status bit. */
353                 WR4(sc, ZY7_QSPI_INTR_STAT_REG,
354                     ZY7_QSPI_INTR_RX_OVERFLOW);
355         }
356
357         /* Empty receive fifo before any more transmit data is sent. */
358         if (sc->rx_bytes_rcvd < sc->rx_bytes &&
359             (istatus & ZY7_QSPI_INTR_RX_FIFO_NOT_EMPTY) != 0) {
360                 zy7_qspi_read_fifo(sc);
361                 if (sc->rx_bytes_rcvd == sc->rx_bytes)
362                         /* Disable receive interrupts. */
363                         WR4(sc, ZY7_QSPI_INTR_DIS_REG,
364                             ZY7_QSPI_INTR_RX_FIFO_NOT_EMPTY |
365                             ZY7_QSPI_INTR_RX_OVERFLOW);
366         }
367
368         /*
369          * Transmit underflows aren't really a bug because a hardware
370          * bug forces us to allow the tx fifo to go empty between full
371          * and partial fifo writes.  Why bother counting?
372          */
373         if ((istatus & ZY7_QSPI_INTR_TX_FIFO_UNDERFLOW) != 0) {
374                 sc->tx_underflows++;
375
376                 /* Clear status bit. */
377                 WR4(sc, ZY7_QSPI_INTR_STAT_REG,
378                     ZY7_QSPI_INTR_TX_FIFO_UNDERFLOW);
379         }
380
381         /* Fill transmit fifo. */
382         if (sc->tx_bytes_sent < sc->tx_bytes &&
383             (istatus & ZY7_QSPI_INTR_TX_FIFO_NOT_FULL) != 0) {
384                 zy7_qspi_write_fifo(sc, MIN(240, sc->tx_bytes -
385                         sc->tx_bytes_sent));
386
387                 if (sc->tx_bytes_sent == sc->tx_bytes) {
388                         /*
389                          * Disable transmit FIFO interrupt, enable receive
390                          * FIFO interrupt.
391                          */
392                         WR4(sc, ZY7_QSPI_INTR_DIS_REG,
393                             ZY7_QSPI_INTR_TX_FIFO_NOT_FULL);
394                         WR4(sc, ZY7_QSPI_INTR_EN_REG,
395                             ZY7_QSPI_INTR_RX_FIFO_NOT_EMPTY);
396                 }
397         }
398
399         /* Finished with transfer? */
400         if (sc->tx_bytes_sent == sc->tx_bytes &&
401             sc->rx_bytes_rcvd == sc->rx_bytes) {
402                 /* De-assert CS. */
403                 sc->cfg_reg_shadow |= ZY7_QSPI_CONFIG_PCS;
404                 WR4(sc, ZY7_QSPI_CONFIG_REG, sc->cfg_reg_shadow);
405
406                 wakeup(sc->dev);
407         }
408
409         QSPI_SC_UNLOCK(sc);
410 }
411
412 /* Initialize hardware. */
413 static int
414 zy7_qspi_init_hw(struct zy7_qspi_softc *sc)
415 {
416         uint32_t baud_div;
417
418         /* Configure LQSPI Config register.  Disable linear mode. */
419         sc->lqspi_cfg_shadow = RD4(sc, ZY7_QSPI_LQSPI_CFG_REG);
420         sc->lqspi_cfg_shadow &= ~(ZY7_QSPI_LQSPI_CFG_LINEAR |
421                                   ZY7_QSPI_LQSPI_CFG_TWO_MEM |
422                                   ZY7_QSPI_LQSPI_CFG_SEP_BUS);
423         if (sc->is_dual) {
424                 sc->lqspi_cfg_shadow |= ZY7_QSPI_LQSPI_CFG_TWO_MEM;
425                 if (sc->is_stacked) {
426                         sc->lqspi_cfg_shadow &=
427                             ~ZY7_QSPI_LQSPI_CFG_INST_CODE_MASK;
428                         sc->lqspi_cfg_shadow |=
429                             ZY7_QSPI_LQSPI_CFG_INST_CODE(sc->is_dio ?
430                                 CMD_READ_DUAL_IO : CMD_READ_QUAD_OUTPUT);
431                 } else
432                         sc->lqspi_cfg_shadow |= ZY7_QSPI_LQSPI_CFG_SEP_BUS;
433         }
434         WR4(sc, ZY7_QSPI_LQSPI_CFG_REG, sc->lqspi_cfg_shadow);
435
436         /* Find best clock divider. */
437         baud_div = 0;
438         while ((sc->ref_clock >> (baud_div + 1)) > sc->spi_clock &&
439                baud_div < 8)
440                 baud_div++;
441         if (baud_div >= 8) {
442                 device_printf(sc->dev, "cannot configure clock divider: ref=%d"
443                     " spi=%d.\n", sc->ref_clock, sc->spi_clock);
444                 return (EINVAL);
445         }
446         sc->spi_clk_real_freq = sc->ref_clock >> (baud_div + 1);
447
448         /*
449          * If divider is 2 (the max speed), use internal loopback master
450          * clock for read data.  (See section 12.3.1 in ref man.)
451          */
452         if (baud_div == 0)
453                 WR4(sc, ZY7_QSPI_LPBK_DLY_ADJ_REG,
454                     ZY7_QSPI_LPBK_DLY_ADJ_USE_LPBK |
455                     ZY7_QSPI_LPBK_DLY_ADJ_DLY1(0) |
456                     ZY7_QSPI_LPBK_DLY_ADJ_DLY0(0));
457         else
458                 WR4(sc, ZY7_QSPI_LPBK_DLY_ADJ_REG, 0);
459
460         /* Set up configuration register. */
461         sc->cfg_reg_shadow =
462                 ZY7_QSPI_CONFIG_IFMODE |
463                 ZY7_QSPI_CONFIG_HOLDB_DR |
464                 ZY7_QSPI_CONFIG_RSVD1 |
465                 ZY7_QSPI_CONFIG_SSFORCE |
466                 ZY7_QSPI_CONFIG_PCS |
467                 ZY7_QSPI_CONFIG_FIFO_WIDTH32 |
468                 ZY7_QSPI_CONFIG_BAUD_RATE_DIV(baud_div) |
469                 ZY7_QSPI_CONFIG_MODE_SEL;
470         WR4(sc, ZY7_QSPI_CONFIG_REG, sc->cfg_reg_shadow);
471
472         /*
473          * Set thresholds.  We must use 1 for tx threshold because there
474          * is no fifo empty flag and we need one to implement a bug
475          * workaround.
476          */
477         WR4(sc, ZY7_QSPI_TX_THRESH_REG, 1);
478         WR4(sc, ZY7_QSPI_RX_THRESH_REG, 1);
479
480         /* Clear and disable all interrupts. */
481         WR4(sc, ZY7_QSPI_INTR_STAT_REG, ~0);
482         WR4(sc, ZY7_QSPI_INTR_DIS_REG, ~0);
483
484         /* Enable SPI. */
485         WR4(sc, ZY7_QSPI_EN_REG, ZY7_SPI_ENABLE);
486
487         return (0);
488 }
489
490 static void
491 zy7_qspi_add_sysctls(device_t dev)
492 {
493         struct zy7_qspi_softc *sc = device_get_softc(dev);
494         struct sysctl_ctx_list *ctx;
495         struct sysctl_oid_list *child;
496
497         ctx = device_get_sysctl_ctx(dev);
498         child = SYSCTL_CHILDREN(device_get_sysctl_tree(dev));
499
500         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "spi_clk_real_freq", CTLFLAG_RD,
501             &sc->spi_clk_real_freq, 0, "SPI clock real frequency");
502
503         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "rx_overflows", CTLFLAG_RD,
504             &sc->rx_overflows, 0, "RX FIFO overflow events");
505
506         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "tx_underflows", CTLFLAG_RD,
507             &sc->tx_underflows, 0, "TX FIFO underflow events");
508
509         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "interrupts", CTLFLAG_RD,
510             &sc->interrupts, 0, "interrupt calls");
511
512         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "stray_ints", CTLFLAG_RD,
513             &sc->stray_ints, 0, "stray interrupts");
514 }
515
516 static int
517 zy7_qspi_probe(device_t dev)
518 {
519
520         if (!ofw_bus_status_okay(dev))
521                 return (ENXIO);
522
523         if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
524                 return (ENXIO);
525
526         device_set_desc(dev, "Zynq Quad-SPI Flash Controller");
527
528         return (BUS_PROBE_DEFAULT);
529 }
530
531 static int
532 zy7_qspi_attach(device_t dev)
533 {
534         struct zy7_qspi_softc *sc;
535         int rid, err;
536         phandle_t node;
537         pcell_t cell;
538
539         sc = device_get_softc(dev);
540         sc->dev = dev;
541
542         QSPI_SC_LOCK_INIT(sc);
543
544         /* Get ref-clock, spi-clock, and other properties. */
545         node = ofw_bus_get_node(dev);
546         if (OF_getprop(node, "ref-clock", &cell, sizeof(cell)) > 0)
547                 sc->ref_clock = fdt32_to_cpu(cell);
548         else {
549                 device_printf(dev, "must have ref-clock property\n");
550                 return (ENXIO);
551         }
552         if (OF_getprop(node, "spi-clock", &cell, sizeof(cell)) > 0)
553                 sc->spi_clock = fdt32_to_cpu(cell);
554         else
555                 sc->spi_clock = ZY7_QSPI_DEFAULT_SPI_CLOCK;
556         if (OF_getprop(node, "is-stacked", &cell, sizeof(cell)) > 0 &&
557             fdt32_to_cpu(cell) != 0) {
558                 sc->is_dual = 1;
559                 sc->is_stacked = 1;
560         } else if (OF_getprop(node, "is-dual", &cell, sizeof(cell)) > 0 &&
561                    fdt32_to_cpu(cell) != 0)
562                 sc->is_dual = 1;
563         if (OF_getprop(node, "is-dio", &cell, sizeof(cell)) > 0 &&
564             fdt32_to_cpu(cell) != 0)
565                 sc->is_dio = 1;
566
567         /* Get memory resource. */
568         rid = 0;
569         sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
570             RF_ACTIVE);
571         if (sc->mem_res == NULL) {
572                 device_printf(dev, "could not allocate memory resources.\n");
573                 zy7_qspi_detach(dev);
574                 return (ENOMEM);
575         }
576
577         /* Allocate IRQ. */
578         rid = 0;
579         sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
580             RF_ACTIVE);
581         if (sc->irq_res == NULL) {
582                 device_printf(dev, "could not allocate IRQ resource.\n");
583                 zy7_qspi_detach(dev);
584                 return (ENOMEM);
585         }
586
587         /* Activate the interrupt. */
588         err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
589             NULL, zy7_qspi_intr, sc, &sc->intrhandle);
590         if (err) {
591                 device_printf(dev, "could not setup IRQ.\n");
592                 zy7_qspi_detach(dev);
593                 return (err);
594         }
595
596         /* Configure the device. */
597         err = zy7_qspi_init_hw(sc);
598         if (err) {
599                 zy7_qspi_detach(dev);
600                 return (err);
601         }
602
603         sc->child = device_add_child(dev, "spibus", -1);
604
605         zy7_qspi_add_sysctls(dev);
606
607         /* Attach spibus driver as a child later when interrupts work. */
608         config_intrhook_oneshot((ich_func_t)bus_generic_attach, dev);
609
610         return (0);
611 }
612
613 static int
614 zy7_qspi_detach(device_t dev)
615 {
616         struct zy7_qspi_softc *sc = device_get_softc(dev);
617
618         if (device_is_attached(dev))
619                 bus_generic_detach(dev);
620
621         /* Delete child bus. */
622         if (sc->child)
623                 device_delete_child(dev, sc->child);
624
625         /* Disable hardware. */
626         if (sc->mem_res != NULL) {
627                 /* Disable SPI. */
628                 WR4(sc, ZY7_QSPI_EN_REG, 0);
629
630                 /* Clear and disable all interrupts. */
631                 WR4(sc, ZY7_QSPI_INTR_STAT_REG, ~0);
632                 WR4(sc, ZY7_QSPI_INTR_DIS_REG, ~0);
633         }
634
635         /* Teardown and release interrupt. */
636         if (sc->irq_res != NULL) {
637                 if (sc->intrhandle)
638                         bus_teardown_intr(dev, sc->irq_res, sc->intrhandle);
639                 bus_release_resource(dev, SYS_RES_IRQ,
640                     rman_get_rid(sc->irq_res), sc->irq_res);
641         }
642
643         /* Release memory resource. */
644         if (sc->mem_res != NULL)
645                 bus_release_resource(dev, SYS_RES_MEMORY,
646                     rman_get_rid(sc->mem_res), sc->mem_res);
647
648         QSPI_SC_LOCK_DESTROY(sc);
649
650         return (0);
651 }
652
653 static phandle_t
654 zy7_qspi_get_node(device_t bus, device_t dev)
655 {
656
657         return (ofw_bus_get_node(bus));
658 }
659
660 static int
661 zy7_qspi_transfer(device_t dev, device_t child, struct spi_command *cmd)
662 {
663         struct zy7_qspi_softc *sc = device_get_softc(dev);
664         int err = 0;
665
666         KASSERT(cmd->tx_cmd_sz == cmd->rx_cmd_sz,
667             ("TX/RX command sizes should be equal"));
668         KASSERT(cmd->tx_data_sz == cmd->rx_data_sz,
669             ("TX/RX data sizes should be equal"));
670
671         if (sc->is_dual && cmd->tx_data_sz % 2 != 0) {
672                 device_printf(dev, "driver does not support odd byte data "
673                     "transfers in dual mode. (sz=%d)\n", cmd->tx_data_sz);
674                 return (EINVAL);
675         }
676
677         QSPI_SC_LOCK(sc);
678
679         /* Wait for controller available. */
680         while (sc->busy != 0) {
681                 err = mtx_sleep(dev, &sc->sc_mtx, 0, "zqspi0", 0);
682                 if (err) {
683                         QSPI_SC_UNLOCK(sc);
684                         return (err);
685                 }
686         }
687
688         /* Start transfer. */
689         sc->busy = 1;
690         sc->cmd = cmd;
691         sc->tx_bytes = sc->cmd->tx_cmd_sz + sc->cmd->tx_data_sz;
692         sc->tx_bytes_sent = 0;
693         sc->rx_bytes = sc->cmd->rx_cmd_sz + sc->cmd->rx_data_sz;
694         sc->rx_bytes_rcvd = 0;
695
696         /* Enable interrupts.  zy7_qspi_intr() will handle transfer. */
697         WR4(sc, ZY7_QSPI_INTR_EN_REG,
698             ZY7_QSPI_INTR_TX_FIFO_NOT_FULL |
699             ZY7_QSPI_INTR_RX_OVERFLOW);
700
701 #ifdef SPI_XFER_U_PAGE  /* XXX: future support for stacked memories. */
702         if (sc->is_stacked) {
703                 if ((cmd->flags & SPI_XFER_U_PAGE) != 0)
704                         sc->lqspi_cfg_shadow |= ZY7_QSPI_LQSPI_CFG_U_PAGE;
705                 else
706                         sc->lqspi_cfg_shadow &= ~ZY7_QSPI_LQSPI_CFG_U_PAGE;
707                 WR4(sc, ZY7_QSPI_LQSPI_CFG_REG, sc->lqspi_cfg_shadow);
708         }
709 #endif
710
711         /* Assert CS. */
712         sc->cfg_reg_shadow &= ~ZY7_QSPI_CONFIG_PCS;
713         WR4(sc, ZY7_QSPI_CONFIG_REG, sc->cfg_reg_shadow);
714
715         /* Wait for completion. */
716         err = mtx_sleep(dev, &sc->sc_mtx, 0, "zqspi1", hz * 2);
717         if (err)
718                 zy7_qspi_abort_transfer(sc);
719
720         /* Release controller. */
721         sc->busy = 0;
722         wakeup_one(dev);
723
724         QSPI_SC_UNLOCK(sc);
725
726         return (err);
727 }
728
729 static device_method_t zy7_qspi_methods[] = {
730         /* Device interface */
731         DEVMETHOD(device_probe,         zy7_qspi_probe),
732         DEVMETHOD(device_attach,        zy7_qspi_attach),
733         DEVMETHOD(device_detach,        zy7_qspi_detach),
734
735         /* SPI interface */
736         DEVMETHOD(spibus_transfer,      zy7_qspi_transfer),
737
738         /* ofw_bus interface */
739         DEVMETHOD(ofw_bus_get_node,     zy7_qspi_get_node),
740
741         DEVMETHOD_END
742 };
743
744 static driver_t zy7_qspi_driver = {
745         "zy7_qspi",
746         zy7_qspi_methods,
747         sizeof(struct zy7_qspi_softc),
748 };
749 static devclass_t zy7_qspi_devclass;
750
751 DRIVER_MODULE(zy7_qspi, simplebus, zy7_qspi_driver, zy7_qspi_devclass, 0, 0);
752 DRIVER_MODULE(ofw_spibus, zy7_qspi, ofw_spibus_driver, ofw_spibus_devclass, 0, 0);
753 SIMPLEBUS_PNP_INFO(compat_data);
754 MODULE_DEPEND(zy7_qspi, ofw_spibus, 1, 1, 1);