All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dario Binacchi <dario.binacchi@amarulasolutions.com>
To: u-boot@lists.denx.de
Cc: Amarula patchwork <linux-amarula@amarulasolutions.com>,
	michael@amarulasolutions.com,
	Dario Binacchi <dario.binacchi@amarulasolutions.com>,
	Patrice Chotard <patrice.chotard@foss.st.com>,
	Simon Glass <sjg@chromium.org>, Wolfgang Denk <wd@denx.de>
Subject: [PATCH v4 03/14] mtd: nand: Add manufacturer specific initialization/detection steps
Date: Fri, 22 Jul 2022 18:09:57 +0200	[thread overview]
Message-ID: <20220722161009.2686504-4-dario.binacchi@amarulasolutions.com> (raw)
In-Reply-To: <20220722161009.2686504-1-dario.binacchi@amarulasolutions.com>

From: Michael Trimarchi <michael@amarulasolutions.com>

Upstream linux commit abbe26d144ec22.

A lot of NANDs are implementing generic features in a non-generic way,
or are providing advanced auto-detection logic where the NAND ID bytes
meaning changes with the NAND generation.

Providing this vendor specific initialization step will allow us to get
rid of full-id entries in the nand_ids table or all the vendor specific
cases added over the time in the generic NAND ID decoding logic.

Signed-off-by: Michael Trimarchi <michael@amarulasolutions.com>
Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
---

(no changes since v3)

Changes in v3:
- Use commit sha1 with 13 digits.
- Fix code style warnings raised by patman.

Changes in v2:
- Use short-commit form.
- Remove linux info. Uboot seems that backport without add this
  extra information.

 drivers/mtd/nand/raw/nand_base.c | 98 ++++++++++++++++++++++++--------
 include/linux/mtd/rawnand.h      | 30 ++++++++++
 2 files changed, 105 insertions(+), 23 deletions(-)

diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index 220804c75c87..0900e6dbf9a6 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -4286,6 +4286,39 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip)
 	}
 }
 
+/*
+ * Manufacturer detection. Only used when the NAND is not ONFI or JEDEC
+ * compliant and does not have a full-id or legacy-id entry in the nand_ids
+ * table.
+ */
+static void nand_manufacturer_detect(struct mtd_info *mtd, struct nand_chip *chip)
+{
+	/*
+	 * Try manufacturer detection if available and use
+	 * nand_decode_ext_id() otherwise.
+	 */
+	if (chip->manufacturer.desc && chip->manufacturer.desc->ops &&
+	    chip->manufacturer.desc->ops->detect)
+		chip->manufacturer.desc->ops->detect(chip);
+	else
+		nand_decode_ext_id(mtd, chip);
+}
+
+/*
+ * Manufacturer initialization. This function is called for all NANDs including
+ * ONFI and JEDEC compliant ones.
+ * Manufacturer drivers should put all their specific initialization code in
+ * their ->init() hook.
+ */
+static int nand_manufacturer_init(struct nand_chip *chip)
+{
+	if (!chip->manufacturer.desc || !chip->manufacturer.desc->ops ||
+	    !chip->manufacturer.desc->ops->init)
+		return 0;
+
+	return chip->manufacturer.desc->ops->init(chip);
+}
+
 /*
  * Old devices have chip data hardcoded in the device ID table. nand_decode_id
  * decodes a matching ID table entry and assigns the MTD size parameters for
@@ -4383,6 +4416,26 @@ static bool find_full_id_nand(struct mtd_info *mtd, struct nand_chip *chip,
 	return false;
 }
 
+/**
+ * nand_get_manufacturer_desc - Get manufacturer information from the
+ *                              manufacturer ID
+ * @id: manufacturer ID
+ *
+ * Returns a nand_manufacturer_desc object if the manufacturer is defined
+ * in the NAND manufacturers database, NULL otherwise.
+ */
+static const struct nand_manufacturers *nand_get_manufacturer_desc(u8 id)
+{
+	int i;
+
+	for (i = 0; nand_manuf_ids[i].id != 0x0; i++) {
+		if (nand_manuf_ids[i].id == id)
+			return &nand_manuf_ids[i];
+	}
+
+	return NULL;
+}
+
 /*
  * Get the flash and manufacturer id and lookup if the type is supported.
  */
@@ -4391,8 +4444,8 @@ struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
 						  int *maf_id, int *dev_id,
 						  struct nand_flash_dev *type)
 {
+	const struct nand_manufacturers *manufacturer_desc;
 	int busw, ret;
-	int maf_idx;
 	u8 *id_data = chip->id.data;
 
 	/*
@@ -4433,6 +4486,12 @@ struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
 		return ERR_PTR(-ENODEV);
 	}
 
+	chip->id.len = nand_id_len(id_data, ARRAY_SIZE(chip->id.data));
+
+	/* Try to identify manufacturer */
+	manufacturer_desc = nand_get_manufacturer_desc(*maf_id);
+	chip->manufacturer.desc = manufacturer_desc;
+
 	if (!type)
 		type = nand_flash_ids;
 
@@ -4451,8 +4510,6 @@ struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
 	 */
 	chip->options &= ~NAND_BUSWIDTH_16;
 
-	chip->id.len = nand_id_len(id_data, ARRAY_SIZE(chip->id.data));
-
 	for (; type->name != NULL; type++) {
 		if (is_full_id_nand(type)) {
 			if (find_full_id_nand(mtd, chip, type))
@@ -4482,8 +4539,7 @@ struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
 	chip->chipsize = (uint64_t)type->chipsize << 20;
 
 	if (!type->pagesize) {
-		/* Decode parameters from extended ID */
-		nand_decode_ext_id(mtd, chip);
+		nand_manufacturer_detect(mtd, chip);
 	} else {
 		nand_decode_id(mtd, chip, type);
 	}
@@ -4499,12 +4555,6 @@ struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
 		chip->options &= ~NAND_SAMSUNG_LP_OPTIONS;
 ident_done:
 
-	/* Try to identify manufacturer */
-	for (maf_idx = 0; nand_manuf_ids[maf_idx].id != 0x0; maf_idx++) {
-		if (nand_manuf_ids[maf_idx].id == *maf_id)
-			break;
-	}
-
 	if (chip->options & NAND_BUSWIDTH_AUTO) {
 		WARN_ON(chip->options & NAND_BUSWIDTH_16);
 		chip->options |= busw;
@@ -4516,7 +4566,7 @@ ident_done:
 		 */
 		pr_info("device found, Manufacturer ID: 0x%02x, Chip ID: 0x%02x\n",
 			*maf_id, *dev_id);
-		pr_info("%s %s\n", nand_manuf_ids[maf_idx].name, mtd->name);
+		pr_info("%s %s\n", manufacturer_desc->name, mtd->name);
 		pr_warn("bus width %d instead %d bit\n",
 			   (chip->options & NAND_BUSWIDTH_16) ? 16 : 8,
 			   busw ? 16 : 8);
@@ -4549,28 +4599,30 @@ ident_done:
 	if (mtd->writesize > 512 && chip->cmdfunc == nand_command)
 		chip->cmdfunc = nand_command_lp;
 
+	ret = nand_manufacturer_init(chip);
+	if (ret)
+		return ERR_PTR(ret);
+
 	pr_info("device found, Manufacturer ID: 0x%02x, Chip ID: 0x%02x\n",
 		*maf_id, *dev_id);
 
 #ifdef CONFIG_SYS_NAND_ONFI_DETECTION
 	if (chip->onfi_version)
-		pr_info("%s %s\n", nand_manuf_ids[maf_idx].name,
-				chip->onfi_params.model);
+		pr_info("%s %s\n", manufacturer_desc->name,
+			chip->onfi_params.model);
 	else if (chip->jedec_version)
-		pr_info("%s %s\n", nand_manuf_ids[maf_idx].name,
-				chip->jedec_params.model);
+		pr_info("%s %s\n", manufacturer_desc->name,
+			chip->jedec_params.model);
 	else
-		pr_info("%s %s\n", nand_manuf_ids[maf_idx].name,
-				type->name);
+		pr_info("%s %s\n", manufacturer_desc->name, type->name);
 #else
 	if (chip->jedec_version)
-		pr_info("%s %s\n", nand_manuf_ids[maf_idx].name,
-				chip->jedec_params.model);
+		pr_info("%s %s\n", manufacturer_desc->name,
+			chip->jedec_params.model);
 	else
-		pr_info("%s %s\n", nand_manuf_ids[maf_idx].name,
-				type->name);
+		pr_info("%s %s\n", manufacturer_desc->name, type->name);
 
-	pr_info("%s %s\n", nand_manuf_ids[maf_idx].name,
+	pr_info("%s %s\n", manufacturer_desc->name,
 		type->name);
 #endif
 
diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
index f2c6a978cbf8..57fe7fb47bd8 100644
--- a/include/linux/mtd/rawnand.h
+++ b/include/linux/mtd/rawnand.h
@@ -796,6 +796,17 @@ nand_get_sdr_timings(const struct nand_data_interface *conf)
 	return &conf->timings.sdr;
 }
 
+/**
+ * struct nand_manufacturer_ops - NAND Manufacturer operations
+ * @detect: detect the NAND memory organization and capabilities
+ * @init: initialize all vendor specific fields (like the ->read_retry()
+ *	  implementation) if any.
+ */
+struct nand_manufacturer_ops {
+	void (*detect)(struct nand_chip *chip);
+	int (*init)(struct nand_chip *chip);
+};
+
 /**
  * struct nand_chip - NAND Private Flash Chip Data
  * @mtd:		MTD device registered to the MTD framework
@@ -897,6 +908,7 @@ nand_get_sdr_timings(const struct nand_data_interface *conf)
  *			devices.
  * @priv:		[OPTIONAL] pointer to private chip data
  * @write_page:		[REPLACEABLE] High-level page write function
+ * @manufacturer:	[INTERN] Contains manufacturer information
  */
 
 struct nand_chip {
@@ -983,6 +995,11 @@ struct nand_chip {
 	struct nand_bbt_descr *badblock_pattern;
 
 	void *priv;
+
+	struct {
+		const struct nand_manufacturers *desc;
+		void *priv;
+	} manufacturer;
 };
 
 static inline void nand_set_flash_node(struct nand_chip *chip,
@@ -1016,6 +1033,17 @@ static inline void nand_set_controller_data(struct nand_chip *chip, void *priv)
 	chip->priv = priv;
 }
 
+static inline void nand_set_manufacturer_data(struct nand_chip *chip,
+					      void *priv)
+{
+	chip->manufacturer.priv = priv;
+}
+
+static inline void *nand_get_manufacturer_data(struct nand_chip *chip)
+{
+	return chip->manufacturer.priv;
+}
+
 /*
  * NAND Flash Manufacturer ID Codes
  */
@@ -1120,10 +1148,12 @@ struct nand_flash_dev {
  * struct nand_manufacturers - NAND Flash Manufacturer ID Structure
  * @name:	Manufacturer name
  * @id:		manufacturer ID code of device.
+ * @ops:	manufacturer operations
 */
 struct nand_manufacturers {
 	int id;
 	char *name;
+	const struct nand_manufacturer_ops *ops;
 };
 
 extern struct nand_flash_dev nand_flash_ids[];
-- 
2.32.0


  parent reply	other threads:[~2022-07-22 16:11 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-22 16:09 [PATCH v4 00/14] Port manufacturer specific initialization Dario Binacchi
2022-07-22 16:09 ` [PATCH v4 01/14] mtd: nand: Get rid of busw parameter Dario Binacchi
2022-07-22 16:09 ` [PATCH v4 02/14] mtd: nand: Store nand ID in struct nand_chip Dario Binacchi
2022-07-22 16:09 ` Dario Binacchi [this message]
2022-07-22 16:09 ` [PATCH v4 04/14] mtd: nand: Get rid of mtd variable in function calls Dario Binacchi
2022-07-22 16:09 ` [PATCH v4 05/14] mtd: nand: Fix MediaTek MT7621 SoC build Dario Binacchi
2022-07-26  0:53   ` Weijie Gao
2022-07-22 16:10 ` [PATCH v4 06/14] mtd: nand: Export symbol nand_decode_ext_id Dario Binacchi
2022-07-22 16:10 ` [PATCH v4 07/14] mtd: nand: Move Samsung specific init/detection logic in nand_samsung.c Dario Binacchi
2022-07-22 16:10 ` [PATCH v4 08/14] mtd: nand: Move Hynix specific init/detection logic in nand_hynix.c Dario Binacchi
2022-07-22 16:10 ` [PATCH v4 09/14] mtd: nand: Move Toshiba specific init/detection logic in nand_toshiba.c Dario Binacchi
2022-07-22 16:10 ` [PATCH v4 10/14] mtd: nand: Move Micron specific init logic in nand_micron.c Dario Binacchi
2022-07-22 16:10 ` [PATCH v4 11/14] mtd: nand: Move AMD/Spansion specific init/detection logic in nand_amd.c Dario Binacchi
2022-07-22 16:10 ` [PATCH v4 12/14] mtd: nand: Move Macronix specific initialization in nand_macronix.c Dario Binacchi
2022-07-22 16:10 ` [PATCH v4 13/14] mtd: nand: toshiba: Retrieve ECC requirements from extended ID Dario Binacchi
2022-07-22 16:10 ` [PATCH v4 14/14] mtd: decommission the NAND museum Dario Binacchi
2022-07-22 17:22 ` [PATCH v4 00/14] Port manufacturer specific initialization Michael Nazzareno Trimarchi

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=20220722161009.2686504-4-dario.binacchi@amarulasolutions.com \
    --to=dario.binacchi@amarulasolutions.com \
    --cc=linux-amarula@amarulasolutions.com \
    --cc=michael@amarulasolutions.com \
    --cc=patrice.chotard@foss.st.com \
    --cc=sjg@chromium.org \
    --cc=u-boot@lists.denx.de \
    --cc=wd@denx.de \
    /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.