All of lore.kernel.org
 help / color / mirror / Atom feed
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.

>  };
>  
>  /**

  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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.