[PATCH v2 3/4] mtd: spinand: Add support continuous read operation

liao jaime jaimeliao.tw at gmail.com
Thu Apr 27 02:58:10 PDT 2023


Hi Chuanhong

>
> Hi!
>
> On Thu, Feb 9, 2023 at 8:10 PM Jaime Liao <jaimeliao.tw at gmail.com> wrote:
> > [...]
> > +static int spinand_mtd_continuous_read(struct mtd_info *mtd, loff_t from,
> > +                                      struct mtd_oob_ops *ops,
> > +                                      struct nand_io_iter *iter)
> > +{
> > +       struct spinand_device *spinand = mtd_to_spinand(mtd);
> > +       struct nand_device *nand = mtd_to_nanddev(mtd);
> > +       int ret = 0;
> > +
> > +       /*
> > +        * Continuous read mode could reduce some operation in On-die ECC free
> > +        * flash when read page sequentially.
> > +        */
> > +       iter->req.type = NAND_PAGE_READ;
> > +       iter->req.mode = MTD_OPS_RAW;
> > +       iter->req.dataoffs = nanddev_offs_to_pos(nand, from, &iter->req.pos);
> > +       iter->req.databuf.in = ops->datbuf;
> > +       iter->req.datalen = ops->len;
> > +
> > +       if (from & (nanddev_page_size(nand) - 1)) {
> > +               pr_debug("%s: unaligned address\n", __func__);
> > +               return -EINVAL;
> > +       }
> > +
> > +       ret = spinand_continuous_read_enable(spinand);
> > +       if (ret)
> > +               return ret;
> > +
> > +       spinand->use_continuous_read = true;
> > +
> > +       ret = spinand_select_target(spinand, iter->req.pos.target);
> > +       if (ret)
> > +               return ret;
> > +
> > +       /*
> > +        * The continuous read operation including: firstly, starting with the
> > +        * page read command and the 1 st page data will be read into the cache
> > +        * after the read latency tRD. Secondly, Issuing the Read From Cache
> > +        * commands (03h/0Bh/3Bh/6Bh/BBh/EBh) to read out the data from cache
> > +        * continuously.
> > +        *
> > +        * The cache is divided into two halves, while one half of the cache is
> > +        * outputting the data, the other half will be loaded for the new data;
> > +        * therefore, the host can read out the data continuously from page to
> > +        * page. Multiple of Read From Cache commands can be issued in one
> > +        * continuous read operation, each Read From Cache command is required
> > +        * to read multiple 4-byte data exactly; otherwise, the data output will
> > +        * be out of sequence from one Read From Cache command to another Read
> > +        * From Cache command.
> > +        *
> > +        * After all the data is read out, the host should pull CS# high to
> > +        * terminate this continuous read operation and wait a 6us of tRST for
> > +        * the NAND device resets read operation. The data output for each page
> > +        * will always start from byte 0 and a full page data should be read out
> > +        * for each page.
> > +        */
>
> This mode requires the entire read_from_cache op to finish in one command.
> i.e. there can only be one read_from_cache command and the chip-select
> can only be pulled low exactly once.
> There's no guarantee that spinand_read_from_cache_op issues exactly one
> command. spi-mem controllers may have a transfer size limit, requiring an
> operation to be split into multiple read_from_cache requests with different
> column addresses. spi-mem controllers with dirmap support can map a
> memory space to a specific spi-mem read operation, and reading from this
> memory-mapped space also isn't guaranteed to be completed in one
> command. (Controllers may decide to respond to a bus read request using
> multiple spi-mem ops with auto-incremented op addr.)
> So, in order to use this mode, you can't reuse the spinand_read_from_cache_op
> function. Instead, you should write a new function for read_from_cache
> using spi_mem_adjust_op_size and spi_mem_exec_op: When calling
> adjust_op_size, check whether the op size is truncated. If it is, current
> continuous_read request should be aborted and fallback to the normal
> read mode.
As I know, data read could be handle by DMA engine even data length is
greater than
controller limit.
In spi-mem.c, spi_mem_adjust_op_size are using when "no_dirmap" so
that I not sure
that is import for checking before continuous read.
Should I check dirmap mode before enable continuous read?

Thanks your reply.
Jaime

>
> > +       ret = spinand_read_page(spinand, &iter->req);
> > +       if (ret)
> > +               goto continuous_read_error;
> > +
> > +       ret = spinand_reset_op(spinand);
> > +       if (ret)
> > +               goto continuous_read_error;
> > +
>
> --
> Regards,
> Chuanhong Guo



More information about the linux-mtd mailing list