From: Boris Brezillon <boris.brezillon@free-electrons.com>
To: Peter Pan <peterpandong@micron.com>
Cc: <richard@nod.at>, <computersforpeace@gmail.com>,
<arnaud.mouiche@gmail.com>, <thomas.petazzoni@free-electrons.com>,
<marex@denx.de>, <cyrille.pitchen@wedev4u.fr>,
<linux-mtd@lists.infradead.org>, <peterpansjtu@gmail.com>,
<linshunquan1@hisilicon.com>
Subject: Re: [PATCH v6 11/15] nand: spi: add basic operations support
Date: Tue, 30 May 2017 00:11:52 +0200 [thread overview]
Message-ID: <20170530001152.1d8beb72@bbrezillon> (raw)
In-Reply-To: <1495609631-18880-12-git-send-email-peterpandong@micron.com>
On Wed, 24 May 2017 15:07:07 +0800
Peter Pan <peterpandong@micron.com> wrote:
> This commit is to support read, readoob, write,
> writeoob and erase operations in the new spi nand
> framework. No ECC support right now.
I still don't understand why patch 10 and 11 are separated. I'd prefer
to see one single patch adding basic spi-nand support, that is,
everything to support detection+initialization+read/write access.
>
> Signed-off-by: Peter Pan <peterpandong@micron.com>
> ---
> drivers/mtd/nand/spi/core.c | 638 ++++++++++++++++++++++++++++++++++++++++++++
> include/linux/mtd/spinand.h | 3 +
> 2 files changed, 641 insertions(+)
>
> diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
> index 93ce212..6251469 100644
> --- a/drivers/mtd/nand/spi/core.c
> +++ b/drivers/mtd/nand/spi/core.c
> @@ -108,6 +108,222 @@ static int spinand_read_status(struct spinand_device *spinand, u8 *status)
> }
>
> /**
> + * spinand_get_cfg - get configuration register value
> + * @spinand: SPI NAND device structure
> + * @cfg: buffer to store value
> + * Description:
> + * Configuration register includes OTP config, Lock Tight enable/disable
> + * and Internal ECC enable/disable.
> + */
> +static int spinand_get_cfg(struct spinand_device *spinand, u8 *cfg)
> +{
> + return spinand_read_reg(spinand, REG_CFG, cfg);
> +}
> +
> +/**
> + * spinand_set_cfg - set value to configuration register
> + * @spinand: SPI NAND device structure
> + * @cfg: value to set
> + * Description:
> + * Configuration register includes OTP config, Lock Tight enable/disable
> + * and Internal ECC enable/disable.
> + */
> +static int spinand_set_cfg(struct spinand_device *spinand, u8 cfg)
> +{
> + return spinand_write_reg(spinand, REG_CFG, cfg);
> +}
> +
> +/**
> + * spinand_disable_ecc - disable internal ECC
> + * @spinand: SPI NAND device structure
> + */
> +static void spinand_disable_ecc(struct spinand_device *spinand)
> +{
> + u8 cfg = 0;
> +
> + spinand_get_cfg(spinand, &cfg);
> +
> + if ((cfg & CFG_ECC_MASK) == CFG_ECC_ENABLE) {
> + cfg &= ~CFG_ECC_ENABLE;
> + spinand_set_cfg(spinand, cfg);
> + }
Is this really a generic (manufacturer-agnostic) feature??? I had the
feeling that is was only working for Micron. If that's the case, this
'disable-ecc' step should be done in spi/micron.c in a
micron_spinand_init() function.
> +}
> +
> +/**
> + * spinand_write_enable - send command 06h to enable write or erase the
> + * NAND cells
> + * @spinand: SPI NAND device structure
> + */
> +static int spinand_write_enable(struct spinand_device *spinand)
> +{
> + struct spinand_op op;
> +
> + spinand_init_op(&op);
> + op.cmd = SPINAND_CMD_WR_ENABLE;
> +
> + return spinand_exec_op(spinand, &op);
> +}
> +
> +/**
> + * spinand_read_page_to_cache - send command 13h to read data from NAND array
> + * to cache
> + * @spinand: SPI NAND device structure
> + * @page_addr: page to read
> + */
> +static int spinand_read_page_to_cache(struct spinand_device *spinand,
> + u32 page_addr)
> +{
> + struct spinand_op op;
> +
> + spinand_init_op(&op);
> + op.cmd = SPINAND_CMD_PAGE_READ;
> + op.n_addr = 3;
> + op.addr[0] = (u8)(page_addr >> 16);
> + op.addr[1] = (u8)(page_addr >> 8);
> + op.addr[2] = (u8)page_addr;
> +
> + return spinand_exec_op(spinand, &op);
> +}
> +
> +/**
> + * spinand_get_address_bits - return address should be transferred
> + * by how many bits
> + * @opcode: command's operation code
> + */
> +static int spinand_get_address_bits(u8 opcode)
> +{
> + switch (opcode) {
> + case SPINAND_CMD_READ_FROM_CACHE_QUAD_IO:
> + return 4;
> + case SPINAND_CMD_READ_FROM_CACHE_DUAL_IO:
> + return 2;
> + default:
> + return 1;
> + }
> +}
> +
> +/**
> + * spinand_get_data_bits - return data should be transferred by how many bits
> + * @opcode: command's operation code
> + */
> +static int spinand_get_data_bits(u8 opcode)
> +{
> + switch (opcode) {
> + case SPINAND_CMD_READ_FROM_CACHE_QUAD_IO:
> + case SPINAND_CMD_READ_FROM_CACHE_X4:
> + case SPINAND_CMD_PROG_LOAD_X4:
> + case SPINAND_CMD_PROG_LOAD_RDM_DATA_X4:
> + return 4;
> + case SPINAND_CMD_READ_FROM_CACHE_DUAL_IO:
> + case SPINAND_CMD_READ_FROM_CACHE_X2:
> + return 2;
> + default:
> + return 1;
> + }
> +}
> +
> +/**
> + * spinand_read_from_cache - read data out from cache register
> + * @spinand: SPI NAND device structure
> + * @page_addr: page to read
> + * @column: the location to read from the cache
> + * @len: number of bytes to read
> + * @rbuf: buffer held @len bytes
> + */
> +static int spinand_read_from_cache(struct spinand_device *spinand,
> + u32 page_addr, u32 column,
> + size_t len, u8 *rbuf)
> +{
> + struct spinand_op op;
> +
> + spinand_init_op(&op);
> + op.cmd = spinand->read_cache_op;
> + op.n_addr = 2;
> + op.addr[0] = (u8)(column >> 8);
> + op.addr[1] = (u8)column;
Casts are unneeded here.
> + op.addr_nbits = spinand_get_address_bits(spinand->read_cache_op);
> + op.n_rx = len;
> + op.rx_buf = rbuf;
> + op.data_nbits = spinand_get_data_bits(spinand->read_cache_op);
> +
> + if (spinand->manufacturer.manu->ops->prepare_op)
> + spinand->manufacturer.manu->ops->prepare_op(spinand, &op,
> + page_addr, column);
> +
> + return spinand_exec_op(spinand, &op);
> +}
> +
> +/**
> + * spinand_write_to_cache - write data to cache register
> + * @spinand: SPI NAND device structure
> + * @page_addr: page to write
> + * @column: the location to write to the cache
> + * @len: number of bytes to write
> + * @wrbuf: buffer held @len bytes
> + */
> +static int spinand_write_to_cache(struct spinand_device *spinand, u32 page_addr,
> + u32 column, size_t len, const u8 *wbuf)
> +{
> + struct spinand_op op;
> +
> + spinand_init_op(&op);
> + op.cmd = spinand->write_cache_op;
> + op.n_addr = 2;
> + op.addr[0] = (u8)(column >> 8);
> + op.addr[1] = (u8)column;
> + op.addr_nbits = spinand_get_address_bits(spinand->write_cache_op);
> + op.n_tx = len;
> + op.tx_buf = wbuf;
> + op.data_nbits = spinand_get_data_bits(spinand->write_cache_op);
> +
> + if (spinand->manufacturer.manu->ops->prepare_op)
> + spinand->manufacturer.manu->ops->prepare_op(spinand, &op,
> + page_addr, column);
> +
> + return spinand_exec_op(spinand, &op);
> +}
> +
> +/**
> + * spinand_program_execute - send command 10h to write a page from
> + * cache to the NAND array
> + * @spinand: SPI NAND device structure
> + * @page_addr: the physical page location to write the page.
> + */
> +static int spinand_program_execute(struct spinand_device *spinand,
> + u32 page_addr)
> +{
> + struct spinand_op op;
> +
> + spinand_init_op(&op);
> + op.cmd = SPINAND_CMD_PROG_EXC;
> + op.n_addr = 3;
> + op.addr[0] = (u8)(page_addr >> 16);
> + op.addr[1] = (u8)(page_addr >> 8);
> + op.addr[2] = (u8)page_addr;
You don't need to adjust the number of dummy cycles here?
The usage of ->prepare_op() is really weird, maybe you should document
a bit more when it's supposed to be used.
> +
> + return spinand_exec_op(spinand, &op);
> +}
> +
[...]
>
> diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h
> index dd9da71..04ad1dd 100644
> --- a/include/linux/mtd/spinand.h
> +++ b/include/linux/mtd/spinand.h
> @@ -103,11 +103,14 @@ struct spinand_controller_ops {
> * return directly and let others to detect.
> * @init: initialize SPI NAND device.
> * @cleanup: clean SPI NAND device footprint.
> + * @prepare_op: prepara read/write operation.
^ prepare
> */
> struct spinand_manufacturer_ops {
> bool (*detect)(struct spinand_device *spinand);
> int (*init)(struct spinand_device *spinand);
> void (*cleanup)(struct spinand_device *spinand);
> + void (*prepare_op)(struct spinand_device *spinand,
> + struct spinand_op *op, u32 page, u32 column);
It seems to be here to prepare read/write page operations, so I'd like
to rename this method ->prepare_page_op() if you don't mind.
> };
>
> /**
next prev parent reply other threads:[~2017-05-29 22:12 UTC|newest]
Thread overview: 65+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-05-24 7:06 [PATCH v6 00/15] A SPI NAND framework under generic NAND framework Peter Pan
2017-05-24 7:06 ` [PATCH v6 01/15] mtd: nand: Rename nand.h into rawnand.h Peter Pan
2017-05-24 7:06 ` [PATCH v6 02/15] mtd: nand: move raw NAND related code to the raw/ subdir Peter Pan
2017-05-24 7:06 ` [PATCH v6 03/15] mtd: nand: add a nand.h file to expose basic NAND stuff Peter Pan
2017-05-29 20:14 ` Boris Brezillon
2017-05-24 7:07 ` [PATCH v6 04/15] mtd: nand: raw: prefix conflicting names with nandcchip instead of nand Peter Pan
2017-05-29 20:22 ` Boris Brezillon
2017-05-24 7:07 ` [PATCH v6 05/15] mtd: nand: raw: create struct rawnand_device Peter Pan
2017-05-29 21:05 ` Boris Brezillon
2017-05-24 7:07 ` [PATCH v6 06/15] mtd: nand: raw: make BBT code more generic Peter Pan
2017-05-24 7:07 ` [PATCH v6 07/15] mtd: nand: move BBT code to drivers/mtd/nand/ Peter Pan
2017-05-24 7:07 ` [PATCH v6 08/15] mtd: nand: Add the page iterator concept Peter Pan
2017-05-29 21:12 ` Boris Brezillon
2017-05-24 7:07 ` [PATCH v6 09/15] mtd: nand: make sure mtd_oob_ops consistent in bbt Peter Pan
2017-05-29 21:06 ` Boris Brezillon
2017-05-24 7:07 ` [PATCH v6 10/15] nand: spi: add basic blocks for infrastructure Peter Pan
2017-05-29 21:51 ` Boris Brezillon
2017-05-31 7:02 ` Peter Pan 潘栋 (peterpandong)
2017-05-31 21:45 ` Cyrille Pitchen
2017-06-01 7:24 ` Boris Brezillon
2017-05-24 7:07 ` [PATCH v6 11/15] nand: spi: add basic operations support Peter Pan
2017-05-29 22:11 ` Boris Brezillon [this message]
2017-05-31 6:51 ` Peter Pan 潘栋 (peterpandong)
2017-05-31 10:02 ` Boris Brezillon
2017-06-27 20:15 ` Boris Brezillon
2017-06-28 9:41 ` Arnaud Mouiche
2017-06-28 11:32 ` Boris Brezillon
2017-06-29 5:45 ` Peter Pan 潘栋 (peterpandong)
2017-06-29 6:07 ` Peter Pan 潘栋 (peterpandong)
2017-06-29 7:05 ` Arnaud Mouiche
2017-10-11 13:35 ` Boris Brezillon
2017-10-12 1:28 ` Peter Pan
2017-05-24 7:07 ` [PATCH v6 12/15] nand: spi: Add bad block support Peter Pan
2017-05-24 7:07 ` [PATCH v6 13/15] nand: spi: add Micron spi nand support Peter Pan
2017-05-24 7:07 ` [PATCH v6 14/15] nand: spi: Add generic SPI controller support Peter Pan
2017-05-24 7:07 ` [PATCH v6 15/15] MAINTAINERS: Add SPI NAND entry Peter Pan
2017-05-29 20:59 ` [PATCH v6 00/15] A SPI NAND framework under generic NAND framework Boris Brezillon
2017-12-04 13:32 ` Frieder Schrempf
2017-12-04 14:05 ` Boris Brezillon
2017-12-05 1:35 ` Peter Pan 潘栋 (peterpandong)
2017-12-05 12:58 ` Boris Brezillon
2017-12-05 13:03 ` Boris Brezillon
2017-12-12 9:58 ` Frieder Schrempf
2017-12-13 21:27 ` Boris Brezillon
2017-12-14 6:15 ` Peter Pan
2017-12-14 7:50 ` Boris Brezillon
2017-12-14 8:06 ` Peter Pan
2017-12-14 14:39 ` Frieder Schrempf
2017-12-14 14:43 ` Frieder Schrempf
2017-12-14 15:38 ` Boris Brezillon
2017-12-15 1:08 ` Peter Pan
2017-12-15 1:21 ` Peter Pan
2017-12-21 11:48 ` Frieder Schrempf
2017-12-21 13:01 ` Boris Brezillon
2017-12-21 13:54 ` Frieder Schrempf
2017-12-22 0:49 ` Peter Pan
2017-12-22 6:37 ` Peter Pan
2017-12-22 8:28 ` Boris Brezillon
2017-12-22 13:51 ` Boris Brezillon
2018-01-02 2:51 ` Peter Pan
2018-01-03 16:46 ` Boris Brezillon
2018-01-04 2:01 ` Peter Pan
2018-01-08 22:07 ` Boris Brezillon
2017-12-15 2:35 ` Peter Pan
2017-12-15 12:41 ` Boris Brezillon
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170530001152.1d8beb72@bbrezillon \
--to=boris.brezillon@free-electrons.com \
--cc=arnaud.mouiche@gmail.com \
--cc=computersforpeace@gmail.com \
--cc=cyrille.pitchen@wedev4u.fr \
--cc=linshunquan1@hisilicon.com \
--cc=linux-mtd@lists.infradead.org \
--cc=marex@denx.de \
--cc=peterpandong@micron.com \
--cc=peterpansjtu@gmail.com \
--cc=richard@nod.at \
--cc=thomas.petazzoni@free-electrons.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).