Skip to content

Commit

Permalink
mtd: spinand: Enhance the logic when picking a variant
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Miquel Raynal committed Jan 15, 2025
1 parent 7ce0d16 commit 666c299
Showing 1 changed file with 10 additions and 3 deletions.
13 changes: 10 additions & 3 deletions drivers/mtd/nand/spi/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1213,10 +1213,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;

Expand All @@ -1235,13 +1238,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;
}

/**
Expand Down

0 comments on commit 666c299

Please sign in to comment.