All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sam Lefebvre <sam.lefebvre@essensium.com>
To: linux-mtd@lists.infradead.org
Cc: Han Xu <han.xu@nxp.com>,
	Sam Lefebvre <sam.lefebvre@essensium.com>,
	Arnout Vandecappelle <arnout@mind.be>
Subject: [PATCH 18/18] mtd: rawnand: gpmi: issue two commands in a single DMA chain
Date: Fri, 20 Apr 2018 10:19:46 +0200	[thread overview]
Message-ID: <20180420081946.16088-19-sam.lefebvre@essensium.com> (raw)
In-Reply-To: <20180420081946.16088-1-sam.lefebvre@essensium.com>

gpmi_nand_command() may issue two commands. Instead of issuing them as
separate DMAs, chain them together and issue only a single DMA.

This removes one DMA interrupt and associated overhead. For full-page
reads with ECC, it reduces the number of interrupts from 4 per page to
3 per page (2 DMA interrupts + 1 BCH interrupt).

Signed-off-by: Sam Lefebvre <sam.lefebvre@essensium.com>
Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
---
 drivers/mtd/nand/raw/gpmi-nand/gpmi-lib.c  | 12 +++++++-----
 drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c |  8 +++++---
 drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.h |  2 +-
 3 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-lib.c
index 46b2208df30e..8f5a2a242228 100644
--- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-lib.c
+++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-lib.c
@@ -549,12 +549,12 @@ int gpmi_is_ready(struct gpmi_nand_data *this, unsigned chip)
 }
 
 int gpmi_send_command(struct gpmi_nand_data *this, struct scatterlist *sgl,
-		      unsigned int command_length)
+		      unsigned int command_length, bool chain, bool start_dma)
 {
 	struct dma_chan *channel = get_dma_chan(this);
 	struct dma_async_tx_descriptor *desc;
 	int chip = this->current_chip;
-	int ret;
+	int ret = 0;
 	u32 pio[3];
 
 	/* [1] send out the PIO words */
@@ -568,7 +568,8 @@ int gpmi_send_command(struct gpmi_nand_data *this, struct scatterlist *sgl,
 	pio[1] = pio[2] = 0;
 	desc = dmaengine_prep_slave_sg(channel,
 					(struct scatterlist *)pio,
-					ARRAY_SIZE(pio), DMA_TRANS_NONE, 0);
+					ARRAY_SIZE(pio), DMA_TRANS_NONE,
+					chain ? DMA_PREP_INTERRUPT : 0);
 	if (!desc)
 		return -EINVAL;
 
@@ -579,8 +580,9 @@ int gpmi_send_command(struct gpmi_nand_data *this, struct scatterlist *sgl,
 	if (!desc)
 		return -EINVAL;
 
-	/* [3] submit the DMA */
-	ret = start_dma_without_bch_irq(this, desc);
+	if (start_dma)
+		/* [3] submit the DMA */
+		ret = start_dma_without_bch_irq(this, desc);
 
 	return ret;
 }
diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
index 4455ea428255..abf227148b01 100644
--- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
@@ -1150,11 +1150,12 @@ static void gpmi_nand_command(struct mtd_info *mtd, unsigned int command,
 			break;
 		}
 
-	/* This starts the DMA for the command and waits for it to finish. */
+	/* Chain the two commands, start the DMA and wait for it to finish. */
 	if (this->command_length > 0) {
 		sg_init_one(&this->cmd_sgl, this->cmd_buffer, this->command_length);
 		dma_map_sg(this->dev, &this->cmd_sgl, 1, DMA_TO_DEVICE);
-		ret = gpmi_send_command(this, &this->cmd_sgl, this->command_length);
+		ret = gpmi_send_command(this, &this->cmd_sgl, this->command_length,
+					false, this->command_length2 == 0);
 		if (ret)
 			dev_err(this->dev, "Chip: %u, Error %d\n",
 				this->current_chip, ret);
@@ -1163,7 +1164,8 @@ static void gpmi_nand_command(struct mtd_info *mtd, unsigned int command,
 	if (this->command_length2 > 0) {
 		sg_init_one(&this->cmd_sgl2, this->cmd_buffer + 64, this->command_length2);
 		dma_map_sg(this->dev, &this->cmd_sgl2, 1, DMA_TO_DEVICE);
-		ret = gpmi_send_command(this, &this->cmd_sgl2, this->command_length2);
+		ret = gpmi_send_command(this, &this->cmd_sgl2, this->command_length2,
+					this->command_length > 0, true);
 		if (ret)
 			dev_err(this->dev, "Chip: %u, Error %d\n",
 				this->current_chip, ret);
diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.h
index 9dc3dd16fa0b..a09ec300754f 100644
--- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.h
+++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.h
@@ -189,7 +189,7 @@ void gpmi_dump_info(struct gpmi_nand_data *);
 int bch_set_geometry(struct gpmi_nand_data *);
 int gpmi_is_ready(struct gpmi_nand_data *, unsigned chip);
 int gpmi_send_command(struct gpmi_nand_data *, struct scatterlist *sgl,
-		      unsigned int command_length);
+		      unsigned int command_length, bool chain, bool start_dma);
 int gpmi_enable_clk(struct gpmi_nand_data *this);
 int gpmi_disable_clk(struct gpmi_nand_data *this);
 int gpmi_setup_data_interface(struct mtd_info *mtd, int chipnr,
-- 
2.14.1

      parent reply	other threads:[~2018-04-20  8:26 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-04-20  8:19 Reducing the number of interrupts by page reads, part 1 Sam Lefebvre
2018-04-20  8:19 ` [PATCH 01/18] mtd: nand: gpmi: drop dma_ops_type Sam Lefebvre
2018-04-20  8:19 ` [PATCH 02/18] mtd: nand: gpmi: pass buffer and len around Sam Lefebvre
2018-04-20  8:19 ` [PATCH 03/18] mtd: nand: gpmi: put only once used functions inline Sam Lefebvre
2018-04-20  8:19 ` [PATCH 04/18] mtd: nand: gpmi: remove direct_dma_map_ok from driver data struct Sam Lefebvre
2018-04-20  8:19 ` [PATCH 05/18] mtd: nand: gpmi: return valid value from bch_set_geometry() Sam Lefebvre
2018-04-20  8:19 ` [PATCH 06/18] mtd: nand: gpmi: remove unnecessary variables Sam Lefebvre
2018-04-20  8:19 ` [PATCH 07/18] mtd: rawnand: gpmi: return generated errors in gpmi_ecc_read_oob() Sam Lefebvre
2018-04-20 22:40   ` Boris Brezillon
2018-04-20  8:19 ` [PATCH 08/18] mtd: rawnand: gpmi: set aggregate ready/busy signalling Sam Lefebvre
2018-04-20  8:19 ` [PATCH 09/18] mtd: rawnand: make nand_command() and nand_command_lp() more similar Sam Lefebvre
2018-04-20  8:19 ` [PATCH 10/18] mtd: rawnand: factor nand_command_lp() into nand_command() Sam Lefebvre
2018-04-20 20:34   ` Boris Brezillon
2018-04-23  7:16     ` Arnout Vandecappelle
2018-04-20  8:19 ` [PATCH 11/18] mtd: rawnand: gpmi: instantiate cmdfunc Sam Lefebvre
2018-04-20 20:38   ` Boris Brezillon
2018-04-23  7:43     ` Arnout Vandecappelle
2018-04-23 10:05       ` Boris Brezillon
2018-04-20  8:19 ` [PATCH 12/18] mtd: rawnand: gpmi: gpmi_ccs_delay() is not needed Sam Lefebvre
2018-04-20  8:19 ` [PATCH 13/18] mtd: rawnand: gpmi: explicit delays are " Sam Lefebvre
2018-04-20  8:19 ` [PATCH 14/18] mtd: rawnand: gpmi: no explicit wait is needed after sending a command Sam Lefebvre
2018-04-20  8:19 ` [PATCH 15/18] mtd: rawnand: gpmi: cmd_ctrl is no longer needed Sam Lefebvre
2018-04-20  8:19 ` [PATCH 16/18] mtd: rawnand: gpmi: inline gpmi_cmd_ctrl() Sam Lefebvre
2018-04-20  8:19 ` [PATCH 17/18] mtd: rawnand: gpmi: gpmi_nand_command(): use separate sgl for the two commands Sam Lefebvre
2018-04-20  8:19 ` Sam Lefebvre [this message]

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=20180420081946.16088-19-sam.lefebvre@essensium.com \
    --to=sam.lefebvre@essensium.com \
    --cc=arnout@mind.be \
    --cc=han.xu@nxp.com \
    --cc=linux-mtd@lists.infradead.org \
    /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.