spi: spi-ti-qspi: support large flash devices
The TI QSPI IP has limitations: - the MMIO region is 64MB in size - in non-MMIO mode, the transfer can handle 4096 words max. Add support for bigger devices. Use MMIO and DMA transfers below the 64MB boundary, use software generated transfers above. Signed-off-by: Jean Pihet <jean.pihet@newoldbits.com> Cc: Ryan Barnett <ryan.barnett@rockwellcollins.com> Cc: Conrad Ratschan <conrad.ratschan@rockwellcollins.com> Cc: Arnout Vandecappelle <arnout.vandecappelle@essensium.com> Link: https://lore.kernel.org/r/20200114124125.361429-2-jean.pihet@newoldbits.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
b8d40d7712
commit
e97f491450
|
@ -525,6 +525,35 @@ static void ti_qspi_setup_mmap_read(struct spi_device *spi, u8 opcode,
|
|||
QSPI_SPI_SETUP_REG(spi->chip_select));
|
||||
}
|
||||
|
||||
static int ti_qspi_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
|
||||
{
|
||||
struct ti_qspi *qspi = spi_controller_get_devdata(mem->spi->master);
|
||||
size_t max_len;
|
||||
|
||||
if (op->data.dir == SPI_MEM_DATA_IN) {
|
||||
if (op->addr.val < qspi->mmap_size) {
|
||||
/* Limit MMIO to the mmaped region */
|
||||
if (op->addr.val + op->data.nbytes > qspi->mmap_size) {
|
||||
max_len = qspi->mmap_size - op->addr.val;
|
||||
op->data.nbytes = min((size_t) op->data.nbytes,
|
||||
max_len);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Use fallback mode (SW generated transfers) above the
|
||||
* mmaped region.
|
||||
* Adjust size to comply with the QSPI max frame length.
|
||||
*/
|
||||
max_len = QSPI_FRAME;
|
||||
max_len -= 1 + op->addr.nbytes + op->dummy.nbytes;
|
||||
op->data.nbytes = min((size_t) op->data.nbytes,
|
||||
max_len);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ti_qspi_exec_mem_op(struct spi_mem *mem,
|
||||
const struct spi_mem_op *op)
|
||||
{
|
||||
|
@ -575,6 +604,7 @@ static int ti_qspi_exec_mem_op(struct spi_mem *mem,
|
|||
|
||||
static const struct spi_controller_mem_ops ti_qspi_mem_ops = {
|
||||
.exec_op = ti_qspi_exec_mem_op,
|
||||
.adjust_op_size = ti_qspi_adjust_op_size,
|
||||
};
|
||||
|
||||
static int ti_qspi_start_transfer_one(struct spi_master *master,
|
||||
|
|
Loading…
Reference in New Issue