diff mbox series

[v2,23/27] mtd: spinand: Enhance the logic when picking a variant

Message ID 20241224-winbond-6-11-rc1-quad-support-v2-23-ad218dbc406f@bootlin.com (mailing list archive)
State New
Headers show
Series spi-nand/spi-mem DTR support | expand

Checks

Context Check Description
conchuod/vmtest-for-next-PR fail PR summary
conchuod/patch-23-test-1 success .github/scripts/patches/tests/build_rv32_defconfig.sh took 137.81s
conchuod/patch-23-test-2 success .github/scripts/patches/tests/build_rv64_clang_allmodconfig.sh took 1377.27s
conchuod/patch-23-test-3 success .github/scripts/patches/tests/build_rv64_gcc_allmodconfig.sh took 1607.08s
conchuod/patch-23-test-4 success .github/scripts/patches/tests/build_rv64_nommu_k210_defconfig.sh took 21.05s
conchuod/patch-23-test-5 success .github/scripts/patches/tests/build_rv64_nommu_virt_defconfig.sh took 23.14s
conchuod/patch-23-test-6 success .github/scripts/patches/tests/checkpatch.sh took 0.70s
conchuod/patch-23-test-7 success .github/scripts/patches/tests/dtb_warn_rv64.sh took 44.24s
conchuod/patch-23-test-8 success .github/scripts/patches/tests/header_inline.sh took 0.01s
conchuod/patch-23-test-9 success .github/scripts/patches/tests/kdoc.sh took 0.57s
conchuod/patch-23-test-10 success .github/scripts/patches/tests/module_param.sh took 0.02s
conchuod/patch-23-test-11 success .github/scripts/patches/tests/verify_fixes.sh took 0.00s
conchuod/patch-23-test-12 success .github/scripts/patches/tests/verify_signedoff.sh took 0.04s

Commit Message

Miquel Raynal Dec. 24, 2024, 5:06 p.m. UTC
Currently the best variant picked in the first one in the list provided
in the manufacturer driver. This worked well while all operations where
performed at the same speed, but with the introduction of DTR transfers
and per operation maximum frequencies, this no longer works correctly.

Let's continue iterating over all the alternatives, even if we find a
match, keeping a reference over the theoretically fastest
operation. Only at the end we can tell which variant is the best.

This logic happening only once at boot, the extra computing needed
compared to the previous version is acceptable wrt. the expected
improvements.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/mtd/nand/spi/core.c | 13 ++++++++++---
 include/linux/spi/spi-mem.h |  2 +-
 2 files changed, 11 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index 94f33c8be031ac60208e22e4e3fa0d90cfae093c..a2a8cfd1752139e3227fa4a39ab0e25bbeec53f8 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -1198,10 +1198,13 @@  spinand_select_op_variant(struct spinand_device *spinand,
 			  const struct spinand_op_variants *variants)
 {
 	struct nand_device *nand = spinand_to_nand(spinand);
+	const struct spi_mem_op *best_variant = NULL;
+	u64 best_op_duration_ns = ULLONG_MAX;
 	unsigned int i;
 
 	for (i = 0; i < variants->nops; i++) {
 		struct spi_mem_op op = variants->ops[i];
+		u64 op_duration_ns = 0;
 		unsigned int nbytes;
 		int ret;
 
@@ -1220,13 +1223,17 @@  spinand_select_op_variant(struct spinand_device *spinand,
 				break;
 
 			nbytes -= op.data.nbytes;
+
+			op_duration_ns += spi_mem_calc_op_duration(&op);
 		}
 
-		if (!nbytes)
-			return &variants->ops[i];
+		if (!nbytes && op_duration_ns < best_op_duration_ns) {
+			best_op_duration_ns = op_duration_ns;
+			best_variant = &variants->ops[i];
+		}
 	}
 
-	return NULL;
+	return best_variant;
 }
 
 /**
diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h
index 82390712794c5a4dcef1319c19d74b77b6e1e724..c4830dfaff3db5549c45bb7a9c4bf5110fa2e338 100644
--- a/include/linux/spi/spi-mem.h
+++ b/include/linux/spi/spi-mem.h
@@ -424,7 +424,7 @@  bool spi_mem_default_supports_op(struct spi_mem *mem,
 
 int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op);
 void spi_mem_adjust_op_freq(struct spi_mem *mem, struct spi_mem_op *op);
-u64 spi_mem_calc_op_duration(struct spi_mem *mem, struct spi_mem_op *op);
+u64 spi_mem_calc_op_duration(struct spi_mem_op *op);
 
 bool spi_mem_supports_op(struct spi_mem *mem,
 			 const struct spi_mem_op *op);