All of lore.kernel.org
 help / color / mirror / Atom feed
From: Boris Brezillon <boris.brezillon@free-electrons.com>
To: Stefan Agner <stefan@agner.ch>
Cc: Mark Rutland <mark.rutland@arm.com>, Andrew Lunn <andrew@lunn.ch>,
	Catalin Marinas <catalin.marinas@arm.com>,
	Hanna Hawa <hannah@marvell.com>,
	Will Deacon <will.deacon@arm.com>,
	Nadav Haklai <nadavh@marvell.com>,
	Masahiro Yamada <yamada.masahiro@socionext.com>,
	linux-mtd@lists.infradead.org,
	Matthias Brugger <matthias.bgg@gmail.com>,
	Robert Jarzmik <robert.jarzmik@free.fr>,
	devel@driverdev.osuosl.org,
	Maxim Levitsky <maximlevitsky@gmail.com>,
	Kamal Dasu <kdasu.kdev@gmail.com>,
	Josh Wu <rainyfeeling@outlook.com>,
	Russell King <linux@armlinux.org.uk>,
	Marek Vasut <marek.vasut@gmail.com>, Chen-Yu Tsai <wens@csie.org>,
	bcm-kernel-feedback-list@broadcom.com,
	Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>,
	Ezequiel Garcia <ezequiel.garcia@free-electrons.com>,
	Sylvain Lemieux <slemieux.tyco@gmail.com>,
	Marc Gonzalez <marc_gonzalez@sigmadesigns.com>,
	devicetree@vger.ker
Subject: Re: [RFC 02/12] mtd: nand: force drivers to explicitly send READ/PROG commands
Date: Fri, 20 Oct 2017 13:18:34 +0200	[thread overview]
Message-ID: <20171020131834.704e2adc@bbrezillon> (raw)
In-Reply-To: <af6a28eeafc9379c3f4e8bb03ff60fc7@agner.ch>

On Fri, 20 Oct 2017 11:29:18 +0200
Stefan Agner <stefan@agner.ch> wrote:

> Hi Miquel,
> 
> Thanks for the work on this, happy to see the new interface is moving
> forward. Some comments below.
> 
> On 2017-10-18 16:36, Miquel Raynal wrote:
> > From: Boris Brezillon <boris.brezillon@free-electrons.com>
> > 
> > The core currently send the READ0 and SEQIN+PAGEPROG commands in
> > nand_do_read/write_ops(). This is inconsistent with  
> > ->read/write_oob[_raw]() hooks behavior which are expected to send  
> > these commands.
> > 
> > There's already a flag (NAND_ECC_CUSTOM_PAGE_ACCESS) to inform the core
> > that a specific controller wants to send the READ/SEQIN+PAGEPROG
> > commands on its own, but it's an opt-in flag, and existing drivers are
> > unlikely to be updated to pass it.
> > 
> > Moreover, some controllers cannot dissociate the READ/PAGEPROG commands
> > from the associated data transfer and ECC engine activation, and
> > developers have to hack things in their ->cmdfunc() implementation to
> > handle such complex cases, or have to accept the perf penalty of sending
> > twice the same command.
> > To address this problem we are planning on adding a new interface which
> > is passed all information about a NAND operation (including the amount
> > of data to transfer) and replacing all calls to ->cmdfunc() to calls to
> > this new ->exec_op() hook. But, in order to do that, we need to have all  
> > ->cmdfunc() calls placed near their associated ->read/write_buf/byte()  
> > calls.
> > 
> > Modify the core and relevant drivers to make NAND_ECC_CUSTOM_PAGE_ACCESS
> > the default case, and remove this flag.
> > 
> > Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
> > [miquel.raynal@free-electrons.com: rebased and fixed some conflicts]
> > Signed-off-by: Miquel Raynal <miquel.raynal@free-electrons.com>
> > ---
> >  drivers/mtd/nand/atmel/nand-controller.c      |  7 ++-
> >  drivers/mtd/nand/bf5xx_nand.c                 |  6 ++-
> >  drivers/mtd/nand/brcmnand/brcmnand.c          | 13 +++--
> >  drivers/mtd/nand/cafe_nand.c                  |  6 +--
> >  drivers/mtd/nand/denali.c                     | 14 +++++-
> >  drivers/mtd/nand/docg4.c                      | 12 +++--
> >  drivers/mtd/nand/fsl_elbc_nand.c              |  6 +--
> >  drivers/mtd/nand/fsl_ifc_nand.c               |  6 +--
> >  drivers/mtd/nand/gpmi-nand/gpmi-nand.c        | 30 ++++++------
> >  drivers/mtd/nand/hisi504_nand.c               |  6 +--
> >  drivers/mtd/nand/lpc32xx_mlc.c                |  5 +-
> >  drivers/mtd/nand/lpc32xx_slc.c                | 11 +++--
> >  drivers/mtd/nand/mtk_nand.c                   | 10 ++--
> >  drivers/mtd/nand/nand_base.c                  | 68 +++++++++------------------
> >  drivers/mtd/nand/nand_micron.c                |  1 -
> >  drivers/mtd/nand/sh_flctl.c                   |  6 +--
> >  drivers/mtd/nand/sunxi_nand.c                 | 34 +++++++++-----
> >  drivers/mtd/nand/tango_nand.c                 |  1 -
> >  drivers/mtd/nand/vf610_nfc.c                  |  6 +--
> >  drivers/staging/mt29f_spinand/mt29f_spinand.c |  7 ++-
> >  include/linux/mtd/rawnand.h                   | 11 -----
> >  21 files changed, 142 insertions(+), 124 deletions(-)
> >   
> 
> <snip>
> 
> > diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> > b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> > index c8ceaecd8065..3f2b903158c1 100644
> > --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> > +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> > @@ -1043,6 +1043,8 @@ static int gpmi_ecc_read_page(struct mtd_info
> > *mtd, struct nand_chip *chip,
> >  	unsigned int  max_bitflips = 0;
> >  	int           ret;
> >  
> > +	nand_read_page_op(chip, page, 0, NULL, 0);
> > +
> >  	dev_dbg(this->dev, "page number is : %d\n", page);
> >  	ret = read_page_prepare(this, buf, nfc_geo->payload_size,
> >  					this->payload_virt, this->payload_phys,
> > @@ -1220,12 +1222,13 @@ static int gpmi_ecc_read_subpage(struct
> > mtd_info *mtd, struct nand_chip *chip,
> >  	meta = geo->metadata_size;
> >  	if (first) {
> >  		col = meta + (size + ecc_parity_size) * first;
> > -		chip->cmdfunc(mtd, NAND_CMD_RNDOUT, col, -1);  
> 
> Shouldn't we add nand_change_read_column_op here?
> 
> 
> >  
> >  		meta = 0;
> >  		buf = buf + first * size;
> >  	}
> >  
> > +	nand_read_page_op(chip, page, col, NULL, 0);
> > +
> >  	/* Save the old environment */
> >  	r1_old = r1_new = readl(bch_regs + HW_BCH_FLASH0LAYOUT0);
> >  	r2_old = r2_new = readl(bch_regs + HW_BCH_FLASH0LAYOUT1);
> > @@ -1277,6 +1280,9 @@ static int gpmi_ecc_write_page(struct mtd_info
> > *mtd, struct nand_chip *chip,
> >  	int        ret;
> >  
> >  	dev_dbg(this->dev, "ecc write page.\n");
> > +
> > +	nand_prog_page_begin_op(chip, page, 0, NULL, 0);
> > +
> >  	if (this->swap_block_mark) {
> >  		/*
> >  		 * If control arrives here, we're doing block mark swapping.
> > @@ -1338,7 +1344,10 @@ static int gpmi_ecc_write_page(struct mtd_info
> > *mtd, struct nand_chip *chip,
> >  				payload_virt, payload_phys);
> >  	}
> >  
> > -	return 0;
> > +	if (ret)
> > +		return ret;
> > +
> > +	return nand_prog_page_end_op(chip);
> >  }
> >  
> >  /*
> > @@ -1472,8 +1481,8 @@ static int gpmi_ecc_read_page_raw(struct mtd_info *mtd,
> >  	uint8_t *oob = chip->oob_poi;
> >  	int step;
> >  
> > -	chip->read_buf(mtd, tmp_buf,
> > -		       mtd->writesize + mtd->oobsize);
> > +	nand_read_page_op(chip, page, 0, tmp_buf,
> > +			  mtd->writesize + mtd->oobsize);
> >  
> >  	/*
> >  	 * If required, swap the bad block marker and the data stored in the
> > @@ -1617,24 +1626,19 @@ static int gpmi_ecc_write_page_raw(struct mtd_info *mtd,
> >  		tmp_buf[mtd->writesize] = swap;
> >  	}
> >  
> > -	chip->write_buf(mtd, tmp_buf, mtd->writesize + mtd->oobsize);
> > -
> > -	return 0;
> > +	return nand_prog_page_op(chip, page, 0, tmp_buf,
> > +				 mtd->writesize + mtd->oobsize);
> >  }
> >  
> >  static int gpmi_ecc_read_oob_raw(struct mtd_info *mtd, struct nand_chip *chip,
> >  				 int page)
> >  {
> > -	nand_read_page_op(chip, page, 0, NULL, 0);
> > -
> >  	return gpmi_ecc_read_page_raw(mtd, chip, NULL, 1, page);
> >  }
> >  
> >  static int gpmi_ecc_write_oob_raw(struct mtd_info *mtd, struct nand_chip *chip,
> >  				 int page)
> >  {
> > -	nand_prog_page_begin_op(chip, page, 0, NULL, 0);
> > -
> >  	return gpmi_ecc_write_page_raw(mtd, chip, NULL, 1, page);
> >  }
> >  
> > @@ -1806,9 +1810,7 @@ static int mx23_write_transcription_stamp(struct
> > gpmi_nand_data *this)
> >  		/* Write the first page of the current stride. */
> >  		dev_dbg(dev, "Writing an NCB fingerprint in page 0x%x\n", page);
> >  
> > -		nand_prog_page_begin_op(chip, page, 0, NULL, 0);
> > -		chip->ecc.write_page_raw(mtd, chip, buffer, 0, page);
> > -		status = nand_prog_page_end_op(chip);
> > +		status = chip->ecc.write_page_raw(mtd, chip, buffer, 0, page);
> >  		if (status)
> >  			dev_err(dev, "[%s] Write failed.\n", __func__);
> >  	}  
> 
> <snip>
> 
> > diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c
> > index 8037d4b48a05..80d31a58e558 100644
> > --- a/drivers/mtd/nand/vf610_nfc.c
> > +++ b/drivers/mtd/nand/vf610_nfc.c
> > @@ -560,7 +560,7 @@ static int vf610_nfc_read_page(struct mtd_info
> > *mtd, struct nand_chip *chip,
> >  	int eccsize = chip->ecc.size;
> >  	int stat;
> >  
> > -	vf610_nfc_read_buf(mtd, buf, eccsize);
> > +	nand_read_page_op(chip, page, 0, buf, eccsize);
> >  	if (oob_required)
> >  		vf610_nfc_read_buf(mtd, chip->oob_poi, mtd->oobsize);
> >  
> > @@ -580,7 +580,7 @@ static int vf610_nfc_write_page(struct mtd_info
> > *mtd, struct nand_chip *chip,
> >  {
> >  	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
> >  
> > -	vf610_nfc_write_buf(mtd, buf, mtd->writesize);  
> 
> We currently ignore NAND_CMD_SEQIN in ->cmdfunc anyway, so I think this
> change would not even be necessary here.

Well, the thing is, we're trying to keep the logic unchanged. Even if
for your driver ->cmdfunc(NAND_CMD_SEQIN) is a NOP, I'd prefer to be
consistent and still replace this ->write_buf() call by a
nand_prog_page_begin_op() one.

> 
> This is a NAND controller which will benefit from the new interface. I
> plan to convert the driver to the new interface, maybe I manage to do
> that soon so we have a second driver making use of the new interface.

Great!!! Let us know if you need any help.

Regards,

Boris

WARNING: multiple messages have this Message-ID (diff)
From: Boris Brezillon <boris.brezillon@free-electrons.com>
To: Stefan Agner <stefan@agner.ch>
Cc: Miquel Raynal <miquel.raynal@free-electrons.com>,
	Andrew Lunn <andrew@lunn.ch>,
	bcm-kernel-feedback-list@broadcom.com,
	Brian Norris <computersforpeace@gmail.com>,
	Catalin Marinas <catalin.marinas@arm.com>,
	Chen-Yu Tsai <wens@csie.org>,
	Cyrille Pitchen <cyrille.pitchen@wedev4u.fr>,
	Daniel Mack <daniel@zonque.org>,
	David Woodhouse <dwmw2@infradead.org>,
	devel@driverdev.osuosl.org, devicetree@vger.kernel.org,
	Ezequiel Garcia <ezequiel.garcia@free-electrons.com>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Gregory Clement <gregory.clement@free-electrons.com>,
	Han Xu <han.xu@nxp.com>,
	Haojian Zhuang <haojian.zhuang@gmail.com>,
	Jason Cooper <jason@lakedaemon.net>,
	Josh Wu <rainyfeeling@outlook.com>,
	Kamal Dasu <kdasu.kdev@gmail.com>,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-mediatek@lists.infradead.org,
	linux-mtd@lists.infradead.org,
	Marc Gonzalez <marc_gonzalez@sigmadesigns.com>,
	Marek Vasut <marek.vasut@gmail.com>,
	Mark Rutland <mark.rutland@arm.com>,
	Masahiro Yamada <yamada.masahiro@socionext.com>,
	Matthias Brugger <matthias.bgg@gmail.com>,
	Maxime Ripard <maxime.ripard@free-electrons.com>,
	Maxim Levitsky <maximlevitsky@gmail.com>,
	Richard Weinberger <richard@nod.at>,
	Robert Jarzmik <robert.jarzmik@free.fr>,
	Rob Herring <robh+dt@kernel.org>,
	Russell King <linux@armlinux.org.uk>,
	Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>,
	Sylvain Lemieux <slemieux.tyco@gmail.com>,
	Vladimir Zapolskiy <vz@mleia.com>,
	Wenyou Yang <wenyou.yang@atmel.com>,
	Will Deacon <will.deacon@arm.com>,
	Thomas Petazzoni <thomas.petazzoni@free-electrons.com>,
	Antoine Tenart <antoine.tenart@free-electrons.com>,
	Igor Grinberg <grinberg@compulab.co.il>,
	Nadav Haklai <nadavh@marvell.com>,
	Ofer Heifetz <oferh@marvell.com>,
	Neta Zur Hershkovits <neta@marvell.com>,
	Hanna Hawa <hannah@marvell.com>
Subject: Re: [RFC 02/12] mtd: nand: force drivers to explicitly send READ/PROG commands
Date: Fri, 20 Oct 2017 13:18:34 +0200	[thread overview]
Message-ID: <20171020131834.704e2adc@bbrezillon> (raw)
In-Reply-To: <af6a28eeafc9379c3f4e8bb03ff60fc7@agner.ch>

On Fri, 20 Oct 2017 11:29:18 +0200
Stefan Agner <stefan@agner.ch> wrote:

> Hi Miquel,
> 
> Thanks for the work on this, happy to see the new interface is moving
> forward. Some comments below.
> 
> On 2017-10-18 16:36, Miquel Raynal wrote:
> > From: Boris Brezillon <boris.brezillon@free-electrons.com>
> > 
> > The core currently send the READ0 and SEQIN+PAGEPROG commands in
> > nand_do_read/write_ops(). This is inconsistent with  
> > ->read/write_oob[_raw]() hooks behavior which are expected to send  
> > these commands.
> > 
> > There's already a flag (NAND_ECC_CUSTOM_PAGE_ACCESS) to inform the core
> > that a specific controller wants to send the READ/SEQIN+PAGEPROG
> > commands on its own, but it's an opt-in flag, and existing drivers are
> > unlikely to be updated to pass it.
> > 
> > Moreover, some controllers cannot dissociate the READ/PAGEPROG commands
> > from the associated data transfer and ECC engine activation, and
> > developers have to hack things in their ->cmdfunc() implementation to
> > handle such complex cases, or have to accept the perf penalty of sending
> > twice the same command.
> > To address this problem we are planning on adding a new interface which
> > is passed all information about a NAND operation (including the amount
> > of data to transfer) and replacing all calls to ->cmdfunc() to calls to
> > this new ->exec_op() hook. But, in order to do that, we need to have all  
> > ->cmdfunc() calls placed near their associated ->read/write_buf/byte()  
> > calls.
> > 
> > Modify the core and relevant drivers to make NAND_ECC_CUSTOM_PAGE_ACCESS
> > the default case, and remove this flag.
> > 
> > Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
> > [miquel.raynal@free-electrons.com: rebased and fixed some conflicts]
> > Signed-off-by: Miquel Raynal <miquel.raynal@free-electrons.com>
> > ---
> >  drivers/mtd/nand/atmel/nand-controller.c      |  7 ++-
> >  drivers/mtd/nand/bf5xx_nand.c                 |  6 ++-
> >  drivers/mtd/nand/brcmnand/brcmnand.c          | 13 +++--
> >  drivers/mtd/nand/cafe_nand.c                  |  6 +--
> >  drivers/mtd/nand/denali.c                     | 14 +++++-
> >  drivers/mtd/nand/docg4.c                      | 12 +++--
> >  drivers/mtd/nand/fsl_elbc_nand.c              |  6 +--
> >  drivers/mtd/nand/fsl_ifc_nand.c               |  6 +--
> >  drivers/mtd/nand/gpmi-nand/gpmi-nand.c        | 30 ++++++------
> >  drivers/mtd/nand/hisi504_nand.c               |  6 +--
> >  drivers/mtd/nand/lpc32xx_mlc.c                |  5 +-
> >  drivers/mtd/nand/lpc32xx_slc.c                | 11 +++--
> >  drivers/mtd/nand/mtk_nand.c                   | 10 ++--
> >  drivers/mtd/nand/nand_base.c                  | 68 +++++++++------------------
> >  drivers/mtd/nand/nand_micron.c                |  1 -
> >  drivers/mtd/nand/sh_flctl.c                   |  6 +--
> >  drivers/mtd/nand/sunxi_nand.c                 | 34 +++++++++-----
> >  drivers/mtd/nand/tango_nand.c                 |  1 -
> >  drivers/mtd/nand/vf610_nfc.c                  |  6 +--
> >  drivers/staging/mt29f_spinand/mt29f_spinand.c |  7 ++-
> >  include/linux/mtd/rawnand.h                   | 11 -----
> >  21 files changed, 142 insertions(+), 124 deletions(-)
> >   
> 
> <snip>
> 
> > diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> > b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> > index c8ceaecd8065..3f2b903158c1 100644
> > --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> > +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> > @@ -1043,6 +1043,8 @@ static int gpmi_ecc_read_page(struct mtd_info
> > *mtd, struct nand_chip *chip,
> >  	unsigned int  max_bitflips = 0;
> >  	int           ret;
> >  
> > +	nand_read_page_op(chip, page, 0, NULL, 0);
> > +
> >  	dev_dbg(this->dev, "page number is : %d\n", page);
> >  	ret = read_page_prepare(this, buf, nfc_geo->payload_size,
> >  					this->payload_virt, this->payload_phys,
> > @@ -1220,12 +1222,13 @@ static int gpmi_ecc_read_subpage(struct
> > mtd_info *mtd, struct nand_chip *chip,
> >  	meta = geo->metadata_size;
> >  	if (first) {
> >  		col = meta + (size + ecc_parity_size) * first;
> > -		chip->cmdfunc(mtd, NAND_CMD_RNDOUT, col, -1);  
> 
> Shouldn't we add nand_change_read_column_op here?
> 
> 
> >  
> >  		meta = 0;
> >  		buf = buf + first * size;
> >  	}
> >  
> > +	nand_read_page_op(chip, page, col, NULL, 0);
> > +
> >  	/* Save the old environment */
> >  	r1_old = r1_new = readl(bch_regs + HW_BCH_FLASH0LAYOUT0);
> >  	r2_old = r2_new = readl(bch_regs + HW_BCH_FLASH0LAYOUT1);
> > @@ -1277,6 +1280,9 @@ static int gpmi_ecc_write_page(struct mtd_info
> > *mtd, struct nand_chip *chip,
> >  	int        ret;
> >  
> >  	dev_dbg(this->dev, "ecc write page.\n");
> > +
> > +	nand_prog_page_begin_op(chip, page, 0, NULL, 0);
> > +
> >  	if (this->swap_block_mark) {
> >  		/*
> >  		 * If control arrives here, we're doing block mark swapping.
> > @@ -1338,7 +1344,10 @@ static int gpmi_ecc_write_page(struct mtd_info
> > *mtd, struct nand_chip *chip,
> >  				payload_virt, payload_phys);
> >  	}
> >  
> > -	return 0;
> > +	if (ret)
> > +		return ret;
> > +
> > +	return nand_prog_page_end_op(chip);
> >  }
> >  
> >  /*
> > @@ -1472,8 +1481,8 @@ static int gpmi_ecc_read_page_raw(struct mtd_info *mtd,
> >  	uint8_t *oob = chip->oob_poi;
> >  	int step;
> >  
> > -	chip->read_buf(mtd, tmp_buf,
> > -		       mtd->writesize + mtd->oobsize);
> > +	nand_read_page_op(chip, page, 0, tmp_buf,
> > +			  mtd->writesize + mtd->oobsize);
> >  
> >  	/*
> >  	 * If required, swap the bad block marker and the data stored in the
> > @@ -1617,24 +1626,19 @@ static int gpmi_ecc_write_page_raw(struct mtd_info *mtd,
> >  		tmp_buf[mtd->writesize] = swap;
> >  	}
> >  
> > -	chip->write_buf(mtd, tmp_buf, mtd->writesize + mtd->oobsize);
> > -
> > -	return 0;
> > +	return nand_prog_page_op(chip, page, 0, tmp_buf,
> > +				 mtd->writesize + mtd->oobsize);
> >  }
> >  
> >  static int gpmi_ecc_read_oob_raw(struct mtd_info *mtd, struct nand_chip *chip,
> >  				 int page)
> >  {
> > -	nand_read_page_op(chip, page, 0, NULL, 0);
> > -
> >  	return gpmi_ecc_read_page_raw(mtd, chip, NULL, 1, page);
> >  }
> >  
> >  static int gpmi_ecc_write_oob_raw(struct mtd_info *mtd, struct nand_chip *chip,
> >  				 int page)
> >  {
> > -	nand_prog_page_begin_op(chip, page, 0, NULL, 0);
> > -
> >  	return gpmi_ecc_write_page_raw(mtd, chip, NULL, 1, page);
> >  }
> >  
> > @@ -1806,9 +1810,7 @@ static int mx23_write_transcription_stamp(struct
> > gpmi_nand_data *this)
> >  		/* Write the first page of the current stride. */
> >  		dev_dbg(dev, "Writing an NCB fingerprint in page 0x%x\n", page);
> >  
> > -		nand_prog_page_begin_op(chip, page, 0, NULL, 0);
> > -		chip->ecc.write_page_raw(mtd, chip, buffer, 0, page);
> > -		status = nand_prog_page_end_op(chip);
> > +		status = chip->ecc.write_page_raw(mtd, chip, buffer, 0, page);
> >  		if (status)
> >  			dev_err(dev, "[%s] Write failed.\n", __func__);
> >  	}  
> 
> <snip>
> 
> > diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c
> > index 8037d4b48a05..80d31a58e558 100644
> > --- a/drivers/mtd/nand/vf610_nfc.c
> > +++ b/drivers/mtd/nand/vf610_nfc.c
> > @@ -560,7 +560,7 @@ static int vf610_nfc_read_page(struct mtd_info
> > *mtd, struct nand_chip *chip,
> >  	int eccsize = chip->ecc.size;
> >  	int stat;
> >  
> > -	vf610_nfc_read_buf(mtd, buf, eccsize);
> > +	nand_read_page_op(chip, page, 0, buf, eccsize);
> >  	if (oob_required)
> >  		vf610_nfc_read_buf(mtd, chip->oob_poi, mtd->oobsize);
> >  
> > @@ -580,7 +580,7 @@ static int vf610_nfc_write_page(struct mtd_info
> > *mtd, struct nand_chip *chip,
> >  {
> >  	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
> >  
> > -	vf610_nfc_write_buf(mtd, buf, mtd->writesize);  
> 
> We currently ignore NAND_CMD_SEQIN in ->cmdfunc anyway, so I think this
> change would not even be necessary here.

Well, the thing is, we're trying to keep the logic unchanged. Even if
for your driver ->cmdfunc(NAND_CMD_SEQIN) is a NOP, I'd prefer to be
consistent and still replace this ->write_buf() call by a
nand_prog_page_begin_op() one.

> 
> This is a NAND controller which will benefit from the new interface. I
> plan to convert the driver to the new interface, maybe I manage to do
> that soon so we have a second driver making use of the new interface.

Great!!! Let us know if you need any help.

Regards,

Boris

WARNING: multiple messages have this Message-ID (diff)
From: boris.brezillon@free-electrons.com (Boris Brezillon)
To: linux-arm-kernel@lists.infradead.org
Subject: [RFC 02/12] mtd: nand: force drivers to explicitly send READ/PROG commands
Date: Fri, 20 Oct 2017 13:18:34 +0200	[thread overview]
Message-ID: <20171020131834.704e2adc@bbrezillon> (raw)
In-Reply-To: <af6a28eeafc9379c3f4e8bb03ff60fc7@agner.ch>

On Fri, 20 Oct 2017 11:29:18 +0200
Stefan Agner <stefan@agner.ch> wrote:

> Hi Miquel,
> 
> Thanks for the work on this, happy to see the new interface is moving
> forward. Some comments below.
> 
> On 2017-10-18 16:36, Miquel Raynal wrote:
> > From: Boris Brezillon <boris.brezillon@free-electrons.com>
> > 
> > The core currently send the READ0 and SEQIN+PAGEPROG commands in
> > nand_do_read/write_ops(). This is inconsistent with  
> > ->read/write_oob[_raw]() hooks behavior which are expected to send  
> > these commands.
> > 
> > There's already a flag (NAND_ECC_CUSTOM_PAGE_ACCESS) to inform the core
> > that a specific controller wants to send the READ/SEQIN+PAGEPROG
> > commands on its own, but it's an opt-in flag, and existing drivers are
> > unlikely to be updated to pass it.
> > 
> > Moreover, some controllers cannot dissociate the READ/PAGEPROG commands
> > from the associated data transfer and ECC engine activation, and
> > developers have to hack things in their ->cmdfunc() implementation to
> > handle such complex cases, or have to accept the perf penalty of sending
> > twice the same command.
> > To address this problem we are planning on adding a new interface which
> > is passed all information about a NAND operation (including the amount
> > of data to transfer) and replacing all calls to ->cmdfunc() to calls to
> > this new ->exec_op() hook. But, in order to do that, we need to have all  
> > ->cmdfunc() calls placed near their associated ->read/write_buf/byte()  
> > calls.
> > 
> > Modify the core and relevant drivers to make NAND_ECC_CUSTOM_PAGE_ACCESS
> > the default case, and remove this flag.
> > 
> > Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
> > [miquel.raynal at free-electrons.com: rebased and fixed some conflicts]
> > Signed-off-by: Miquel Raynal <miquel.raynal@free-electrons.com>
> > ---
> >  drivers/mtd/nand/atmel/nand-controller.c      |  7 ++-
> >  drivers/mtd/nand/bf5xx_nand.c                 |  6 ++-
> >  drivers/mtd/nand/brcmnand/brcmnand.c          | 13 +++--
> >  drivers/mtd/nand/cafe_nand.c                  |  6 +--
> >  drivers/mtd/nand/denali.c                     | 14 +++++-
> >  drivers/mtd/nand/docg4.c                      | 12 +++--
> >  drivers/mtd/nand/fsl_elbc_nand.c              |  6 +--
> >  drivers/mtd/nand/fsl_ifc_nand.c               |  6 +--
> >  drivers/mtd/nand/gpmi-nand/gpmi-nand.c        | 30 ++++++------
> >  drivers/mtd/nand/hisi504_nand.c               |  6 +--
> >  drivers/mtd/nand/lpc32xx_mlc.c                |  5 +-
> >  drivers/mtd/nand/lpc32xx_slc.c                | 11 +++--
> >  drivers/mtd/nand/mtk_nand.c                   | 10 ++--
> >  drivers/mtd/nand/nand_base.c                  | 68 +++++++++------------------
> >  drivers/mtd/nand/nand_micron.c                |  1 -
> >  drivers/mtd/nand/sh_flctl.c                   |  6 +--
> >  drivers/mtd/nand/sunxi_nand.c                 | 34 +++++++++-----
> >  drivers/mtd/nand/tango_nand.c                 |  1 -
> >  drivers/mtd/nand/vf610_nfc.c                  |  6 +--
> >  drivers/staging/mt29f_spinand/mt29f_spinand.c |  7 ++-
> >  include/linux/mtd/rawnand.h                   | 11 -----
> >  21 files changed, 142 insertions(+), 124 deletions(-)
> >   
> 
> <snip>
> 
> > diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> > b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> > index c8ceaecd8065..3f2b903158c1 100644
> > --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> > +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> > @@ -1043,6 +1043,8 @@ static int gpmi_ecc_read_page(struct mtd_info
> > *mtd, struct nand_chip *chip,
> >  	unsigned int  max_bitflips = 0;
> >  	int           ret;
> >  
> > +	nand_read_page_op(chip, page, 0, NULL, 0);
> > +
> >  	dev_dbg(this->dev, "page number is : %d\n", page);
> >  	ret = read_page_prepare(this, buf, nfc_geo->payload_size,
> >  					this->payload_virt, this->payload_phys,
> > @@ -1220,12 +1222,13 @@ static int gpmi_ecc_read_subpage(struct
> > mtd_info *mtd, struct nand_chip *chip,
> >  	meta = geo->metadata_size;
> >  	if (first) {
> >  		col = meta + (size + ecc_parity_size) * first;
> > -		chip->cmdfunc(mtd, NAND_CMD_RNDOUT, col, -1);  
> 
> Shouldn't we add nand_change_read_column_op here?
> 
> 
> >  
> >  		meta = 0;
> >  		buf = buf + first * size;
> >  	}
> >  
> > +	nand_read_page_op(chip, page, col, NULL, 0);
> > +
> >  	/* Save the old environment */
> >  	r1_old = r1_new = readl(bch_regs + HW_BCH_FLASH0LAYOUT0);
> >  	r2_old = r2_new = readl(bch_regs + HW_BCH_FLASH0LAYOUT1);
> > @@ -1277,6 +1280,9 @@ static int gpmi_ecc_write_page(struct mtd_info
> > *mtd, struct nand_chip *chip,
> >  	int        ret;
> >  
> >  	dev_dbg(this->dev, "ecc write page.\n");
> > +
> > +	nand_prog_page_begin_op(chip, page, 0, NULL, 0);
> > +
> >  	if (this->swap_block_mark) {
> >  		/*
> >  		 * If control arrives here, we're doing block mark swapping.
> > @@ -1338,7 +1344,10 @@ static int gpmi_ecc_write_page(struct mtd_info
> > *mtd, struct nand_chip *chip,
> >  				payload_virt, payload_phys);
> >  	}
> >  
> > -	return 0;
> > +	if (ret)
> > +		return ret;
> > +
> > +	return nand_prog_page_end_op(chip);
> >  }
> >  
> >  /*
> > @@ -1472,8 +1481,8 @@ static int gpmi_ecc_read_page_raw(struct mtd_info *mtd,
> >  	uint8_t *oob = chip->oob_poi;
> >  	int step;
> >  
> > -	chip->read_buf(mtd, tmp_buf,
> > -		       mtd->writesize + mtd->oobsize);
> > +	nand_read_page_op(chip, page, 0, tmp_buf,
> > +			  mtd->writesize + mtd->oobsize);
> >  
> >  	/*
> >  	 * If required, swap the bad block marker and the data stored in the
> > @@ -1617,24 +1626,19 @@ static int gpmi_ecc_write_page_raw(struct mtd_info *mtd,
> >  		tmp_buf[mtd->writesize] = swap;
> >  	}
> >  
> > -	chip->write_buf(mtd, tmp_buf, mtd->writesize + mtd->oobsize);
> > -
> > -	return 0;
> > +	return nand_prog_page_op(chip, page, 0, tmp_buf,
> > +				 mtd->writesize + mtd->oobsize);
> >  }
> >  
> >  static int gpmi_ecc_read_oob_raw(struct mtd_info *mtd, struct nand_chip *chip,
> >  				 int page)
> >  {
> > -	nand_read_page_op(chip, page, 0, NULL, 0);
> > -
> >  	return gpmi_ecc_read_page_raw(mtd, chip, NULL, 1, page);
> >  }
> >  
> >  static int gpmi_ecc_write_oob_raw(struct mtd_info *mtd, struct nand_chip *chip,
> >  				 int page)
> >  {
> > -	nand_prog_page_begin_op(chip, page, 0, NULL, 0);
> > -
> >  	return gpmi_ecc_write_page_raw(mtd, chip, NULL, 1, page);
> >  }
> >  
> > @@ -1806,9 +1810,7 @@ static int mx23_write_transcription_stamp(struct
> > gpmi_nand_data *this)
> >  		/* Write the first page of the current stride. */
> >  		dev_dbg(dev, "Writing an NCB fingerprint in page 0x%x\n", page);
> >  
> > -		nand_prog_page_begin_op(chip, page, 0, NULL, 0);
> > -		chip->ecc.write_page_raw(mtd, chip, buffer, 0, page);
> > -		status = nand_prog_page_end_op(chip);
> > +		status = chip->ecc.write_page_raw(mtd, chip, buffer, 0, page);
> >  		if (status)
> >  			dev_err(dev, "[%s] Write failed.\n", __func__);
> >  	}  
> 
> <snip>
> 
> > diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c
> > index 8037d4b48a05..80d31a58e558 100644
> > --- a/drivers/mtd/nand/vf610_nfc.c
> > +++ b/drivers/mtd/nand/vf610_nfc.c
> > @@ -560,7 +560,7 @@ static int vf610_nfc_read_page(struct mtd_info
> > *mtd, struct nand_chip *chip,
> >  	int eccsize = chip->ecc.size;
> >  	int stat;
> >  
> > -	vf610_nfc_read_buf(mtd, buf, eccsize);
> > +	nand_read_page_op(chip, page, 0, buf, eccsize);
> >  	if (oob_required)
> >  		vf610_nfc_read_buf(mtd, chip->oob_poi, mtd->oobsize);
> >  
> > @@ -580,7 +580,7 @@ static int vf610_nfc_write_page(struct mtd_info
> > *mtd, struct nand_chip *chip,
> >  {
> >  	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
> >  
> > -	vf610_nfc_write_buf(mtd, buf, mtd->writesize);  
> 
> We currently ignore NAND_CMD_SEQIN in ->cmdfunc anyway, so I think this
> change would not even be necessary here.

Well, the thing is, we're trying to keep the logic unchanged. Even if
for your driver ->cmdfunc(NAND_CMD_SEQIN) is a NOP, I'd prefer to be
consistent and still replace this ->write_buf() call by a
nand_prog_page_begin_op() one.

> 
> This is a NAND controller which will benefit from the new interface. I
> plan to convert the driver to the new interface, maybe I manage to do
> that soon so we have a second driver making use of the new interface.

Great!!! Let us know if you need any help.

Regards,

Boris

  reply	other threads:[~2017-10-20 11:18 UTC|newest]

Thread overview: 75+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-10-18 14:36 [RFC 00/12] Marvell NAND controller rework with ->exec_op() Miquel Raynal
2017-10-18 14:36 ` Miquel Raynal
2017-10-18 14:36 ` Miquel Raynal
2017-10-18 14:36 ` [RFC 01/12] mtd: nand: provide several helpers to do common NAND operations Miquel Raynal
2017-10-18 14:36   ` Miquel Raynal
2017-10-18 14:36   ` Miquel Raynal
2017-10-18 14:36 ` [RFC 02/12] mtd: nand: force drivers to explicitly send READ/PROG commands Miquel Raynal
2017-10-18 14:36   ` Miquel Raynal
2017-10-18 14:36   ` Miquel Raynal
2017-10-20  9:29   ` Stefan Agner
2017-10-20  9:29     ` Stefan Agner
2017-10-20  9:29     ` Stefan Agner
2017-10-20 11:18     ` Boris Brezillon [this message]
2017-10-20 11:18       ` Boris Brezillon
2017-10-20 11:18       ` Boris Brezillon
2017-11-06 15:02     ` Miquel RAYNAL
2017-10-18 14:36 ` [RFC 03/12] mtd: nand: use a static data_interface in the nand_chip structure Miquel Raynal
2017-10-18 14:36   ` Miquel Raynal
2017-10-18 14:36   ` Miquel Raynal
2017-10-18 17:02   ` Boris Brezillon
2017-10-18 17:02     ` Boris Brezillon
2017-10-18 17:02     ` Boris Brezillon
2017-11-03 13:46     ` Miquel RAYNAL
2017-10-18 14:36 ` [RFC 04/12] mtd: nand: add ->exec_op() implementation Miquel Raynal
2017-10-18 14:36   ` Miquel Raynal
2017-10-18 14:36   ` Miquel Raynal
2017-10-18 21:57   ` Boris Brezillon
2017-10-18 21:57     ` Boris Brezillon
2017-10-18 21:57     ` Boris Brezillon
2017-11-06 14:09     ` Miquel RAYNAL
2017-10-18 14:36 ` [RFC 05/12] dt-bindings: mtd: add Marvell NAND controller documentation Miquel Raynal
2017-10-18 14:36   ` Miquel Raynal
2017-10-18 14:36   ` Miquel Raynal
2017-10-18 22:01   ` Boris Brezillon
2017-10-18 22:01     ` Boris Brezillon
2017-10-18 22:01     ` Boris Brezillon
2017-10-24 19:04   ` Rob Herring
2017-10-24 19:04     ` Rob Herring
2017-10-24 19:04     ` Rob Herring
2017-11-06 13:24     ` Miquel RAYNAL
2017-11-06 13:24       ` Miquel RAYNAL
2017-11-06 13:24       ` Miquel RAYNAL
2017-10-18 14:36 ` [RFC 06/12] mtd: nand: add reworked Marvell NAND controller driver Miquel Raynal
2017-10-18 14:36   ` Miquel Raynal
2017-10-18 14:36   ` Miquel Raynal
2017-10-19  7:18   ` Boris Brezillon
2017-10-19  7:18     ` Boris Brezillon
2017-10-19  7:18     ` Boris Brezillon
2017-11-06 13:49     ` Miquel RAYNAL
2017-10-18 14:36 ` [RFC 07/12] ARM: dts: armada-370-xp: use reworked " Miquel Raynal
2017-10-18 14:36   ` Miquel Raynal
2017-10-18 14:36   ` Miquel Raynal
2017-10-18 14:36 ` [RFC 08/12] ARM: dts: armada-375: " Miquel Raynal
2017-10-18 14:36   ` Miquel Raynal
2017-10-18 14:36   ` Miquel Raynal
2017-10-18 14:36 ` [RFC 09/12] ARM: dts: armada-38x: " Miquel Raynal
2017-10-18 14:36   ` Miquel Raynal
2017-10-18 14:36   ` Miquel Raynal
2017-10-18 14:36 ` [RFC 10/12] ARM: dts: armada-39x: " Miquel Raynal
2017-10-18 14:36   ` Miquel Raynal
2017-10-18 14:36   ` Miquel Raynal
2017-10-18 14:36 ` [RFC 11/12] ARM: dts: pxa: " Miquel Raynal
2017-10-18 14:36   ` Miquel Raynal
2017-10-18 14:36   ` Miquel Raynal
2017-10-18 14:36 ` [RFC 12/12] ARM64: dts: marvell: use reworked NAND controller driver on Armada 7K/8K Miquel Raynal
2017-10-18 14:36 ` Miquel Raynal
2017-10-18 14:36   ` Miquel Raynal
2017-10-18 14:36   ` Miquel Raynal
2017-10-18 14:36 ` Miquel Raynal
     [not found] ` <20171018143629.29302-1-miquel.raynal-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
2017-10-18 14:36   ` Miquel Raynal
2017-10-18 22:29 ` [RFC 00/12] Marvell NAND controller rework with ->exec_op() Boris Brezillon
2017-10-18 22:29   ` Boris Brezillon
2017-10-18 22:29   ` Boris Brezillon
2017-10-19  8:47   ` Marc Gonzalez
2017-10-19 11:30     ` 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=20171020131834.704e2adc@bbrezillon \
    --to=boris.brezillon@free-electrons.com \
    --cc=andrew@lunn.ch \
    --cc=bcm-kernel-feedback-list@broadcom.com \
    --cc=catalin.marinas@arm.com \
    --cc=devel@driverdev.osuosl.org \
    --cc=devicetree@vger.ker \
    --cc=ezequiel.garcia@free-electrons.com \
    --cc=hannah@marvell.com \
    --cc=kdasu.kdev@gmail.com \
    --cc=linux-mtd@lists.infradead.org \
    --cc=linux@armlinux.org.uk \
    --cc=marc_gonzalez@sigmadesigns.com \
    --cc=marek.vasut@gmail.com \
    --cc=mark.rutland@arm.com \
    --cc=matthias.bgg@gmail.com \
    --cc=maximlevitsky@gmail.com \
    --cc=nadavh@marvell.com \
    --cc=rainyfeeling@outlook.com \
    --cc=robert.jarzmik@free.fr \
    --cc=sebastian.hesselbarth@gmail.com \
    --cc=slemieux.tyco@gmail.com \
    --cc=stefan@agner.ch \
    --cc=wens@csie.org \
    --cc=will.deacon@arm.com \
    --cc=yamada.masahiro@socionext.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.