]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm/xilinx/zy7_qspi.c
Update ncurses to 20200118
[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
272 /* Read hardware fifo data into command response and data buffers. */
273 static void
274 zy7_qspi_read_fifo(struct zy7_qspi_softc *sc)
275 {
276         int n, nbytes;
277         uint32_t data;
278
279         do {
280                 data = RD4(sc, ZY7_QSPI_RX_DATA_REG);
281                 nbytes = MIN(4, sc->rx_bytes - sc->rx_bytes_rcvd);
282
283                 /*
284                  * Last word in non-word-multiple transfer is packed
285                  * non-intuitively.
286                  */
287                 if (nbytes < 4)
288                         data >>= 8 * (4 - nbytes);
289
290                 if (sc->rx_bytes_rcvd < sc->cmd->rx_cmd_sz) {
291                         /* Reading command. */
292                         n = MIN(nbytes, sc->cmd->rx_cmd_sz -
293                             sc->rx_bytes_rcvd);
294                         memcpy((uint8_t *)sc->cmd->rx_cmd + sc->rx_bytes_rcvd,
295                             &data, n);
296                         sc->rx_bytes_rcvd += n;
297                         nbytes -= n;
298                         data >>= 8 * n;
299                 }
300
301                 if (nbytes > 0) {
302                         /* Reading data. */
303                         memcpy((uint8_t *)sc->cmd->rx_data +
304                             (sc->rx_bytes_rcvd - sc->cmd->rx_cmd_sz),
305                             &data, nbytes);
306                         sc->rx_bytes_rcvd += nbytes;
307                 }
308
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);
312 }
313
314 /* End a transfer early by draining rx fifo and disabling interrupts. */
315 static void
316 zy7_qspi_abort_transfer(struct zy7_qspi_softc *sc)
317 {
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);
322
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);
328 }
329
330
331 static void
332 zy7_qspi_intr(void *arg)
333 {
334         struct zy7_qspi_softc *sc = (struct zy7_qspi_softc *)arg;
335         uint32_t istatus;
336
337         QSPI_SC_LOCK(sc);
338
339         sc->interrupts++;
340
341         istatus = RD4(sc, ZY7_QSPI_INTR_STAT_REG);
342
343         /* Stray interrupts can happen if a transfer gets interrupted. */
344         if (!sc->busy) {
345                 sc->stray_ints++;
346                 QSPI_SC_UNLOCK(sc);
347                 return;
348         }
349
350         if ((istatus & ZY7_QSPI_INTR_RX_OVERFLOW) != 0) {
351                 device_printf(sc->dev, "rx fifo overflow!\n");
352                 sc->rx_overflows++;
353
354                 /* Clear status bit. */
355                 WR4(sc, ZY7_QSPI_INTR_STAT_REG,
356                     ZY7_QSPI_INTR_RX_OVERFLOW);
357         }
358
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);
368         }
369
370         /*
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?
374          */
375         if ((istatus & ZY7_QSPI_INTR_TX_FIFO_UNDERFLOW) != 0) {
376                 sc->tx_underflows++;
377
378                 /* Clear status bit. */
379                 WR4(sc, ZY7_QSPI_INTR_STAT_REG,
380                     ZY7_QSPI_INTR_TX_FIFO_UNDERFLOW);
381         }
382
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 -
387                         sc->tx_bytes_sent));
388
389                 if (sc->tx_bytes_sent == sc->tx_bytes) {
390                         /*
391                          * Disable transmit FIFO interrupt, enable receive
392                          * FIFO interrupt.
393                          */
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);
398                 }
399         }
400
401         /* Finished with transfer? */
402         if (sc->tx_bytes_sent == sc->tx_bytes &&
403             sc->rx_bytes_rcvd == sc->rx_bytes) {
404
405                 /* De-assert CS. */
406                 sc->cfg_reg_shadow |= ZY7_QSPI_CONFIG_PCS;
407                 WR4(sc, ZY7_QSPI_CONFIG_REG, sc->cfg_reg_shadow);
408
409                 wakeup(sc->dev);
410         }
411
412         QSPI_SC_UNLOCK(sc);
413 }
414
415 /* Initialize hardware. */
416 static int
417 zy7_qspi_init_hw(struct zy7_qspi_softc *sc)
418 {
419         uint32_t baud_div;
420
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);
426         if (sc->is_dual) {
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);
434                 } else
435                         sc->lqspi_cfg_shadow |= ZY7_QSPI_LQSPI_CFG_SEP_BUS;
436         }
437         WR4(sc, ZY7_QSPI_LQSPI_CFG_REG, sc->lqspi_cfg_shadow);
438
439         /* Find best clock divider. */
440         baud_div = 0;
441         while ((sc->ref_clock >> (baud_div + 1)) > sc->spi_clock &&
442                baud_div < 8)
443                 baud_div++;
444         if (baud_div >= 8) {
445                 device_printf(sc->dev, "cannot configure clock divider: ref=%d"
446                     " spi=%d.\n", sc->ref_clock, sc->spi_clock);
447                 return (EINVAL);
448         }
449         sc->spi_clk_real_freq = sc->ref_clock >> (baud_div + 1);
450
451         /*
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.)
454          */
455         if (baud_div == 0)
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));
460         else
461                 WR4(sc, ZY7_QSPI_LPBK_DLY_ADJ_REG, 0);
462
463         /* Set up configuration register. */
464         sc->cfg_reg_shadow =
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);
474
475         /*
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
478          * workaround.
479          */
480         WR4(sc, ZY7_QSPI_TX_THRESH_REG, 1);
481         WR4(sc, ZY7_QSPI_RX_THRESH_REG, 1);
482
483         /* Clear and disable all interrupts. */
484         WR4(sc, ZY7_QSPI_INTR_STAT_REG, ~0);
485         WR4(sc, ZY7_QSPI_INTR_DIS_REG, ~0);
486
487         /* Enable SPI. */
488         WR4(sc, ZY7_QSPI_EN_REG, ZY7_SPI_ENABLE);
489
490         return (0);
491 }
492
493
494 static void
495 zy7_qspi_add_sysctls(device_t dev)
496 {
497         struct zy7_qspi_softc *sc = device_get_softc(dev);
498         struct sysctl_ctx_list *ctx;
499         struct sysctl_oid_list *child;
500
501         ctx = device_get_sysctl_ctx(dev);
502         child = SYSCTL_CHILDREN(device_get_sysctl_tree(dev));
503
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");
506
507         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "rx_overflows", CTLFLAG_RD,
508             &sc->rx_overflows, 0, "RX FIFO overflow events");
509
510         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "tx_underflows", CTLFLAG_RD,
511             &sc->tx_underflows, 0, "TX FIFO underflow events");
512
513         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "interrupts", CTLFLAG_RD,
514             &sc->interrupts, 0, "interrupt calls");
515
516         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "stray_ints", CTLFLAG_RD,
517             &sc->stray_ints, 0, "stray interrupts");
518 }
519
520
521 static int
522 zy7_qspi_probe(device_t dev)
523 {
524
525         if (!ofw_bus_status_okay(dev))
526                 return (ENXIO);
527
528         if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
529                 return (ENXIO);
530
531         device_set_desc(dev, "Zynq Quad-SPI Flash Controller");
532
533         return (BUS_PROBE_DEFAULT);
534 }
535
536
537 static int
538 zy7_qspi_attach(device_t dev)
539 {
540         struct zy7_qspi_softc *sc;
541         int rid, err;
542         phandle_t node;
543         pcell_t cell;
544
545         sc = device_get_softc(dev);
546         sc->dev = dev;
547
548         QSPI_SC_LOCK_INIT(sc);
549
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);
554         else {
555                 device_printf(dev, "must have ref-clock property\n");
556                 return (ENXIO);
557         }
558         if (OF_getprop(node, "spi-clock", &cell, sizeof(cell)) > 0)
559                 sc->spi_clock = fdt32_to_cpu(cell);
560         else
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) {
564                 sc->is_dual = 1;
565                 sc->is_stacked = 1;
566         } else if (OF_getprop(node, "is-dual", &cell, sizeof(cell)) > 0 &&
567                    fdt32_to_cpu(cell) != 0)
568                 sc->is_dual = 1;
569         if (OF_getprop(node, "is-dio", &cell, sizeof(cell)) > 0 &&
570             fdt32_to_cpu(cell) != 0)
571                 sc->is_dio = 1;
572
573         /* Get memory resource. */
574         rid = 0;
575         sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
576             RF_ACTIVE);
577         if (sc->mem_res == NULL) {
578                 device_printf(dev, "could not allocate memory resources.\n");
579                 zy7_qspi_detach(dev);
580                 return (ENOMEM);
581         }
582
583         /* Allocate IRQ. */
584         rid = 0;
585         sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
586             RF_ACTIVE);
587         if (sc->irq_res == NULL) {
588                 device_printf(dev, "could not allocate IRQ resource.\n");
589                 zy7_qspi_detach(dev);
590                 return (ENOMEM);
591         }
592
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);
596         if (err) {
597                 device_printf(dev, "could not setup IRQ.\n");
598                 zy7_qspi_detach(dev);
599                 return (err);
600         }
601
602         /* Configure the device. */
603         err = zy7_qspi_init_hw(sc);
604         if (err) {
605                 zy7_qspi_detach(dev);
606                 return (err);
607         }
608
609         sc->child = device_add_child(dev, "spibus", -1);
610
611         zy7_qspi_add_sysctls(dev);
612
613         /* Attach spibus driver as a child later when interrupts work. */
614         config_intrhook_oneshot((ich_func_t)bus_generic_attach, dev);
615
616         return (0);
617 }
618
619 static int
620 zy7_qspi_detach(device_t dev)
621 {
622         struct zy7_qspi_softc *sc = device_get_softc(dev);
623
624         if (device_is_attached(dev))
625                 bus_generic_detach(dev);
626
627         /* Delete child bus. */
628         if (sc->child)
629                 device_delete_child(dev, sc->child);
630
631         /* Disable hardware. */
632         if (sc->mem_res != NULL) {
633                 /* Disable SPI. */
634                 WR4(sc, ZY7_QSPI_EN_REG, 0);
635
636                 /* Clear and disable all interrupts. */
637                 WR4(sc, ZY7_QSPI_INTR_STAT_REG, ~0);
638                 WR4(sc, ZY7_QSPI_INTR_DIS_REG, ~0);
639         }
640
641         /* Teardown and release interrupt. */
642         if (sc->irq_res != NULL) {
643                 if (sc->intrhandle)
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);
647         }
648
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);
653
654         QSPI_SC_LOCK_DESTROY(sc);
655
656         return (0);
657 }
658
659
660 static phandle_t
661 zy7_qspi_get_node(device_t bus, device_t dev)
662 {
663
664         return (ofw_bus_get_node(bus));
665 }
666
667
668 static int
669 zy7_qspi_transfer(device_t dev, device_t child, struct spi_command *cmd)
670 {
671         struct zy7_qspi_softc *sc = device_get_softc(dev);
672         int err = 0;
673
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"));
678
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);
682                 return (EINVAL);
683         }
684
685         QSPI_SC_LOCK(sc);
686
687         /* Wait for controller available. */
688         while (sc->busy != 0) {
689                 err = mtx_sleep(dev, &sc->sc_mtx, 0, "zqspi0", 0);
690                 if (err) {
691                         QSPI_SC_UNLOCK(sc);
692                         return (err);
693                 }
694         }
695
696         /* Start transfer. */
697         sc->busy = 1;
698         sc->cmd = cmd;
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;
703
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);
708
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;
713                 else
714                         sc->lqspi_cfg_shadow &= ~ZY7_QSPI_LQSPI_CFG_U_PAGE;
715                 WR4(sc, ZY7_QSPI_LQSPI_CFG_REG, sc->lqspi_cfg_shadow);
716         }
717 #endif
718
719         /* Assert CS. */
720         sc->cfg_reg_shadow &= ~ZY7_QSPI_CONFIG_PCS;
721         WR4(sc, ZY7_QSPI_CONFIG_REG, sc->cfg_reg_shadow);
722
723         /* Wait for completion. */
724         err = mtx_sleep(dev, &sc->sc_mtx, 0, "zqspi1", hz * 2);
725         if (err)
726                 zy7_qspi_abort_transfer(sc);
727
728         /* Release controller. */
729         sc->busy = 0;
730         wakeup_one(dev);
731
732         QSPI_SC_UNLOCK(sc);
733
734         return (err);
735 }
736
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),
742
743         /* SPI interface */
744         DEVMETHOD(spibus_transfer,      zy7_qspi_transfer),
745
746         /* ofw_bus interface */
747         DEVMETHOD(ofw_bus_get_node,     zy7_qspi_get_node),
748
749         DEVMETHOD_END
750 };
751
752
753 static driver_t zy7_qspi_driver = {
754         "zy7_qspi",
755         zy7_qspi_methods,
756         sizeof(struct zy7_qspi_softc),
757 };
758 static devclass_t zy7_qspi_devclass;
759
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);