Skip to content

Commit

Permalink
spi: Add Zynq QSPI controller driver
Browse files Browse the repository at this point in the history
 - Upstreamed Zynq QSPI controller driver is under spi-mem framework,
   updated the driver to register under spi-master framework.
 - Added SPI_ZYNQ_QSPI_DUAL_STACKED config flag, This selects the
   Zynq QSPI controller in dual stacked mode.
 - Added stripe flag to distinguish between command and data,
   in dual parallel mode.

Signed-off-by: Amit Kumar Mahapatra <amit.kumar-mahapatra@xilinx.com>
Signed-off-by: Naga Sureshkumar Relli <naga.sureshkumar.relli@xilinx.com>
Signed-off-by: Harini Katakam <harinik@xilinx.com>
Signed-off-by: Punnaiah Choudary Kalluri <punnaia@xilinx.com>
Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
State: pending
  • Loading branch information
Amit Kumar Mahapatra authored and Michal Simek committed Apr 16, 2020
1 parent 2976a45 commit 3780469
Show file tree
Hide file tree
Showing 4 changed files with 296 additions and 153 deletions.
10 changes: 9 additions & 1 deletion drivers/spi/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -865,10 +865,18 @@ config SPI_XTENSA_XTFPGA
config SPI_ZYNQ_QSPI
tristate "Xilinx Zynq QSPI controller"
depends on ARCH_ZYNQ || COMPILE_TEST
depends on SPI_MASTER
help
This enables support for the Zynq Quad SPI controller
in master mode.
This controller only supports SPI memory interface.

config SPI_ZYNQ_QSPI_DUAL_STACKED
bool "Xilinx Zynq QSPI Dual stacked configuration"
depends on SPI_ZYNQ_QSPI
help
This selects the Xilinx ZYNQ Quad SPI controller in dual stacked mode.
Enable this option if your hw design is using dual stacked
configuration.

config SPI_ZYNQMP_GQSPI
tristate "Xilinx ZynqMP GQSPI controller"
Expand Down
21 changes: 21 additions & 0 deletions drivers/spi/spi-mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,32 @@
*/
#include <linux/dmaengine.h>
#include <linux/pm_runtime.h>
#include <linux/mtd/spi-nor.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi-mem.h>

#include "internals.h"

#define SPI_MEM_MAX_BUSWIDTH 8

bool update_stripe(const u8 opcode)
{
if (opcode == SPINOR_OP_BE_4K ||
opcode == SPINOR_OP_BE_32K ||
opcode == SPINOR_OP_CHIP_ERASE ||
opcode == SPINOR_OP_SE ||
opcode == SPINOR_OP_BE_32K_4B ||
opcode == SPINOR_OP_SE_4B ||
opcode == SPINOR_OP_BE_4K_4B ||
opcode == SPINOR_OP_WRSR ||
opcode == SPINOR_OP_WREAR ||
opcode == SPINOR_OP_BRWR ||
opcode == SPINOR_OP_WRSR2)
return false;

return true;
}

/**
* spi_controller_dma_map_mem_op_data() - DMA-map the buffer attached to a
* memory operation
Expand Down Expand Up @@ -346,6 +365,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
xfers[xferpos].tx_buf = tmpbuf + op->addr.nbytes + 1;
xfers[xferpos].len = op->dummy.nbytes;
xfers[xferpos].tx_nbits = op->dummy.buswidth;
xfers[xferpos].dummy = op->dummy.nbytes * 8;
spi_message_add_tail(&xfers[xferpos], &msg);
xferpos++;
totalxferlen += op->dummy.nbytes;
Expand All @@ -360,6 +380,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
xfers[xferpos].tx_nbits = op->data.buswidth;
}

xfers[xferpos].stripe = update_stripe(op->cmd.opcode);
xfers[xferpos].len = op->data.nbytes;
spi_message_add_tail(&xfers[xferpos], &msg);
xferpos++;
Expand Down
Loading

0 comments on commit 3780469

Please sign in to comment.