// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2019 Xilinx, Inc. * * Author: Naga Sureshkumar Relli <[email protected]> */ #include <linux/clk.h> #include <linux/delay.h> #include <linux/interrupt.h> #include <linux/io.h> #include <linux/module.h> #include <linux/of_irq.h> #include <linux/of_address.h> #include <linux/platform_device.h> #include <linux/spi/spi.h> #include <linux/workqueue.h> #include <linux/spi/spi-mem.h> /* Register offset definitions */ #define ZYNQ_QSPI_CONFIG_OFFSET … #define ZYNQ_QSPI_STATUS_OFFSET … #define ZYNQ_QSPI_IEN_OFFSET … #define ZYNQ_QSPI_IDIS_OFFSET … #define ZYNQ_QSPI_IMASK_OFFSET … #define ZYNQ_QSPI_ENABLE_OFFSET … #define ZYNQ_QSPI_DELAY_OFFSET … #define ZYNQ_QSPI_TXD_00_00_OFFSET … #define ZYNQ_QSPI_TXD_00_01_OFFSET … #define ZYNQ_QSPI_TXD_00_10_OFFSET … #define ZYNQ_QSPI_TXD_00_11_OFFSET … #define ZYNQ_QSPI_RXD_OFFSET … #define ZYNQ_QSPI_SIC_OFFSET … #define ZYNQ_QSPI_TX_THRESH_OFFSET … #define ZYNQ_QSPI_RX_THRESH_OFFSET … #define ZYNQ_QSPI_GPIO_OFFSET … #define ZYNQ_QSPI_LINEAR_CFG_OFFSET … #define ZYNQ_QSPI_MOD_ID_OFFSET … /* * QSPI Configuration Register bit Masks * * This register contains various control bits that effect the operation * of the QSPI controller */ #define ZYNQ_QSPI_CONFIG_IFMODE_MASK … #define ZYNQ_QSPI_CONFIG_MANSRT_MASK … #define ZYNQ_QSPI_CONFIG_MANSRTEN_MASK … #define ZYNQ_QSPI_CONFIG_SSFORCE_MASK … #define ZYNQ_QSPI_CONFIG_BDRATE_MASK … #define ZYNQ_QSPI_CONFIG_CPHA_MASK … #define ZYNQ_QSPI_CONFIG_CPOL_MASK … #define ZYNQ_QSPI_CONFIG_FWIDTH_MASK … #define ZYNQ_QSPI_CONFIG_MSTREN_MASK … /* * QSPI Configuration Register - Baud rate and target select * * These are the values used in the calculation of baud rate divisor and * setting the target select. */ #define ZYNQ_QSPI_CONFIG_BAUD_DIV_MAX … #define ZYNQ_QSPI_CONFIG_BAUD_DIV_SHIFT … #define ZYNQ_QSPI_CONFIG_PCS … /* * QSPI Interrupt Registers bit Masks * * All the four interrupt registers (Status/Mask/Enable/Disable) have the same * bit definitions. */ #define ZYNQ_QSPI_IXR_RX_OVERFLOW_MASK … #define ZYNQ_QSPI_IXR_TXNFULL_MASK … #define ZYNQ_QSPI_IXR_TXFULL_MASK … #define ZYNQ_QSPI_IXR_RXNEMTY_MASK … #define ZYNQ_QSPI_IXR_RXF_FULL_MASK … #define ZYNQ_QSPI_IXR_TXF_UNDRFLOW_MASK … #define ZYNQ_QSPI_IXR_ALL_MASK … #define ZYNQ_QSPI_IXR_RXTX_MASK … /* * QSPI Enable Register bit Masks * * This register is used to enable or disable the QSPI controller */ #define ZYNQ_QSPI_ENABLE_ENABLE_MASK … /* * QSPI Linear Configuration Register * * It is named Linear Configuration but it controls other modes when not in * linear mode also. */ #define ZYNQ_QSPI_LCFG_TWO_MEM … #define ZYNQ_QSPI_LCFG_SEP_BUS … #define ZYNQ_QSPI_LCFG_U_PAGE … #define ZYNQ_QSPI_LCFG_DUMMY_SHIFT … #define ZYNQ_QSPI_FAST_READ_QOUT_CODE … #define ZYNQ_QSPI_FIFO_DEPTH … #define ZYNQ_QSPI_RX_THRESHOLD … #define ZYNQ_QSPI_TX_THRESHOLD … /* * The modebits configurable by the driver to make the SPI support different * data formats */ #define ZYNQ_QSPI_MODEBITS … /* Maximum number of chip selects */ #define ZYNQ_QSPI_MAX_NUM_CS … /** * struct zynq_qspi - Defines qspi driver instance * @dev: Pointer to the this device's information * @regs: Virtual address of the QSPI controller registers * @refclk: Pointer to the peripheral clock * @pclk: Pointer to the APB clock * @irq: IRQ number * @txbuf: Pointer to the TX buffer * @rxbuf: Pointer to the RX buffer * @tx_bytes: Number of bytes left to transfer * @rx_bytes: Number of bytes left to receive * @data_completion: completion structure */ struct zynq_qspi { … }; /* * Inline functions for the QSPI controller read/write */ static inline u32 zynq_qspi_read(struct zynq_qspi *xqspi, u32 offset) { … } static inline void zynq_qspi_write(struct zynq_qspi *xqspi, u32 offset, u32 val) { … } /** * zynq_qspi_init_hw - Initialize the hardware * @xqspi: Pointer to the zynq_qspi structure * @num_cs: Number of connected CS (to enable dual memories if needed) * * The default settings of the QSPI controller's configurable parameters on * reset are * - Host mode * - Baud rate divisor is set to 2 * - Tx threshold set to 1l Rx threshold set to 32 * - Flash memory interface mode enabled * - Size of the word to be transferred as 8 bit * This function performs the following actions * - Disable and clear all the interrupts * - Enable manual target select * - Enable manual start * - Deselect all the chip select lines * - Set the size of the word to be transferred as 32 bit * - Set the little endian mode of TX FIFO and * - Enable the QSPI controller */ static void zynq_qspi_init_hw(struct zynq_qspi *xqspi, unsigned int num_cs) { … } static bool zynq_qspi_supports_op(struct spi_mem *mem, const struct spi_mem_op *op) { … } /** * zynq_qspi_rxfifo_op - Read 1..4 bytes from RxFIFO to RX buffer * @xqspi: Pointer to the zynq_qspi structure * @size: Number of bytes to be read (1..4) */ static void zynq_qspi_rxfifo_op(struct zynq_qspi *xqspi, unsigned int size) { … } /** * zynq_qspi_txfifo_op - Write 1..4 bytes from TX buffer to TxFIFO * @xqspi: Pointer to the zynq_qspi structure * @size: Number of bytes to be written (1..4) */ static void zynq_qspi_txfifo_op(struct zynq_qspi *xqspi, unsigned int size) { … } /** * zynq_qspi_chipselect - Select or deselect the chip select line * @spi: Pointer to the spi_device structure * @assert: 1 for select or 0 for deselect the chip select line */ static void zynq_qspi_chipselect(struct spi_device *spi, bool assert) { … } /** * zynq_qspi_config_op - Configure QSPI controller for specified transfer * @xqspi: Pointer to the zynq_qspi structure * @spi: Pointer to the spi_device structure * * Sets the operational mode of QSPI controller for the next QSPI transfer and * sets the requested clock frequency. * * Return: 0 on success and -EINVAL on invalid input parameter * * Note: If the requested frequency is not an exact match with what can be * obtained using the prescalar value, the driver sets the clock frequency which * is lower than the requested frequency (maximum lower) for the transfer. If * the requested frequency is higher or lower than that is supported by the QSPI * controller the driver will set the highest or lowest frequency supported by * controller. */ static int zynq_qspi_config_op(struct zynq_qspi *xqspi, struct spi_device *spi) { … } /** * zynq_qspi_setup_op - Configure the QSPI controller * @spi: Pointer to the spi_device structure * * Sets the operational mode of QSPI controller for the next QSPI transfer, baud * rate and divisor value to setup the requested qspi clock. * * Return: 0 on success and error value on failure */ static int zynq_qspi_setup_op(struct spi_device *spi) { … } /** * zynq_qspi_write_op - Fills the TX FIFO with as many bytes as possible * @xqspi: Pointer to the zynq_qspi structure * @txcount: Maximum number of words to write * @txempty: Indicates that TxFIFO is empty */ static void zynq_qspi_write_op(struct zynq_qspi *xqspi, int txcount, bool txempty) { … } /** * zynq_qspi_read_op - Drains the RX FIFO by as many bytes as possible * @xqspi: Pointer to the zynq_qspi structure * @rxcount: Maximum number of words to read */ static void zynq_qspi_read_op(struct zynq_qspi *xqspi, int rxcount) { … } /** * zynq_qspi_irq - Interrupt service routine of the QSPI controller * @irq: IRQ number * @dev_id: Pointer to the xqspi structure * * This function handles TX empty only. * On TX empty interrupt this function reads the received data from RX FIFO and * fills the TX FIFO if there is any data remaining to be transferred. * * Return: IRQ_HANDLED when interrupt is handled; IRQ_NONE otherwise. */ static irqreturn_t zynq_qspi_irq(int irq, void *dev_id) { … } /** * zynq_qspi_exec_mem_op() - Initiates the QSPI transfer * @mem: the SPI memory * @op: the memory operation to execute * * Executes a memory operation. * * This function first selects the chip and starts the memory operation. * * Return: 0 in case of success, a negative error code otherwise. */ static int zynq_qspi_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op) { … } static const struct spi_controller_mem_ops zynq_qspi_mem_ops = …; /** * zynq_qspi_probe - Probe method for the QSPI driver * @pdev: Pointer to the platform_device structure * * This function initializes the driver data structures and the hardware. * * Return: 0 on success and error value on failure */ static int zynq_qspi_probe(struct platform_device *pdev) { … } /** * zynq_qspi_remove - Remove method for the QSPI driver * @pdev: Pointer to the platform_device structure * * This function is called if a device is physically removed from the system or * if the driver module is being unloaded. It frees all resources allocated to * the device. * * Return: 0 on success and error value on failure */ static void zynq_qspi_remove(struct platform_device *pdev) { … } static const struct of_device_id zynq_qspi_of_match[] = …; MODULE_DEVICE_TABLE(of, zynq_qspi_of_match); /* * zynq_qspi_driver - This structure defines the QSPI platform driver */ static struct platform_driver zynq_qspi_driver = …; module_platform_driver(…) …; MODULE_AUTHOR(…) …; MODULE_DESCRIPTION(…) …; MODULE_LICENSE(…) …;