All of lore.kernel.org
 help / color / mirror / Atom feed
From: Miquel Raynal <miquel.raynal@bootlin.com>
To: Richard Weinberger <richard@nod.at>,
	Vignesh Raghavendra <vigneshr@ti.com>,
	Tudor Ambarus <Tudor.Ambarus@microchip.com>,
	<linux-mtd@lists.infradead.org>
Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com>,
	Michal Simek <monstr@monstr.eu>,
	Naga Sureshkumar Relli <nagasure@xilinx.com>,
	Amit Kumar Mahapatra <akumarma@xilinx.com>,
	Miquel Raynal <miquel.raynal@bootlin.com>
Subject: [PATCH 18/22] mtd: rawnand: Choose the best timings, NV-DDR included
Date: Wed,  5 May 2021 23:37:46 +0200	[thread overview]
Message-ID: <20210505213750.257417-19-miquel.raynal@bootlin.com> (raw)
In-Reply-To: <20210505213750.257417-1-miquel.raynal@bootlin.com>

Now that the necessary peaces to support the NV-DDR interface type have
been contributed, let's add the relevant logic to make use of it. In
particular, the core does not choose the best SDR timings anymore but
calls a more generic helper instead.

This helper checks if NV-DDR is supported by trying to find the best
NV-DDR supported mode through a logic very close to what is being done
for SDR timings. If no NV-DDR mode in common between the NAND controller
and the NAND chip is found, the core will fallback to SDR.

Side note: theoretically, the data clock speed in NV-DDR mode 0 is
slower than in SDR mode 5. In the situation where we would get a working
NV-DDR mode 0, we could also try if SDR mode 5 is supported and
eventually fallback to it in order to get the fastest possible
throughput. However, in the field, it looks like most of the devices
supporting NV-DDR avoid implementing the fastest SDR modes (like 4 and 5
EDO modes, which are a bit more complicated to handle than the other SDR
modes). So, we will stick to the simplest logic: try NV-DDR otherwise
fallback to SDR. If someone else experiences strong differences because
of that we may still implement the logic defined above.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/mtd/nand/raw/internals.h |  3 ++
 drivers/mtd/nand/raw/nand_base.c | 76 +++++++++++++++++++++++++++++++-
 2 files changed, 78 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/raw/internals.h b/drivers/mtd/nand/raw/internals.h
index c06bc2f1aaa2..7016e0f38398 100644
--- a/drivers/mtd/nand/raw/internals.h
+++ b/drivers/mtd/nand/raw/internals.h
@@ -95,6 +95,9 @@ onfi_find_closest_nvddr_mode(const struct nand_nvddr_timings *spec_timings);
 int nand_choose_best_sdr_timings(struct nand_chip *chip,
 				 struct nand_interface_config *iface,
 				 struct nand_sdr_timings *spec_timings);
+int nand_choose_best_nvddr_timings(struct nand_chip *chip,
+				   struct nand_interface_config *iface,
+				   struct nand_nvddr_timings *spec_timings);
 const struct nand_interface_config *nand_get_reset_interface_config(void);
 int nand_get_features(struct nand_chip *chip, int addr, u8 *subfeature_param);
 int nand_set_features(struct nand_chip *chip, int addr, u8 *subfeature_param);
diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index e20551cb3ce5..22974a53077f 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -961,6 +961,80 @@ int nand_choose_best_sdr_timings(struct nand_chip *chip,
 	return ret;
 }
 
+/**
+ * nand_choose_best_nvddr_timings - Pick up the best NVDDR timings that both the
+ *                                  NAND controller and the NAND chip support
+ * @chip: the NAND chip
+ * @iface: the interface configuration (can eventually be updated)
+ * @spec_timings: specific timings, when not fitting the ONFI specification
+ *
+ * If specific timings are provided, use them. Otherwise, retrieve supported
+ * timing modes from ONFI information.
+ */
+int nand_choose_best_nvddr_timings(struct nand_chip *chip,
+				   struct nand_interface_config *iface,
+				   struct nand_nvddr_timings *spec_timings)
+{
+	const struct nand_controller_ops *ops = chip->controller->ops;
+	int best_mode = 0, mode, ret;
+
+	iface->type = NAND_NVDDR_IFACE;
+
+	if (spec_timings) {
+		iface->timings.nvddr = *spec_timings;
+		iface->timings.mode = onfi_find_closest_nvddr_mode(spec_timings);
+
+		/* Verify the controller supports the requested interface */
+		ret = ops->setup_interface(chip, NAND_DATA_IFACE_CHECK_ONLY,
+					   iface);
+		if (!ret) {
+			chip->best_interface_config = iface;
+			return ret;
+		}
+
+		/* Fallback to slower modes */
+		best_mode = iface->timings.mode;
+	} else if (chip->parameters.onfi) {
+		best_mode = fls(chip->parameters.onfi->nvddr_timing_modes) - 1;
+	}
+
+	for (mode = best_mode; mode >= 0; mode--) {
+		onfi_fill_interface_config(chip, iface, NAND_NVDDR_IFACE, mode);
+
+		ret = ops->setup_interface(chip, NAND_DATA_IFACE_CHECK_ONLY,
+					   iface);
+		if (!ret) {
+			chip->best_interface_config = iface;
+			break;
+		}
+	}
+
+	return ret;
+}
+
+/**
+ * nand_choose_best_timings - Pick up the best NVDDR or SDR timings that both
+ *                            NAND controller and the NAND chip support
+ * @chip: the NAND chip
+ * @iface: the interface configuration (can eventually be updated)
+ *
+ * If specific timings are provided, use them. Otherwise, retrieve supported
+ * timing modes from ONFI information.
+ */
+static int nand_choose_best_timings(struct nand_chip *chip,
+				    struct nand_interface_config *iface)
+{
+	int ret;
+
+	/* Try the fastest timings: NV-DDR */
+	ret = nand_choose_best_nvddr_timings(chip, iface, NULL);
+	if (!ret)
+		return 0;
+
+	/* Fallback to SDR timings otherwise */
+	return nand_choose_best_sdr_timings(chip, iface, NULL);
+}
+
 /**
  * nand_choose_interface_config - find the best data interface and timings
  * @chip: The NAND chip
@@ -989,7 +1063,7 @@ static int nand_choose_interface_config(struct nand_chip *chip)
 	if (chip->ops.choose_interface_config)
 		ret = chip->ops.choose_interface_config(chip, iface);
 	else
-		ret = nand_choose_best_sdr_timings(chip, iface, NULL);
+		ret = nand_choose_best_timings(chip, iface);
 
 	if (ret)
 		kfree(iface);
-- 
2.27.0


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

  parent reply	other threads:[~2021-05-05 22:12 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-05 21:37 [PATCH 00/22] mtd: rawnand: NV-DDR support Miquel Raynal
2021-05-05 21:37 ` [PATCH 01/22] mtd: rawnand: Add a helper to clarify the interface configuration Miquel Raynal
2021-05-26  9:05   ` Miquel Raynal
2021-05-05 21:37 ` [PATCH 02/22] mtd: rawnand: arasan: Check the proposed data interface is supported Miquel Raynal
2021-05-26  9:05   ` Miquel Raynal
2021-05-05 21:37 ` [PATCH 03/22] mtd: rawnand: atmel: " Miquel Raynal
2021-05-26  9:05   ` Miquel Raynal
2021-05-05 21:37 ` [PATCH 04/22] mtd: rawnand: onfi: Use the BIT() macro when possible Miquel Raynal
2021-05-26  9:05   ` Miquel Raynal
2021-05-05 21:37 ` [PATCH 05/22] mtd: rawnand: Update dead URL Miquel Raynal
2021-05-26  9:05   ` Miquel Raynal
2021-05-05 21:37 ` [PATCH 06/22] mtd: rawnand: Use more recent ONFI specification wording Miquel Raynal
2021-05-26  9:05   ` Miquel Raynal
2021-05-05 21:37 ` [PATCH 07/22] mtd: rawnand: Clarify the NV-DDR entries in the ONFI structure Miquel Raynal
2021-05-26  9:04   ` Miquel Raynal
2021-05-05 21:37 ` [PATCH 08/22] mtd: rawnand: Add NV-DDR timings Miquel Raynal
2021-05-26  9:04   ` Miquel Raynal
2021-05-05 21:37 ` [PATCH 09/22] mtd: rawnand: Retrieve NV-DDR timing modes from the ONFI parameter page Miquel Raynal
2021-05-26  9:04   ` Miquel Raynal
2021-05-05 21:37 ` [PATCH 10/22] mtd: rawnand: Add an indirection on onfi_fill_interface_config() Miquel Raynal
2021-05-26  9:04   ` Miquel Raynal
2021-05-05 21:37 ` [PATCH 11/22] mtd: rawnand: Add onfi_fill_nvddr_interface_config() helper Miquel Raynal
2021-05-26  9:04   ` Miquel Raynal
2021-05-05 21:37 ` [PATCH 12/22] mtd: rawnand: Avoid accessing NV-DDR timings from legacy code Miquel Raynal
2021-05-26  9:04   ` Miquel Raynal
2021-05-05 21:37 ` [PATCH 13/22] mtd: rawnand: Access SDR and NV-DDR timings through a common macro Miquel Raynal
2021-05-26  9:04   ` Miquel Raynal
2021-05-05 21:37 ` [PATCH 14/22] mtd: rawnand: Handle the double bytes in NV-DDR mode Miquel Raynal
2021-05-26  9:04   ` Miquel Raynal
2021-05-05 21:37 ` [PATCH 15/22] mtd: rawnand: Add a helper to find the closest ONFI " Miquel Raynal
2021-05-26  9:04   ` Miquel Raynal
2021-05-05 21:37 ` [PATCH 16/22] mtd: rawnand: Support enabling NV-DDR through SET_FEATURES Miquel Raynal
2021-05-05 21:37 ` [PATCH 17/22] mtd: rawnand: Allow SDR timings to be nacked Miquel Raynal
2021-05-26  9:04   ` Miquel Raynal
2021-05-05 21:37 ` Miquel Raynal [this message]
2021-05-26  9:04   ` [PATCH 18/22] mtd: rawnand: Choose the best timings, NV-DDR included Miquel Raynal
2021-05-05 21:37 ` [PATCH 19/22] MAINTAINERS: Add myself as co-maintainer of the Arasan NAND controller driver Miquel Raynal
2021-05-26  9:04   ` Miquel Raynal
2021-05-05 21:37 ` [PATCH 20/22] mtd: rawnand: arasan: Fix a macro parameter Miquel Raynal
2021-05-26  9:03   ` Miquel Raynal
2021-05-05 21:37 ` [PATCH 21/22] mtd: rawnand: arasan: Workaround a misbehaving prog type with NV-DDR Miquel Raynal
2021-05-26  9:03   ` Miquel Raynal
2021-05-05 21:37 ` [PATCH 22/22] mtd: rawnand: arasan: Support NV-DDR interface Miquel Raynal
2021-05-26  9:03   ` Miquel Raynal

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=20210505213750.257417-19-miquel.raynal@bootlin.com \
    --to=miquel.raynal@bootlin.com \
    --cc=Tudor.Ambarus@microchip.com \
    --cc=akumarma@xilinx.com \
    --cc=linux-mtd@lists.infradead.org \
    --cc=monstr@monstr.eu \
    --cc=nagasure@xilinx.com \
    --cc=richard@nod.at \
    --cc=thomas.petazzoni@bootlin.com \
    --cc=vigneshr@ti.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.