mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-15 11:47:47 +00:00
spi: Add spi_mem_calc_op_duration() helper
Merge series from Miquel Raynal <miquel.raynal@bootlin.com>: Add a spi_mem_calc_op_duration() helper
This commit is contained in:
commit
fd85b6b7bc
@ -562,6 +562,36 @@ void spi_mem_adjust_op_freq(struct spi_mem *mem, struct spi_mem_op *op)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(spi_mem_adjust_op_freq);
|
EXPORT_SYMBOL_GPL(spi_mem_adjust_op_freq);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* spi_mem_calc_op_duration() - Derives the theoretical length (in ns) of an
|
||||||
|
* operation. This helps finding the best variant
|
||||||
|
* among a list of possible choices.
|
||||||
|
* @op: the operation to benchmark
|
||||||
|
*
|
||||||
|
* Some chips have per-op frequency limitations, PCBs usually have their own
|
||||||
|
* limitations as well, and controllers can support dual, quad or even octal
|
||||||
|
* modes, sometimes in DTR. All these combinations make it impossible to
|
||||||
|
* statically list the best combination for all situations. If we want something
|
||||||
|
* accurate, all these combinations should be rated (eg. with a time estimate)
|
||||||
|
* and the best pick should be taken based on these calculations.
|
||||||
|
*
|
||||||
|
* Returns a ns estimate for the time this op would take.
|
||||||
|
*/
|
||||||
|
u64 spi_mem_calc_op_duration(struct spi_mem_op *op)
|
||||||
|
{
|
||||||
|
u64 ncycles = 0;
|
||||||
|
u32 ns_per_cycles;
|
||||||
|
|
||||||
|
ns_per_cycles = 1000000000 / op->max_freq;
|
||||||
|
ncycles += ((op->cmd.nbytes * 8) / op->cmd.buswidth) / (op->cmd.dtr ? 2 : 1);
|
||||||
|
ncycles += ((op->addr.nbytes * 8) / op->addr.buswidth) / (op->addr.dtr ? 2 : 1);
|
||||||
|
ncycles += ((op->dummy.nbytes * 8) / op->dummy.buswidth) / (op->dummy.dtr ? 2 : 1);
|
||||||
|
ncycles += ((op->data.nbytes * 8) / op->data.buswidth) / (op->data.dtr ? 2 : 1);
|
||||||
|
|
||||||
|
return ncycles * ns_per_cycles;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(spi_mem_calc_op_duration);
|
||||||
|
|
||||||
static ssize_t spi_mem_no_dirmap_read(struct spi_mem_dirmap_desc *desc,
|
static ssize_t spi_mem_no_dirmap_read(struct spi_mem_dirmap_desc *desc,
|
||||||
u64 offs, size_t len, void *buf)
|
u64 offs, size_t len, void *buf)
|
||||||
{
|
{
|
||||||
|
@ -424,6 +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);
|
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);
|
void spi_mem_adjust_op_freq(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,
|
bool spi_mem_supports_op(struct spi_mem *mem,
|
||||||
const struct spi_mem_op *op);
|
const struct spi_mem_op *op);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user