linux/drivers/spi/spi-zynq-qspi.c

// 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();