The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/flash/cqspi.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2017-2018 Ruslan Bukin <br@bsdpad.com>
    3  * All rights reserved.
    4  *
    5  * This software was developed by SRI International and the University of
    6  * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237
    7  * ("CTSRD"), as part of the DARPA CRASH research programme.
    8  *
    9  * Redistribution and use in source and binary forms, with or without
   10  * modification, are permitted provided that the following conditions
   11  * are met:
   12  * 1. Redistributions of source code must retain the above copyright
   13  *    notice, this list of conditions and the following disclaimer.
   14  * 2. Redistributions in binary form must reproduce the above copyright
   15  *    notice, this list of conditions and the following disclaimer in the
   16  *    documentation and/or other materials provided with the distribution.
   17  *
   18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   28  * SUCH DAMAGE.
   29  */
   30 
   31 /*
   32  * Cadence Quad SPI Flash Controller driver.
   33  * 4B-addressing mode supported only.
   34  */
   35 
   36 #include <sys/cdefs.h>
   37 __FBSDID("$FreeBSD$");
   38 
   39 #include "opt_platform.h"
   40 
   41 #include <sys/param.h>
   42 #include <sys/systm.h>
   43 #include <sys/bio.h>
   44 #include <sys/bus.h>
   45 #include <sys/conf.h>
   46 #include <sys/kernel.h>
   47 #include <sys/kthread.h>
   48 #include <sys/lock.h>
   49 #include <sys/mbuf.h>
   50 #include <sys/malloc.h>
   51 #include <sys/module.h>
   52 #include <sys/mutex.h>
   53 #include <sys/rman.h>
   54 #include <geom/geom_disk.h>
   55 
   56 #include <machine/bus.h>
   57 
   58 #include <dev/fdt/simplebus.h>
   59 #include <dev/fdt/fdt_common.h>
   60 #include <dev/ofw/ofw_bus_subr.h>
   61 #include <dev/ofw/openfirm.h>
   62 
   63 #include <dev/flash/cqspi.h>
   64 #include <dev/flash/mx25lreg.h>
   65 #include <dev/xdma/xdma.h>
   66 
   67 #include "qspi_if.h"
   68 
   69 #define CQSPI_DEBUG
   70 #undef CQSPI_DEBUG
   71 
   72 #ifdef CQSPI_DEBUG
   73 #define dprintf(fmt, ...)  printf(fmt, ##__VA_ARGS__)
   74 #else
   75 #define dprintf(fmt, ...)
   76 #endif
   77 
   78 #define CQSPI_SECTORSIZE        512
   79 #define TX_QUEUE_SIZE           16
   80 #define RX_QUEUE_SIZE           16
   81 
   82 #define READ4(_sc, _reg) bus_read_4((_sc)->res[0], _reg)
   83 #define READ2(_sc, _reg) bus_read_2((_sc)->res[0], _reg)
   84 #define READ1(_sc, _reg) bus_read_1((_sc)->res[0], _reg)
   85 #define WRITE4(_sc, _reg, _val) bus_write_4((_sc)->res[0], _reg, _val)
   86 #define WRITE2(_sc, _reg, _val) bus_write_2((_sc)->res[0], _reg, _val)
   87 #define WRITE1(_sc, _reg, _val) bus_write_1((_sc)->res[0], _reg, _val)
   88 #define READ_DATA_4(_sc, _reg) bus_read_4((_sc)->res[1], _reg)
   89 #define READ_DATA_1(_sc, _reg) bus_read_1((_sc)->res[1], _reg)
   90 #define WRITE_DATA_4(_sc, _reg, _val) bus_write_4((_sc)->res[1], _reg, _val)
   91 #define WRITE_DATA_1(_sc, _reg, _val) bus_write_1((_sc)->res[1], _reg, _val)
   92 
   93 struct cqspi_softc {
   94         device_t                dev;
   95 
   96         struct resource         *res[3];
   97         bus_space_tag_t         bst;
   98         bus_space_handle_t      bsh;
   99         void                    *ih;
  100         uint8_t                 read_op_done;
  101         uint8_t                 write_op_done;
  102 
  103         uint32_t                fifo_depth;
  104         uint32_t                fifo_width;
  105         uint32_t                trigger_address;
  106         uint32_t                sram_phys;
  107 
  108         /* xDMA */
  109         xdma_controller_t       *xdma_tx;
  110         xdma_channel_t          *xchan_tx;
  111         void                    *ih_tx;
  112 
  113         xdma_controller_t       *xdma_rx;
  114         xdma_channel_t          *xchan_rx;
  115         void                    *ih_rx;
  116 
  117         struct intr_config_hook config_intrhook;
  118         struct mtx              sc_mtx;
  119 };
  120 
  121 #define CQSPI_LOCK(_sc)         mtx_lock(&(_sc)->sc_mtx)
  122 #define CQSPI_UNLOCK(_sc)       mtx_unlock(&(_sc)->sc_mtx)
  123 #define CQSPI_LOCK_INIT(_sc)                                    \
  124         mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev),   \
  125             "cqspi", MTX_DEF)
  126 #define CQSPI_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx);
  127 #define CQSPI_ASSERT_LOCKED(_sc)                                \
  128         mtx_assert(&_sc->sc_mtx, MA_OWNED);
  129 #define CQSPI_ASSERT_UNLOCKED(_sc)                              \
  130         mtx_assert(&_sc->sc_mtx, MA_NOTOWNED);
  131 
  132 static struct resource_spec cqspi_spec[] = {
  133         { SYS_RES_MEMORY,       0,      RF_ACTIVE },
  134         { SYS_RES_MEMORY,       1,      RF_ACTIVE },
  135         { SYS_RES_IRQ,          0,      RF_ACTIVE },
  136         { -1, 0 }
  137 };
  138 
  139 static struct ofw_compat_data compat_data[] = {
  140         { "cdns,qspi-nor",      1 },
  141         { NULL,                 0 },
  142 };
  143 
  144 static void
  145 cqspi_intr(void *arg)
  146 {
  147         struct cqspi_softc *sc;
  148         uint32_t pending;
  149 
  150         sc = arg;
  151 
  152         pending = READ4(sc, CQSPI_IRQSTAT);
  153 
  154         dprintf("%s: IRQSTAT %x\n", __func__, pending);
  155 
  156         if (pending & (IRQMASK_INDOPDONE | IRQMASK_INDXFRLVL |
  157             IRQMASK_INDSRAMFULL)) {
  158                 /* TODO: PIO operation done */
  159         }
  160 
  161         WRITE4(sc, CQSPI_IRQSTAT, pending);
  162 }
  163 
  164 static int
  165 cqspi_xdma_tx_intr(void *arg, xdma_transfer_status_t *status)
  166 {
  167         struct xdma_transfer_status st;
  168         struct cqspi_softc *sc;
  169         struct bio *bp;
  170         int ret;
  171         int deq;
  172 
  173         sc = arg;
  174 
  175         dprintf("%s\n", __func__);
  176 
  177         deq = 0;
  178 
  179         while (1) {
  180                 ret = xdma_dequeue_bio(sc->xchan_tx, &bp, &st);
  181                 if (ret != 0) {
  182                         break;
  183                 }
  184                 sc->write_op_done = 1;
  185                 deq++;
  186         }
  187 
  188         if (deq > 1)
  189                 device_printf(sc->dev,
  190                     "Warning: more than 1 tx bio dequeued\n");
  191 
  192         wakeup(&sc->xdma_tx);
  193 
  194         return (0);
  195 }
  196 
  197 static int
  198 cqspi_xdma_rx_intr(void *arg, xdma_transfer_status_t *status)
  199 {
  200         struct xdma_transfer_status st;
  201         struct cqspi_softc *sc;
  202         struct bio *bp;
  203         int ret;
  204         int deq;
  205 
  206         sc = arg;
  207 
  208         dprintf("%s\n", __func__);
  209 
  210         deq = 0;
  211 
  212         while (1) {
  213                 ret = xdma_dequeue_bio(sc->xchan_rx, &bp, &st);
  214                 if (ret != 0) {
  215                         break;
  216                 }
  217                 sc->read_op_done = 1;
  218                 deq++;
  219         }
  220 
  221         if (deq > 1)
  222                 device_printf(sc->dev,
  223                     "Warning: more than 1 rx bio dequeued\n");
  224 
  225         wakeup(&sc->xdma_rx);
  226 
  227         return (0);
  228 }
  229 
  230 static int
  231 cqspi_wait_for_completion(struct cqspi_softc *sc)
  232 {
  233         int timeout;
  234         int i;
  235 
  236         timeout = 10000;
  237 
  238         for (i = timeout; i > 0; i--) {
  239                 if ((READ4(sc, CQSPI_FLASHCMD) & FLASHCMD_CMDEXECSTAT) == 0) {
  240                         break;
  241                 }
  242         }
  243 
  244         if (i == 0) {
  245                 device_printf(sc->dev, "%s: cmd timed out: %x\n",
  246                     __func__, READ4(sc, CQSPI_FLASHCMD));
  247                 return (-1);
  248         }
  249 
  250         return (0);
  251 }
  252 
  253 static int
  254 cqspi_cmd_write_addr(struct cqspi_softc *sc, uint8_t cmd,
  255     uint32_t addr, uint32_t len)
  256 {
  257         uint32_t reg;
  258         int ret;
  259 
  260         dprintf("%s: %x\n", __func__, cmd);
  261 
  262         WRITE4(sc, CQSPI_FLASHCMDADDR, addr);
  263         reg = (cmd << FLASHCMD_CMDOPCODE_S);
  264         reg |= (FLASHCMD_ENCMDADDR);
  265         reg |= ((len - 1) << FLASHCMD_NUMADDRBYTES_S);
  266         WRITE4(sc, CQSPI_FLASHCMD, reg);
  267 
  268         reg |= FLASHCMD_EXECCMD;
  269         WRITE4(sc, CQSPI_FLASHCMD, reg);
  270 
  271         ret = cqspi_wait_for_completion(sc);
  272 
  273         return (ret);
  274 }
  275 
  276 static int
  277 cqspi_cmd_write(struct cqspi_softc *sc, uint8_t cmd,
  278     uint8_t *addr, uint32_t len)
  279 {
  280         uint32_t reg;
  281         int ret;
  282 
  283         reg = (cmd << FLASHCMD_CMDOPCODE_S);
  284         WRITE4(sc, CQSPI_FLASHCMD, reg);
  285         reg |= FLASHCMD_EXECCMD;
  286         WRITE4(sc, CQSPI_FLASHCMD, reg);
  287 
  288         ret = cqspi_wait_for_completion(sc);
  289 
  290         return (ret);
  291 }
  292 
  293 static int
  294 cqspi_cmd_read(struct cqspi_softc *sc, uint8_t cmd,
  295     uint8_t *addr, uint32_t len)
  296 {
  297         uint32_t data;
  298         uint32_t reg;
  299         uint8_t *buf;
  300         int ret;
  301         int i;
  302 
  303         if (len > 8) {
  304                 device_printf(sc->dev, "Failed to read data\n");
  305                 return (-1);
  306         }
  307 
  308         dprintf("%s: %x\n", __func__, cmd);
  309 
  310         buf = (uint8_t *)addr;
  311 
  312         reg = (cmd << FLASHCMD_CMDOPCODE_S);
  313         reg |= ((len - 1) << FLASHCMD_NUMRDDATABYTES_S);
  314         reg |= FLASHCMD_ENRDDATA;
  315         WRITE4(sc, CQSPI_FLASHCMD, reg);
  316 
  317         reg |= FLASHCMD_EXECCMD;
  318         WRITE4(sc, CQSPI_FLASHCMD, reg);
  319 
  320         ret = cqspi_wait_for_completion(sc);
  321         if (ret != 0) {
  322                 device_printf(sc->dev, "%s: cmd failed: %x\n",
  323                     __func__, cmd);
  324                 return (ret);
  325         }
  326 
  327         data = READ4(sc, CQSPI_FLASHCMDRDDATALO);
  328 
  329         for (i = 0; i < len; i++)
  330                 buf[i] = (data >> (i * 8)) & 0xff;
  331 
  332         return (0);
  333 }
  334 
  335 static int
  336 cqspi_wait_ready(struct cqspi_softc *sc)
  337 {
  338         uint8_t data;
  339 
  340         do {
  341                 cqspi_cmd_read(sc, CMD_READ_STATUS, &data, 1);
  342         } while (data & STATUS_WIP);
  343 
  344         return (0);
  345 }
  346 
  347 static int
  348 cqspi_write_reg(device_t dev, device_t child,
  349     uint8_t opcode, uint8_t *addr, uint32_t len)
  350 {
  351         struct cqspi_softc *sc;
  352         int ret;
  353 
  354         sc = device_get_softc(dev);
  355 
  356         ret = cqspi_cmd_write(sc, opcode, addr, len);
  357 
  358         return (ret);
  359 }
  360 
  361 static int
  362 cqspi_read_reg(device_t dev, device_t child,
  363     uint8_t opcode, uint8_t *addr, uint32_t len)
  364 {
  365         struct cqspi_softc *sc;
  366         int ret;
  367 
  368         sc = device_get_softc(dev);
  369 
  370         ret = cqspi_cmd_read(sc, opcode, addr, len);
  371 
  372         return (ret);
  373 }
  374 
  375 static int
  376 cqspi_wait_idle(struct cqspi_softc *sc)
  377 {
  378         uint32_t reg;
  379 
  380         do {
  381                 reg = READ4(sc, CQSPI_CFG);
  382                 if (reg & CFG_IDLE) {
  383                         break;
  384                 }
  385         } while (1);
  386 
  387         return (0);
  388 }
  389 
  390 static int
  391 cqspi_erase(device_t dev, device_t child, off_t offset)
  392 {
  393         struct cqspi_softc *sc;
  394 
  395         sc = device_get_softc(dev);
  396 
  397         cqspi_wait_idle(sc);
  398         cqspi_wait_ready(sc);
  399         cqspi_cmd_write(sc, CMD_WRITE_ENABLE, 0, 0);
  400 
  401         cqspi_wait_idle(sc);
  402         cqspi_wait_ready(sc);
  403         cqspi_cmd_write_addr(sc, CMD_QUAD_SECTOR_ERASE, offset, 4);
  404 
  405         cqspi_wait_idle(sc);
  406 
  407         return (0);
  408 }
  409 
  410 static int
  411 cqspi_write(device_t dev, device_t child, struct bio *bp,
  412     off_t offset, caddr_t data, off_t count)
  413 {
  414         struct cqspi_softc *sc;
  415         uint32_t reg;
  416 
  417         dprintf("%s: offset 0x%llx count %lld bytes\n",
  418             __func__, offset, count);
  419 
  420         sc = device_get_softc(dev);
  421 
  422         cqspi_wait_ready(sc);
  423         cqspi_cmd_write(sc, CMD_WRITE_ENABLE, 0, 0);
  424 
  425         cqspi_wait_idle(sc);
  426         cqspi_wait_ready(sc);
  427         cqspi_wait_idle(sc);
  428 
  429         reg = DMAPER_NUMSGLREQBYTES_4;
  430         reg |= DMAPER_NUMBURSTREQBYTES_4;
  431         WRITE4(sc, CQSPI_DMAPER, reg);
  432 
  433         WRITE4(sc, CQSPI_INDWRWATER, 64);
  434         WRITE4(sc, CQSPI_INDWR, INDRD_IND_OPS_DONE_STATUS);
  435         WRITE4(sc, CQSPI_INDWR, 0);
  436 
  437         WRITE4(sc, CQSPI_INDWRCNT, count);
  438         WRITE4(sc, CQSPI_INDWRSTADDR, offset);
  439 
  440         reg = (0 << DEVWR_DUMMYWRCLKS_S);
  441         reg |= DEVWR_DATA_WIDTH_QUAD;
  442         reg |= DEVWR_ADDR_WIDTH_SINGLE;
  443         reg |= (CMD_QUAD_PAGE_PROGRAM << DEVWR_WROPCODE_S);
  444         WRITE4(sc, CQSPI_DEVWR, reg);
  445 
  446         reg = DEVRD_DATA_WIDTH_QUAD;
  447         reg |= DEVRD_ADDR_WIDTH_SINGLE;
  448         reg |= DEVRD_INST_WIDTH_SINGLE;
  449         WRITE4(sc, CQSPI_DEVRD, reg);
  450 
  451         xdma_enqueue_bio(sc->xchan_tx, &bp,
  452             sc->sram_phys, 4, 4, XDMA_MEM_TO_DEV);
  453         xdma_queue_submit(sc->xchan_tx);
  454 
  455         sc->write_op_done = 0;
  456 
  457         WRITE4(sc, CQSPI_INDWR, INDRD_START);
  458 
  459         while (sc->write_op_done == 0)
  460                 tsleep(&sc->xdma_tx, PCATCH | PZERO, "spi", hz/2);
  461 
  462         cqspi_wait_idle(sc);
  463 
  464         return (0);
  465 }
  466 
  467 static int
  468 cqspi_read(device_t dev, device_t child, struct bio *bp,
  469     off_t offset, caddr_t data, off_t count)
  470 {
  471         struct cqspi_softc *sc;
  472         uint32_t reg;
  473 
  474         sc = device_get_softc(dev);
  475 
  476         dprintf("%s: offset 0x%llx count %lld bytes\n",
  477             __func__, offset, count);
  478 
  479         cqspi_wait_idle(sc);
  480 
  481         reg = DMAPER_NUMSGLREQBYTES_4;
  482         reg |= DMAPER_NUMBURSTREQBYTES_4;
  483         WRITE4(sc, CQSPI_DMAPER, reg);
  484 
  485         WRITE4(sc, CQSPI_INDRDWATER, 64);
  486         WRITE4(sc, CQSPI_INDRD, INDRD_IND_OPS_DONE_STATUS);
  487         WRITE4(sc, CQSPI_INDRD, 0);
  488 
  489         WRITE4(sc, CQSPI_INDRDCNT, count);
  490         WRITE4(sc, CQSPI_INDRDSTADDR, offset);
  491 
  492         reg = (0 << DEVRD_DUMMYRDCLKS_S);
  493         reg |= DEVRD_DATA_WIDTH_QUAD;
  494         reg |= DEVRD_ADDR_WIDTH_SINGLE;
  495         reg |= DEVRD_INST_WIDTH_SINGLE;
  496         reg |= DEVRD_ENMODEBITS;
  497         reg |= (CMD_READ_4B_QUAD_OUTPUT << DEVRD_RDOPCODE_S);
  498         WRITE4(sc, CQSPI_DEVRD, reg);
  499 
  500         WRITE4(sc, CQSPI_MODEBIT, 0xff);
  501         WRITE4(sc, CQSPI_IRQMASK, 0);
  502 
  503         xdma_enqueue_bio(sc->xchan_rx, &bp, sc->sram_phys, 4, 4,
  504             XDMA_DEV_TO_MEM);
  505         xdma_queue_submit(sc->xchan_rx);
  506 
  507         sc->read_op_done = 0;
  508 
  509         WRITE4(sc, CQSPI_INDRD, INDRD_START);
  510 
  511         while (sc->read_op_done == 0)
  512                 tsleep(&sc->xdma_rx, PCATCH | PZERO, "spi", hz/2);
  513 
  514         cqspi_wait_idle(sc);
  515 
  516         return (0);
  517 }
  518 
  519 static int
  520 cqspi_init(struct cqspi_softc *sc)
  521 {
  522         pcell_t dts_value[1];
  523         phandle_t node;
  524         uint32_t reg;
  525         int len;
  526 
  527         device_printf(sc->dev, "Module ID %x\n",
  528             READ4(sc, CQSPI_MODULEID));
  529 
  530         if ((node = ofw_bus_get_node(sc->dev)) == -1) {
  531                 return (ENXIO);
  532         }
  533 
  534         if ((len = OF_getproplen(node, "cdns,fifo-depth")) <= 0) {
  535                 return (ENXIO);
  536         }
  537         OF_getencprop(node, "cdns,fifo-depth", dts_value, len);
  538         sc->fifo_depth = dts_value[0];
  539 
  540         if ((len = OF_getproplen(node, "cdns,fifo-width")) <= 0) {
  541                 return (ENXIO);
  542         }
  543         OF_getencprop(node, "cdns,fifo-width", dts_value, len);
  544         sc->fifo_width = dts_value[0];
  545 
  546         if ((len = OF_getproplen(node, "cdns,trigger-address")) <= 0) {
  547                 return (ENXIO);
  548         }
  549         OF_getencprop(node, "cdns,trigger-address", dts_value, len);
  550         sc->trigger_address = dts_value[0];
  551 
  552         /* Disable controller */
  553         reg = READ4(sc, CQSPI_CFG);
  554         reg &= ~(CFG_EN);
  555         WRITE4(sc, CQSPI_CFG, reg);
  556 
  557         reg = READ4(sc, CQSPI_DEVSZ);
  558         reg &= ~(DEVSZ_NUMADDRBYTES_M);
  559         reg |= ((4 - 1) - DEVSZ_NUMADDRBYTES_S);
  560         WRITE4(sc, CQSPI_DEVSZ, reg);
  561 
  562         WRITE4(sc, CQSPI_SRAMPART, sc->fifo_depth/2);
  563 
  564         /* TODO: calculate baud rate and delay values. */
  565 
  566         reg = READ4(sc, CQSPI_CFG);
  567         /* Configure baud rate */
  568         reg &= ~(CFG_BAUD_M);
  569         reg |= CFG_BAUD12;
  570         reg |= CFG_ENDMA;
  571         WRITE4(sc, CQSPI_CFG, reg);
  572 
  573         reg = (3 << DELAY_NSS_S);
  574         reg |= (3  << DELAY_BTWN_S);
  575         reg |= (1 << DELAY_AFTER_S);
  576         reg |= (1 << DELAY_INIT_S);
  577         WRITE4(sc, CQSPI_DELAY, reg);
  578 
  579         READ4(sc, CQSPI_RDDATACAP);
  580         reg &= ~(RDDATACAP_DELAY_M);
  581         reg |= (1 << RDDATACAP_DELAY_S);
  582         WRITE4(sc, CQSPI_RDDATACAP, reg);
  583 
  584         /* Enable controller */
  585         reg = READ4(sc, CQSPI_CFG);
  586         reg |= (CFG_EN);
  587         WRITE4(sc, CQSPI_CFG, reg);
  588 
  589         return (0);
  590 }
  591 
  592 static int
  593 cqspi_add_devices(device_t dev)
  594 {
  595         phandle_t child, node;
  596         device_t child_dev;
  597         int error;
  598 
  599         node = ofw_bus_get_node(dev);
  600 
  601         for (child = OF_child(node); child != 0; child = OF_peer(child)) {
  602                 child_dev =
  603                     simplebus_add_device(dev, child, 0, NULL, -1, NULL);
  604                 if (child_dev == NULL) {
  605                         return (ENXIO);
  606                 }
  607 
  608                 error = device_probe_and_attach(child_dev);
  609                 if (error != 0) {
  610                         printf("can't probe and attach: %d\n", error);
  611                 }
  612         }
  613 
  614         return (0);
  615 }
  616 
  617 static void
  618 cqspi_delayed_attach(void *arg)
  619 {
  620         struct cqspi_softc *sc;
  621 
  622         sc = arg;
  623 
  624         cqspi_add_devices(sc->dev);
  625         bus_generic_attach(sc->dev);
  626 
  627         config_intrhook_disestablish(&sc->config_intrhook);
  628 }
  629 
  630 static int
  631 cqspi_probe(device_t dev)
  632 {
  633 
  634         if (!ofw_bus_status_okay(dev)) {
  635                 return (ENXIO);
  636         }
  637 
  638         if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data) {
  639                 return (ENXIO);
  640         }
  641 
  642         device_set_desc(dev, "Cadence Quad SPI controller");
  643 
  644         return (0);
  645 }
  646 
  647 static int
  648 cqspi_attach(device_t dev)
  649 {
  650         struct cqspi_softc *sc;
  651         uint32_t caps;
  652         int error;
  653 
  654         sc = device_get_softc(dev);
  655         sc->dev = dev;
  656 
  657         if (bus_alloc_resources(dev, cqspi_spec, sc->res)) {
  658                 device_printf(dev, "could not allocate resources\n");
  659                 return (ENXIO);
  660         }
  661 
  662         /* Memory interface */
  663         sc->bst = rman_get_bustag(sc->res[0]);
  664         sc->bsh = rman_get_bushandle(sc->res[0]);
  665 
  666         sc->sram_phys = rman_get_start(sc->res[1]);
  667 
  668         /* Setup interrupt handlers */
  669         if (bus_setup_intr(sc->dev, sc->res[2], INTR_TYPE_BIO | INTR_MPSAFE,
  670             NULL, cqspi_intr, sc, &sc->ih)) {
  671                 device_printf(sc->dev, "Unable to setup intr\n");
  672                 return (ENXIO);
  673         }
  674 
  675         CQSPI_LOCK_INIT(sc);
  676 
  677         caps = 0;
  678 
  679         /* Get xDMA controller. */
  680         sc->xdma_tx = xdma_ofw_get(sc->dev, "tx");
  681         if (sc->xdma_tx == NULL) {
  682                 device_printf(dev, "Can't find DMA controller.\n");
  683                 return (ENXIO);
  684         }
  685 
  686         sc->xdma_rx = xdma_ofw_get(sc->dev, "rx");
  687         if (sc->xdma_rx == NULL) {
  688                 device_printf(dev, "Can't find DMA controller.\n");
  689                 return (ENXIO);
  690         }
  691 
  692         /* Alloc xDMA virtual channels. */
  693         sc->xchan_tx = xdma_channel_alloc(sc->xdma_tx, caps);
  694         if (sc->xchan_tx == NULL) {
  695                 device_printf(dev, "Can't alloc virtual DMA channel.\n");
  696                 return (ENXIO);
  697         }
  698 
  699         sc->xchan_rx = xdma_channel_alloc(sc->xdma_rx, caps);
  700         if (sc->xchan_rx == NULL) {
  701                 device_printf(dev, "Can't alloc virtual DMA channel.\n");
  702                 return (ENXIO);
  703         }
  704 
  705         /* Setup xDMA interrupt handlers. */
  706         error = xdma_setup_intr(sc->xchan_tx, 0, cqspi_xdma_tx_intr,
  707             sc, &sc->ih_tx);
  708         if (error) {
  709                 device_printf(sc->dev,
  710                     "Can't setup xDMA interrupt handler.\n");
  711                 return (ENXIO);
  712         }
  713 
  714         error = xdma_setup_intr(sc->xchan_rx, 0, cqspi_xdma_rx_intr,
  715             sc, &sc->ih_rx);
  716         if (error) {
  717                 device_printf(sc->dev,
  718                     "Can't setup xDMA interrupt handler.\n");
  719                 return (ENXIO);
  720         }
  721 
  722         xdma_prep_sg(sc->xchan_tx, TX_QUEUE_SIZE, maxphys, 8, 16, 0,
  723             BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR);
  724         xdma_prep_sg(sc->xchan_rx, TX_QUEUE_SIZE, maxphys, 8, 16, 0,
  725             BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR);
  726 
  727         cqspi_init(sc);
  728 
  729         sc->config_intrhook.ich_func = cqspi_delayed_attach;
  730         sc->config_intrhook.ich_arg = sc;
  731         if (config_intrhook_establish(&sc->config_intrhook) != 0) {
  732                 device_printf(dev, "config_intrhook_establish failed\n");
  733                 return (ENOMEM);
  734         }
  735 
  736         return (0);
  737 }
  738 
  739 static int
  740 cqspi_detach(device_t dev)
  741 {
  742 
  743         return (ENXIO);
  744 }
  745 
  746 static device_method_t cqspi_methods[] = {
  747         /* Device interface */
  748         DEVMETHOD(device_probe,         cqspi_probe),
  749         DEVMETHOD(device_attach,        cqspi_attach),
  750         DEVMETHOD(device_detach,        cqspi_detach),
  751 
  752         /* Quad SPI Flash Interface */
  753         DEVMETHOD(qspi_read_reg,        cqspi_read_reg),
  754         DEVMETHOD(qspi_write_reg,       cqspi_write_reg),
  755         DEVMETHOD(qspi_read,            cqspi_read),
  756         DEVMETHOD(qspi_write,           cqspi_write),
  757         DEVMETHOD(qspi_erase,           cqspi_erase),
  758 
  759         { 0, 0 }
  760 };
  761 
  762 DEFINE_CLASS_1(cqspi, cqspi_driver, cqspi_methods,
  763     sizeof(struct cqspi_softc), simplebus_driver);
  764 
  765 DRIVER_MODULE(cqspi, simplebus, cqspi_driver, 0, 0);

Cache object: 31b91ca7ae06ae0883250578ec6eacf4


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.