Skip to content

Commit a11a518

Browse files
committed
spi: spi-mem: Take into account the actual maximum frequency
In order to pick the best variant, the duration of each typical operation is derived and then compared. These durations are based on the maximum capabilities of the chips, which are commonly the limiting factors. However there are other possible limiting pieces, such as the hardware layout, EMC considerations and in some cases, the SPI controller itself. We need to take this into account to further refine our variant choice, so let's use the actual frequency that will be used for the operation instead of the theoretical maximum. Signed-off-by: Miquel Raynal <[email protected]> Reviewed-by: Mark Brown <[email protected]>
1 parent 62df72a commit a11a518

File tree

3 files changed

+16
-6
lines changed

3 files changed

+16
-6
lines changed

drivers/mtd/nand/spi/core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1297,7 +1297,7 @@ spinand_select_op_variant(struct spinand_device *spinand,
12971297

12981298
nbytes -= op.data.nbytes;
12991299

1300-
op_duration_ns += spi_mem_calc_op_duration(&op);
1300+
op_duration_ns += spi_mem_calc_op_duration(spinand->spimem, &op);
13011301
}
13021302

13031303
if (!nbytes && op_duration_ns < best_op_duration_ns) {

drivers/spi/spi-mem.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -586,15 +586,25 @@ EXPORT_SYMBOL_GPL(spi_mem_adjust_op_freq);
586586
* accurate, all these combinations should be rated (eg. with a time estimate)
587587
* and the best pick should be taken based on these calculations.
588588
*
589-
* Returns a ns estimate for the time this op would take.
589+
* Returns a ns estimate for the time this op would take, except if no
590+
* frequency limit has been set, in this case we return the number of
591+
* cycles nevertheless to allow callers to distinguish which operation
592+
* would be the fastest at iso-frequency.
590593
*/
591-
u64 spi_mem_calc_op_duration(struct spi_mem_op *op)
594+
u64 spi_mem_calc_op_duration(struct spi_mem *mem, struct spi_mem_op *op)
592595
{
593596
u64 ncycles = 0;
594597
u64 ps_per_cycles, duration;
595598

596-
ps_per_cycles = 1000000000000ULL;
597-
do_div(ps_per_cycles, op->max_freq);
599+
spi_mem_adjust_op_freq(mem, op);
600+
601+
if (op->max_freq) {
602+
ps_per_cycles = 1000000000000ULL;
603+
do_div(ps_per_cycles, op->max_freq);
604+
} else {
605+
/* In this case, the unit is no longer a time unit */
606+
ps_per_cycles = 1;
607+
}
598608

599609
ncycles += ((op->cmd.nbytes * 8) / op->cmd.buswidth) / (op->cmd.dtr ? 2 : 1);
600610
ncycles += ((op->addr.nbytes * 8) / op->addr.buswidth) / (op->addr.dtr ? 2 : 1);

include/linux/spi/spi-mem.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ bool spi_mem_default_supports_op(struct spi_mem *mem,
424424

425425
int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op);
426426
void spi_mem_adjust_op_freq(struct spi_mem *mem, struct spi_mem_op *op);
427-
u64 spi_mem_calc_op_duration(struct spi_mem_op *op);
427+
u64 spi_mem_calc_op_duration(struct spi_mem *mem, struct spi_mem_op *op);
428428

429429
bool spi_mem_supports_op(struct spi_mem *mem,
430430
const struct spi_mem_op *op);

0 commit comments

Comments
 (0)