All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] Driver for Cadence xSPI flash controller
@ 2020-12-09  7:57 Jayshri Pawar
  2020-12-09  7:57 ` [PATCH 1/2] Add support for Cadence XSPI controller Jayshri Pawar
  2020-12-09  7:57 ` [PATCH 2/2] Add dt-bindings documentation " Jayshri Pawar
  0 siblings, 2 replies; 8+ messages in thread
From: Jayshri Pawar @ 2020-12-09  7:57 UTC (permalink / raw)
  To: linux-spi
  Cc: miquel.raynal, richard, vigneshr, linux-kernel, dkangude, mparab,
	sjakhade, jpawar

Command processing
Driver uses STIG work mode to communicate with flash memories.
In this mode, controller sends low-level instructions to memory.
Each instruction is 128-bit width. There is special instruction
DataSequence which carries information about data phase.
Driver uses Slave DMA interface to transfer data as only this
interface can be used in STIG work mode.

PHY initialization
The initialization of PHY module in Cadence XSPI controller
is done by driving external pin-strap signals to controller.
Next, driver runs PHY training to find optimal value of
read_dqs_delay parameter. Controller checks device discovery
status and if it's completed and with no error PHY training
passes.

Jayshri Pawar (2):
  Add support for Cadence XSPI controller
  Add dt-bindings documentation for Cadence XSPI controller

 .../devicetree/bindings/spi/cdns,xspi.yaml         | 164 ++++
 drivers/spi/Kconfig                                |  11 +
 drivers/spi/Makefile                               |   1 +
 drivers/spi/spi-cadence-xspi.c                     | 894 +++++++++++++++++++++
 4 files changed, 1070 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/spi/cdns,xspi.yaml
 create mode 100644 drivers/spi/spi-cadence-xspi.c

-- 
2.7.4


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/2] Add support for Cadence XSPI controller
  2020-12-09  7:57 [PATCH 0/2] Driver for Cadence xSPI flash controller Jayshri Pawar
@ 2020-12-09  7:57 ` Jayshri Pawar
  2020-12-09 10:28     ` kernel test robot
                     ` (2 more replies)
  2020-12-09  7:57 ` [PATCH 2/2] Add dt-bindings documentation " Jayshri Pawar
  1 sibling, 3 replies; 8+ messages in thread
From: Jayshri Pawar @ 2020-12-09  7:57 UTC (permalink / raw)
  To: linux-spi
  Cc: miquel.raynal, richard, vigneshr, linux-kernel, dkangude, mparab,
	sjakhade, jpawar, Konrad Kociolek

This driver uses SPI-MEM framework and is capable to operate with
single, dual, quad and octal SPI-NOR memories.
Low-level controller work mode (STIG) is utilized to communicate
with flash memories.

Signed-off-by: Jayshri Pawar <jpawar@cadence.com>
Signed-off-by: Konrad Kociolek <konrad@cadence.com>
---
 drivers/spi/Kconfig            |  11 +
 drivers/spi/Makefile           |   1 +
 drivers/spi/spi-cadence-xspi.c | 894 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 906 insertions(+)
 create mode 100644 drivers/spi/spi-cadence-xspi.c

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 5cff60d..a699c14 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -212,6 +212,17 @@ config SPI_CADENCE_QUADSPI
 	  device with a Cadence QSPI controller and want to access the
 	  Flash as an MTD device.
 
+config SPI_CADENCE_XSPI
+	tristate "Cadence XSPI controller"
+	depends on (OF || COMPILE_TEST) && HAS_IOMEM
+	help
+	  Enable support for the Cadence XSPI Flash controller.
+
+	  Cadence XSPI is a specialized controller for connecting an SPI
+	  Flash over upto 8bit wide bus. Enable this option if you have a
+	  device with a Cadence XSPI controller and want to access the
+	  Flash as an MTD device.
+
 config SPI_CLPS711X
 	tristate "CLPS711X host SPI controller"
 	depends on ARCH_CLPS711X || COMPILE_TEST
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 6fea582..cb72cd6 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_SPI_BITBANG)		+= spi-bitbang.o
 obj-$(CONFIG_SPI_BUTTERFLY)		+= spi-butterfly.o
 obj-$(CONFIG_SPI_CADENCE)		+= spi-cadence.o
 obj-$(CONFIG_SPI_CADENCE_QUADSPI)	+= spi-cadence-quadspi.o
+obj-$(CONFIG_SPI_CADENCE_XSPI)      	+= spi-cadence-xspi.o
 obj-$(CONFIG_SPI_CLPS711X)		+= spi-clps711x.o
 obj-$(CONFIG_SPI_COLDFIRE_QSPI)		+= spi-coldfire-qspi.o
 obj-$(CONFIG_SPI_DAVINCI)		+= spi-davinci.o
diff --git a/drivers/spi/spi-cadence-xspi.c b/drivers/spi/spi-cadence-xspi.c
new file mode 100644
index 0000000..fbf2aec
--- /dev/null
+++ b/drivers/spi/spi-cadence-xspi.c
@@ -0,0 +1,894 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Cadence XSPI flash controller driver
+ *
+ * Copyright (C) 2020 Cadence
+ *
+ * Author: Konrad Kociolek <konrad@cadence.com>
+ * Author: Jayshri Pawar <jpawar@cadence.com>
+ */
+#include <linux/completion.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/spi/spi.h>
+#include <linux/mtd/spi-nor.h>
+#include <linux/bitfield.h>
+#include <linux/limits.h>
+#include <linux/log2.h>
+
+#define CDNS_XSPI_MAGIC_NUM_VALUE               0x6522
+#define CDNS_XSPI_MAX_BANKS                     8
+#define CDNS_XSPI_NAME                          "cadence-xspi"
+
+/*
+ * Note: below are additional auxiliary registers to
+ * configure XSPI controller pin-strap settings
+ */
+
+/* PHY DQ timing register */
+#define CDNS_XSPI_CCP_PHY_DQ_TIMING           0x0000
+#define CDNS_XSPI_CCP_DATA_SELECT_OE_START    GENMASK(6, 4)
+#define CDNS_XSPI_CCP_DATA_SELECT_OE_END      GENMASK(2, 0)
+#define CDNS_XSPI_CCP_PHY_DQ_TIMING_INIT_VAL  0x80000000
+
+/* PHY DQS timing register */
+#define CDNS_XSPI_CCP_PHY_DQS_TIMING          0x0004
+#define CDNS_XSPI_CCP_USE_EXT_LPBCK_DQS       BIT(22)
+#define CDNS_XSPI_CCP_USE_LPBCK_DQS           BIT(21)
+#define CDNS_XSPI_CCP_USE_PHONY               BIT(20)
+#define CDNS_XSPI_CCP_DQS_SELECT_OE_START     GENMASK(7, 4)
+#define CDNS_XSPI_CCP_DQS_SELECT_OE_END       GENMASK(3, 0)
+
+/* PHY gate loopback control register */
+#define CDNS_XSPI_CCP_PHY_GATE_LPBCK_CTRL     0x0008
+#define CDNS_XSPI_CCP_READ_DATA_DELAY_SEL     GENMASK(24, 19)
+#define CDNS_XSPI_CCP_GATE_CFG_CLOSE          GENMASK(5, 4)
+#define CDNS_XSPI_CCP_GATE_CFG                GENMASK(3, 0)
+
+/* PHY DLL slave control register */
+#define CDNS_XSPI_CCP_PHY_DLL_SLAVE_CTRL      0x0010
+#define CDNS_XSPI_CCP_CLK_WR_DELAY            GENMASK(15, 8)
+#define CDNS_XSPI_CCP_READ_DQS_DELAY          GENMASK(7, 0)
+
+#define CDNS_XSPI_AUX_PHY_ADDONS_REG          0x0040
+#define CDNS_XSPI_AUX_PHY_ADDONS_VALUE        0xE0012000
+#define CDNS_XSPI_AUX_DEV_DISC_CONFIG_REG     0x0048
+#define CDNS_XSPI_AUX_DEV_DISC_CONFIG_VALUE   0x00000000
+#define CDNS_XSPI_AUX_DRIVING_REG             0x0050
+#define CDNS_XSPI_AUX_CTRL_RESET              BIT(0)
+
+/* DLL PHY control register */
+#define CDNS_XSPI_DLL_PHY_CTRL                0x1034
+#define CDNS_XSPI_CCP_DQS_LAST_DATA_DROP_EN   BIT(20)
+
+/* Command registers */
+#define CDNS_XSPI_CMD_REG_0                   0x0000
+#define CDNS_XSPI_CMD_REG_1                   0x0004
+#define CDNS_XSPI_CMD_REG_2                   0x0008
+#define CDNS_XSPI_CMD_REG_3                   0x000C
+#define CDNS_XSPI_CMD_REG_4                   0x0010
+#define CDNS_XSPI_CMD_REG_5                   0x0014
+
+/* Command status registers */
+#define CDNS_XSPI_CMD_STATUS_REG              0x0044
+#define CDNS_XSPI_CMD_COMPLETED               BIT(15)
+#define CDNS_XSPI_CMD_FAILED                  BIT(14)
+
+/* Controller status register */
+#define CDNS_XSPI_CTRL_STATUS_REG             0x0100
+#define CDNS_XSPI_INIT_COMPLETED              BIT(16)
+#define CDNS_XSPI_INIT_LEGACY                 BIT(9)
+#define CDNS_XSPI_INIT_FAIL                   BIT(8)
+#define CDNS_XSPI_CTRL_BUSY                   BIT(7)
+
+/* Controller interrupt status register */
+#define CDNS_XSPI_INTR_STATUS_REG             0x0110
+#define CDNS_XSPI_STIG_DONE                   BIT(23)
+#define CDNS_XSPI_SDMA_ERROR                  BIT(22)
+#define CDNS_XSPI_SDMA_TRIGGER                BIT(21)
+
+/* Controller interrupt enable register */
+#define CDNS_XSPI_INTR_ENABLE_REG             0x0114
+#define CDNS_XSPI_INTR_EN                     BIT(31)
+#define CDNS_XSPI_STIG_DONE_EN                BIT(23)
+#define CDNS_XSPI_SDMA_ERROR_EN               BIT(22)
+#define CDNS_XSPI_SDMA_TRIGGER_EN             BIT(21)
+
+#define CDNS_XSPI_INTR_MASK (CDNS_XSPI_INTR_EN | \
+	CDNS_XSPI_STIG_DONE_EN  | \
+	CDNS_XSPI_SDMA_ERROR_EN | \
+	CDNS_XSPI_SDMA_TRIGGER_EN)
+
+/* Controller config register */
+#define CDNS_XSPI_CTRL_CONFIG_REG             0x0230
+#define CDNS_XSPI_CTRL_WORK_MODE              GENMASK(6, 5)
+
+/* SDMA trigger transaction registers */
+#define CDNS_XSPI_SDMA_SIZE_REG               0x0240
+#define CDNS_XSPI_SDMA_TRD_INFO_REG           0x0244
+#define CDNS_XSPI_SDMA_DIR                    BIT(8)
+
+/* Controller features register */
+#define CDNS_XSPI_CTRL_FEATURES_REG           0x0F04
+#define CDNS_XSPI_NUM_BANKS                   GENMASK(25, 24)
+#define CDNS_XSPI_DMA_DATA_WIDTH              BIT(21)
+#define CDNS_XSPI_NUM_THREADS                 GENMASK(3, 0)
+
+/* Controller version register */
+#define CDNS_XSPI_CTRL_VERSION_REG            0x0F00
+#define CDNS_XSPI_MAGIC_NUM                   GENMASK(31, 16)
+#define CDNS_XSPI_CTRL_REV                    GENMASK(7, 0)
+
+/* STIG Profile 1.0 instruction fields (split into registers) */
+#define CDNS_XSPI_CMD_INSTR_TYPE              GENMASK(6, 0)
+#define CDNS_XSPI_CMD_P1_R1_ADDR0             GENMASK(31, 24)
+#define CDNS_XSPI_CMD_P1_R2_ADDR1             GENMASK(7, 0)
+#define CDNS_XSPI_CMD_P1_R2_ADDR2             GENMASK(15, 8)
+#define CDNS_XSPI_CMD_P1_R2_ADDR3             GENMASK(23, 16)
+#define CDNS_XSPI_CMD_P1_R2_ADDR4             GENMASK(31, 24)
+#define CDNS_XSPI_CMD_P1_R3_ADDR5             GENMASK(7, 0)
+#define CDNS_XSPI_CMD_P1_R3_CMD               GENMASK(23, 16)
+#define CDNS_XSPI_CMD_P1_R3_NUM_ADDR_BYTES    GENMASK(30, 28)
+#define CDNS_XSPI_CMD_P1_R4_ADDR_IOS          GENMASK(1, 0)
+#define CDNS_XSPI_CMD_P1_R4_CMD_IOS           GENMASK(9, 8)
+#define CDNS_XSPI_CMD_P1_R4_BANK              GENMASK(14, 12)
+
+/* STIG data sequence instruction fields (split into registers) */
+#define CDNS_XSPI_CMD_DSEQ_R2_DCNT_L          GENMASK(31, 16)
+#define CDNS_XSPI_CMD_DSEQ_R3_DCNT_H          GENMASK(15, 0)
+#define CDNS_XSPI_CMD_DSEQ_R3_NUM_OF_DUMMY    GENMASK(25, 20)
+#define CDNS_XSPI_CMD_DSEQ_R4_BANK            GENMASK(14, 12)
+#define CDNS_XSPI_CMD_DSEQ_R4_DATA_IOS        GENMASK(9, 8)
+#define CDNS_XSPI_CMD_DSEQ_R4_DIR             BIT(4)
+
+/* STIG command status fields */
+#define CDNS_XSPI_CMD_STATUS_COMPLETED        BIT(15)
+#define CDNS_XSPI_CMD_STATUS_FAILED           BIT(14)
+#define CDNS_XSPI_CMD_STATUS_DQS_ERROR        BIT(3)
+#define CDNS_XSPI_CMD_STATUS_CRC_ERROR        BIT(2)
+#define CDNS_XSPI_CMD_STATUS_BUS_ERROR        BIT(1)
+#define CDNS_XSPI_CMD_STATUS_INV_SEQ_ERROR    BIT(0)
+
+#define CDNS_XSPI_CTRL_WORK_MODE_STIG         0x01
+
+#define CDNS_XSPI_STIG_DONE_FLAG              BIT(0)
+
+/* Helper macros for filling command registers */
+#define CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_1(op, data_phase) ( \
+	FIELD_PREP(CDNS_XSPI_CMD_INSTR_TYPE, (data_phase) ? \
+		CDNS_XSPI_STIG_INSTR_TYPE_1 : CDNS_XSPI_STIG_INSTR_TYPE_0) | \
+	FIELD_PREP(CDNS_XSPI_CMD_P1_R1_ADDR0, op->addr.val & 0xff))
+
+#define CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_2(op) ( \
+	FIELD_PREP(CDNS_XSPI_CMD_P1_R2_ADDR1, (op->addr.val >> 8)  & 0xFF) | \
+	FIELD_PREP(CDNS_XSPI_CMD_P1_R2_ADDR2, (op->addr.val >> 16) & 0xFF) | \
+	FIELD_PREP(CDNS_XSPI_CMD_P1_R2_ADDR3, (op->addr.val >> 24) & 0xFF) | \
+	FIELD_PREP(CDNS_XSPI_CMD_P1_R2_ADDR4, (op->addr.val >> 32) & 0xFF))
+
+#define CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_3(op) ( \
+	FIELD_PREP(CDNS_XSPI_CMD_P1_R3_ADDR5, (op->addr.val >> 40) & 0xFF) | \
+	FIELD_PREP(CDNS_XSPI_CMD_P1_R3_CMD, op->cmd.opcode) | \
+	FIELD_PREP(CDNS_XSPI_CMD_P1_R3_NUM_ADDR_BYTES, op->addr.nbytes))
+
+#define CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_4(op, chipsel) ( \
+	FIELD_PREP(CDNS_XSPI_CMD_P1_R4_ADDR_IOS, ilog2(op->addr.buswidth)) | \
+	FIELD_PREP(CDNS_XSPI_CMD_P1_R4_CMD_IOS, ilog2(op->cmd.buswidth)) | \
+	FIELD_PREP(CDNS_XSPI_CMD_P1_R4_BANK, chipsel))
+
+#define CDNS_XSPI_CMD_FLD_DSEQ_CMD_1(op) \
+	FIELD_PREP(CDNS_XSPI_CMD_INSTR_TYPE, CDNS_XSPI_STIG_INSTR_TYPE_DATA_SEQ)
+
+#define CDNS_XSPI_CMD_FLD_DSEQ_CMD_2(op) \
+	FIELD_PREP(CDNS_XSPI_CMD_DSEQ_R2_DCNT_L, op->data.nbytes & 0xFFFF)
+
+#define CDNS_XSPI_CMD_FLD_DSEQ_CMD_3(op) ( \
+	FIELD_PREP(CDNS_XSPI_CMD_DSEQ_R3_DCNT_H, \
+		(op->data.nbytes >> 16) & 0xffff) | \
+	FIELD_PREP(CDNS_XSPI_CMD_DSEQ_R3_NUM_OF_DUMMY, op->dummy.nbytes * 8))
+
+#define CDNS_XSPI_CMD_FLD_DSEQ_CMD_4(op, chipsel) ( \
+	FIELD_PREP(CDNS_XSPI_CMD_DSEQ_R4_BANK, chipsel) | \
+	FIELD_PREP(CDNS_XSPI_CMD_DSEQ_R4_DATA_IOS, ilog2(op->data.buswidth)) | \
+	FIELD_PREP(CDNS_XSPI_CMD_DSEQ_R4_DIR, \
+		(op->data.dir == SPI_MEM_DATA_IN) ? \
+		CDNS_XSPI_STIG_CMD_DIR_READ : CDNS_XSPI_STIG_CMD_DIR_WRITE))
+
+enum cdns_xspi_stig_instr_type {
+	CDNS_XSPI_STIG_INSTR_TYPE_0,
+	CDNS_XSPI_STIG_INSTR_TYPE_1,
+	CDNS_XSPI_STIG_INSTR_TYPE_DATA_SEQ = 127,
+};
+
+enum cdns_xspi_sdma_dir {
+	CDNS_XSPI_SDMA_DIR_READ,
+	CDNS_XSPI_SDMA_DIR_WRITE,
+};
+
+enum cdns_xspi_stig_cmd_dir {
+	CDNS_XSPI_STIG_CMD_DIR_READ,
+	CDNS_XSPI_STIG_CMD_DIR_WRITE,
+};
+
+struct cdns_xspi_platform_data {
+	u32 phy_data_sel_oe_start;
+	u32 phy_data_sel_oe_end;
+	u32 phy_dqs_sel_oe_start;
+	u32 phy_dqs_sel_oe_end;
+	u32 phy_gate_cfg_close;
+	u32 phy_gate_cfg;
+	u32 phy_rd_del_sel;
+	u32 clk_wr_delay;
+	bool dqs_last_data_drop;
+	bool use_lpbk_dqs;
+	bool use_ext_lpbk_dqs;
+};
+
+struct cdns_xspi_dev {
+	struct platform_device *pdev;
+	struct device *dev;
+
+	void __iomem *iobase;
+	void __iomem *auxbase;
+	void __iomem *sdmabase;
+
+	int irq;
+	int current_cs;
+
+	struct mutex lock;
+
+	struct completion cmd_complete;
+	struct completion sdma_complete;
+	bool sdma_error;
+
+	void *in_buffer;
+	const void *out_buffer;
+
+	u8 hw_num_banks;
+
+	struct cdns_xspi_platform_data *plat_data;
+};
+
+static void cdns_xspi_controller_reset(struct cdns_xspi_dev *cdns_xspi)
+{
+	u32 driving_reg = 0;
+
+	driving_reg = readl(cdns_xspi->auxbase + CDNS_XSPI_AUX_DRIVING_REG);
+	driving_reg |= CDNS_XSPI_AUX_CTRL_RESET;
+	writel(driving_reg, cdns_xspi->auxbase + CDNS_XSPI_AUX_DRIVING_REG);
+
+	udelay(10);
+
+	driving_reg &= ~CDNS_XSPI_AUX_CTRL_RESET;
+	writel(driving_reg, cdns_xspi->auxbase + CDNS_XSPI_AUX_DRIVING_REG);
+}
+
+static int cdns_xspi_read_dqs_delay_training(struct cdns_xspi_dev *cdns_xspi)
+{
+	int rd_dqs_del;
+	int rd_dqs_del_min = -1;
+	int rd_dqs_del_max = -1;
+
+	u32 phy_dll_slave_ctrl = 0;
+	u32 ctrl_status = 0;
+
+	phy_dll_slave_ctrl = readl(cdns_xspi->auxbase +
+		CDNS_XSPI_CCP_PHY_DLL_SLAVE_CTRL);
+
+	for (rd_dqs_del = 0; rd_dqs_del < U8_MAX; rd_dqs_del++) {
+		phy_dll_slave_ctrl &= ~CDNS_XSPI_CCP_READ_DQS_DELAY;
+		phy_dll_slave_ctrl |= FIELD_PREP(CDNS_XSPI_CCP_READ_DQS_DELAY,
+			rd_dqs_del);
+
+		writel(phy_dll_slave_ctrl,
+			cdns_xspi->auxbase + CDNS_XSPI_CCP_PHY_DLL_SLAVE_CTRL);
+
+		cdns_xspi_controller_reset(cdns_xspi);
+
+		readl_relaxed_poll_timeout(cdns_xspi->iobase +
+			CDNS_XSPI_CTRL_STATUS_REG, ctrl_status,
+			(ctrl_status & CDNS_XSPI_INIT_COMPLETED), 10, 10000);
+
+		if (!(ctrl_status & CDNS_XSPI_INIT_COMPLETED) ||
+			(ctrl_status & CDNS_XSPI_INIT_FAIL)) {
+			if (rd_dqs_del_min != -1)
+				rd_dqs_del_max = rd_dqs_del - 1;
+		} else {
+			if (rd_dqs_del_min == -1)
+				rd_dqs_del_min = rd_dqs_del;
+		}
+	}
+
+	if (rd_dqs_del_min == -1) {
+		dev_err(cdns_xspi->dev, "PHY training failed\n");
+		return -EBUSY;
+	} else if (rd_dqs_del_max == -1) {
+		rd_dqs_del_max = U8_MAX;
+	}
+
+	rd_dqs_del = rd_dqs_del_min + rd_dqs_del_max / 2;
+	dev_info(cdns_xspi->dev,
+		"Using optimal read_dqs_delay value: %d\n", rd_dqs_del);
+
+	phy_dll_slave_ctrl &= ~CDNS_XSPI_CCP_READ_DQS_DELAY;
+	phy_dll_slave_ctrl |= FIELD_PREP(CDNS_XSPI_CCP_READ_DQS_DELAY,
+		rd_dqs_del);
+
+	writel(phy_dll_slave_ctrl,
+		cdns_xspi->auxbase + CDNS_XSPI_CCP_PHY_DLL_SLAVE_CTRL);
+
+	return 0;
+}
+
+static int cdns_xspi_phy_init(struct cdns_xspi_dev *cdns_xspi)
+{
+	u32 xspi_dll_phy_ctrl = 0;
+	u32 phy_dq_timing = CDNS_XSPI_CCP_PHY_DQ_TIMING_INIT_VAL;
+	u32 phy_dqs_timing = 0;
+	u32 phy_gate_lpbck_ctrl = 0;
+	u32 phy_dll_slave_ctrl = 0;
+
+	if (cdns_xspi->plat_data->use_lpbk_dqs) {
+		phy_dqs_timing |= FIELD_PREP(CDNS_XSPI_CCP_USE_LPBCK_DQS, 1);
+
+		/*
+		 * For XSPI protocol, phony_dqs and lpbk_dqs must
+		 * have same value
+		 */
+		phy_dqs_timing |= FIELD_PREP(CDNS_XSPI_CCP_USE_PHONY, 1);
+
+		if (cdns_xspi->plat_data->use_ext_lpbk_dqs)
+			phy_dqs_timing |=
+				FIELD_PREP(CDNS_XSPI_CCP_USE_EXT_LPBCK_DQS, 1);
+	}
+
+	xspi_dll_phy_ctrl = readl(cdns_xspi->auxbase + CDNS_XSPI_DLL_PHY_CTRL);
+
+	/* While using memory DQS last_data_drop parameter should be enabled */
+	if (cdns_xspi->plat_data->dqs_last_data_drop)
+		xspi_dll_phy_ctrl |=
+			FIELD_PREP(CDNS_XSPI_CCP_DQS_LAST_DATA_DROP_EN, 1);
+
+	phy_dq_timing |= FIELD_PREP(CDNS_XSPI_CCP_DATA_SELECT_OE_START,
+		cdns_xspi->plat_data->phy_data_sel_oe_start);
+	phy_dq_timing |= FIELD_PREP(CDNS_XSPI_CCP_DATA_SELECT_OE_END,
+		cdns_xspi->plat_data->phy_data_sel_oe_end);
+
+	phy_dqs_timing |= FIELD_PREP(CDNS_XSPI_CCP_DQS_SELECT_OE_START,
+		cdns_xspi->plat_data->phy_dqs_sel_oe_start);
+	phy_dqs_timing |= FIELD_PREP(CDNS_XSPI_CCP_DQS_SELECT_OE_END,
+		cdns_xspi->plat_data->phy_dqs_sel_oe_end);
+
+	phy_gate_lpbck_ctrl |= FIELD_PREP(CDNS_XSPI_CCP_GATE_CFG_CLOSE,
+		cdns_xspi->plat_data->phy_gate_cfg_close);
+	phy_gate_lpbck_ctrl |= FIELD_PREP(CDNS_XSPI_CCP_GATE_CFG,
+		cdns_xspi->plat_data->phy_gate_cfg);
+	phy_gate_lpbck_ctrl |= FIELD_PREP(CDNS_XSPI_CCP_READ_DATA_DELAY_SEL,
+		cdns_xspi->plat_data->phy_rd_del_sel);
+
+	phy_dll_slave_ctrl |= FIELD_PREP(CDNS_XSPI_CCP_CLK_WR_DELAY,
+		cdns_xspi->plat_data->clk_wr_delay);
+
+	writel(xspi_dll_phy_ctrl,
+		cdns_xspi->auxbase + CDNS_XSPI_DLL_PHY_CTRL);
+	writel(phy_dq_timing,
+		cdns_xspi->auxbase + CDNS_XSPI_CCP_PHY_DQ_TIMING);
+	writel(phy_dqs_timing,
+		cdns_xspi->auxbase + CDNS_XSPI_CCP_PHY_DQS_TIMING);
+	writel(phy_gate_lpbck_ctrl,
+		cdns_xspi->auxbase + CDNS_XSPI_CCP_PHY_GATE_LPBCK_CTRL);
+	writel(phy_dll_slave_ctrl,
+		cdns_xspi->auxbase + CDNS_XSPI_CCP_PHY_DLL_SLAVE_CTRL);
+
+	writel(CDNS_XSPI_AUX_PHY_ADDONS_VALUE,
+		cdns_xspi->auxbase + CDNS_XSPI_AUX_PHY_ADDONS_REG);
+	writel(CDNS_XSPI_AUX_DEV_DISC_CONFIG_VALUE,
+		cdns_xspi->auxbase + CDNS_XSPI_AUX_DEV_DISC_CONFIG_REG);
+
+	return cdns_xspi_read_dqs_delay_training(cdns_xspi);
+}
+
+static int cdns_xspi_wait_for_controller_idle(struct cdns_xspi_dev *cdns_xspi)
+{
+	u32 ctrl_stat;
+
+	return readl_relaxed_poll_timeout(cdns_xspi->iobase +
+		CDNS_XSPI_CTRL_STATUS_REG,
+		ctrl_stat, ((ctrl_stat & CDNS_XSPI_CTRL_BUSY) == 0), 100, 1000);
+}
+
+static void cdns_xspi_trigger_command(struct cdns_xspi_dev *cdns_xspi,
+	u32 cmd_regs[5])
+{
+	writel(cmd_regs[5], cdns_xspi->iobase + CDNS_XSPI_CMD_REG_5);
+	writel(cmd_regs[4], cdns_xspi->iobase + CDNS_XSPI_CMD_REG_4);
+	writel(cmd_regs[3], cdns_xspi->iobase + CDNS_XSPI_CMD_REG_3);
+	writel(cmd_regs[2], cdns_xspi->iobase + CDNS_XSPI_CMD_REG_2);
+	writel(cmd_regs[1], cdns_xspi->iobase + CDNS_XSPI_CMD_REG_1);
+	writel(cmd_regs[0], cdns_xspi->iobase + CDNS_XSPI_CMD_REG_0);
+}
+
+static int cdns_xspi_check_command_status(struct cdns_xspi_dev *cdns_xspi)
+{
+	int ret = 0;
+	u32 cmd_status = readl(cdns_xspi->iobase + CDNS_XSPI_CMD_STATUS_REG);
+
+	if (cmd_status & CDNS_XSPI_CMD_STATUS_COMPLETED) {
+		if ((cmd_status & CDNS_XSPI_CMD_STATUS_FAILED) != 0) {
+			if (cmd_status & CDNS_XSPI_CMD_STATUS_DQS_ERROR) {
+				dev_err(cdns_xspi->dev,
+					"Incorrect DQS pulses were detected during data read operation\n");
+				ret = -EPROTO;
+			}
+			if (cmd_status & CDNS_XSPI_CMD_STATUS_CRC_ERROR) {
+				dev_err(cdns_xspi->dev,
+					"CRC error received from minicontroller\n");
+				ret = -EPROTO;
+			}
+			if (cmd_status & CDNS_XSPI_CMD_STATUS_BUS_ERROR) {
+				dev_err(cdns_xspi->dev,
+					"Controller got an error response on the system DMA interface\n");
+				ret = -EPROTO;
+			}
+			if (cmd_status & CDNS_XSPI_CMD_STATUS_INV_SEQ_ERROR) {
+				dev_err(cdns_xspi->dev,
+					"Invalid command sequence has been detected\n");
+				ret = -EPROTO;
+			}
+		}
+	} else {
+		dev_err(cdns_xspi->dev, "Fatal error - command not completed\n");
+		ret = -EPROTO;
+	}
+
+	return ret;
+}
+
+static void cdns_xspi_set_interrupts(struct cdns_xspi_dev *cdns_xspi,
+	bool enabled)
+{
+	u32 intr_enable;
+
+	intr_enable = readl(cdns_xspi->iobase + CDNS_XSPI_INTR_ENABLE_REG);
+	if (enabled)
+		intr_enable |= CDNS_XSPI_INTR_MASK;
+	else
+		intr_enable &= ~CDNS_XSPI_INTR_MASK;
+	writel(intr_enable, cdns_xspi->iobase + CDNS_XSPI_INTR_ENABLE_REG);
+}
+
+static int cdns_xspi_controller_init(struct cdns_xspi_dev *cdns_xspi)
+{
+	u32 ctrl_ver;
+	u32 ctrl_features;
+	u16 hw_magic_num;
+
+	ctrl_ver = readl(cdns_xspi->iobase + CDNS_XSPI_CTRL_VERSION_REG);
+	hw_magic_num = FIELD_GET(CDNS_XSPI_MAGIC_NUM, ctrl_ver);
+	if (hw_magic_num != CDNS_XSPI_MAGIC_NUM_VALUE) {
+		dev_err(cdns_xspi->dev,
+			"Incorrect XSPI magic nunber: %x, expected: %x\n",
+			hw_magic_num, CDNS_XSPI_MAGIC_NUM_VALUE);
+		return -EIO;
+	}
+
+	ctrl_features = readl(cdns_xspi->iobase + CDNS_XSPI_CTRL_FEATURES_REG);
+	cdns_xspi->hw_num_banks = FIELD_GET(CDNS_XSPI_NUM_BANKS, ctrl_features);
+
+	writel(FIELD_PREP(CDNS_XSPI_CTRL_WORK_MODE,
+		CDNS_XSPI_CTRL_WORK_MODE_STIG),
+		cdns_xspi->iobase + CDNS_XSPI_CTRL_CONFIG_REG);
+
+	cdns_xspi_set_interrupts(cdns_xspi, false);
+
+	return 0;
+}
+
+static void cdns_xspi_sdma_handle(struct cdns_xspi_dev *cdns_xspi)
+{
+	u32 sdma_size, sdma_trd_info;
+	u8 sdma_dir;
+
+	sdma_size = readl(cdns_xspi->iobase + CDNS_XSPI_SDMA_SIZE_REG);
+	sdma_trd_info = readl(cdns_xspi->iobase + CDNS_XSPI_SDMA_TRD_INFO_REG);
+	sdma_dir = FIELD_GET(CDNS_XSPI_SDMA_DIR, sdma_trd_info);
+
+	switch (sdma_dir) {
+	case CDNS_XSPI_SDMA_DIR_READ:
+		ioread8_rep(cdns_xspi->sdmabase,
+			cdns_xspi->in_buffer, sdma_size);
+		break;
+
+	case CDNS_XSPI_SDMA_DIR_WRITE:
+		iowrite8_rep(cdns_xspi->sdmabase,
+			cdns_xspi->out_buffer, sdma_size);
+		break;
+	}
+}
+
+static int cdns_xspi_send_stig_command(struct cdns_xspi_dev *cdns_xspi,
+	const struct spi_mem_op *op, bool data_phase)
+{
+	u32 cmd_regs[5] = {0};
+	u32 cmd_status;
+
+	cdns_xspi_wait_for_controller_idle(cdns_xspi);
+	cdns_xspi_set_interrupts(cdns_xspi, true);
+	cdns_xspi->sdma_error = false;
+
+	cmd_regs[1] = CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_1(op, data_phase);
+	cmd_regs[2] = CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_2(op);
+	cmd_regs[3] = CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_3(op);
+	cmd_regs[4] = CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_4(op,
+		cdns_xspi->current_cs);
+
+	cdns_xspi_trigger_command(cdns_xspi, cmd_regs);
+
+	if (data_phase) {
+
+		cmd_regs[0] = CDNS_XSPI_STIG_DONE_FLAG;
+
+		cmd_regs[1] = CDNS_XSPI_CMD_FLD_DSEQ_CMD_1(op);
+		cmd_regs[2] = CDNS_XSPI_CMD_FLD_DSEQ_CMD_2(op);
+		cmd_regs[3] = CDNS_XSPI_CMD_FLD_DSEQ_CMD_3(op);
+		cmd_regs[4] = CDNS_XSPI_CMD_FLD_DSEQ_CMD_4(op,
+			cdns_xspi->current_cs);
+
+		cdns_xspi->in_buffer = op->data.buf.in;
+		cdns_xspi->out_buffer = op->data.buf.out;
+
+		cdns_xspi_trigger_command(cdns_xspi, cmd_regs);
+
+		wait_for_completion(&cdns_xspi->sdma_complete);
+		if (cdns_xspi->sdma_error) {
+			cdns_xspi_set_interrupts(cdns_xspi, false);
+			return -EIO;
+		}
+		cdns_xspi_sdma_handle(cdns_xspi);
+	}
+
+	wait_for_completion(&cdns_xspi->cmd_complete);
+
+	cmd_status = cdns_xspi_check_command_status(cdns_xspi);
+	cdns_xspi_set_interrupts(cdns_xspi, false);
+
+	if (cmd_status & CDNS_XSPI_CMD_STATUS_FAILED)
+		return -EPROTO;
+
+	return 0;
+}
+
+static int cdns_xspi_mem_op(struct cdns_xspi_dev *cdns_xspi,
+	struct spi_mem *mem, const struct spi_mem_op *op)
+{
+	if (cdns_xspi->current_cs != mem->spi->chip_select)
+		cdns_xspi->current_cs = mem->spi->chip_select;
+
+	return cdns_xspi_send_stig_command(cdns_xspi, op,
+		(op->data.dir != SPI_MEM_NO_DATA));
+}
+
+static int cdns_xspi_mem_op_execute(struct spi_mem *mem,
+	const struct spi_mem_op *op)
+{
+	struct cdns_xspi_dev *cdns_xspi =
+		spi_master_get_devdata(mem->spi->master);
+	int ret = 0;
+
+	mutex_lock(&cdns_xspi->lock);
+	ret = cdns_xspi_mem_op(cdns_xspi, mem, op);
+	mutex_unlock(&cdns_xspi->lock);
+
+	return ret;
+}
+
+static const struct spi_controller_mem_ops cadence_xspi_mem_ops = {
+	.exec_op = cdns_xspi_mem_op_execute,
+};
+
+static int cdns_xspi_setup(struct spi_device *spi_dev)
+{
+	if (spi_dev->chip_select > spi_dev->master->num_chipselect) {
+		dev_err(&spi_dev->dev,
+			"%d chip-select is out of range\n",
+			spi_dev->chip_select);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static irqreturn_t cdns_xspi_irq_handler(int this_irq, void *dev)
+{
+	struct cdns_xspi_dev *cdns_xspi = dev;
+	u32 irq_status;
+	irqreturn_t result = IRQ_NONE;
+
+	irq_status = readl(cdns_xspi->iobase + CDNS_XSPI_INTR_STATUS_REG);
+	if (irq_status) {
+		writel(irq_status,
+			cdns_xspi->iobase + CDNS_XSPI_INTR_STATUS_REG);
+
+		if (irq_status & CDNS_XSPI_SDMA_ERROR) {
+			dev_err(cdns_xspi->dev, "Slave DMA transaction error\n");
+			cdns_xspi->sdma_error = true;
+			complete(&cdns_xspi->sdma_complete);
+		}
+
+		if (irq_status & CDNS_XSPI_SDMA_TRIGGER)
+			complete(&cdns_xspi->sdma_complete);
+
+		if (irq_status & CDNS_XSPI_STIG_DONE)
+			complete(&cdns_xspi->cmd_complete);
+
+		result = IRQ_HANDLED;
+	}
+
+	return result;
+}
+
+static int cdns_xspi_of_get_plat_data(struct platform_device *pdev)
+{
+	struct device_node *node_prop = pdev->dev.of_node;
+	struct device_node *node_child;
+	struct cdns_xspi_platform_data *plat_data = pdev->dev.platform_data;
+	unsigned int property;
+	unsigned int cs;
+
+	if (of_property_read_u32(node_prop,
+		"cdns,phy-data-select-oe-start", &property)) {
+		dev_err(&pdev->dev, "Couldn't determine data select oe start\n");
+		return -ENXIO;
+	}
+	plat_data->phy_data_sel_oe_start = property;
+
+	if (of_property_read_u32(node_prop,
+		"cdns,phy-data-select-oe-end", &property)) {
+		dev_err(&pdev->dev, "Couldn't determine data select oe end\n");
+		return -ENXIO;
+	}
+	plat_data->phy_data_sel_oe_end = property;
+
+	if (of_property_read_u32(node_prop,
+		"cdns,phy-dqs-select-oe-start", &property)) {
+		dev_err(&pdev->dev, "Couldn't determine DQS select oe start\n");
+		return -ENXIO;
+	}
+	plat_data->phy_dqs_sel_oe_start = property;
+
+	if (of_property_read_u32(node_prop,
+		"cdns,phy-dqs-select-oe-end", &property)) {
+		dev_err(&pdev->dev, "Couldn't determine DQS select oe end\n");
+		return -ENXIO;
+	}
+	plat_data->phy_dqs_sel_oe_end = property;
+
+	if (of_property_read_u32(node_prop,
+		"cdns,phy-gate-cfg-close", &property)) {
+		dev_err(&pdev->dev, "Couldn't determine gate config close\n");
+		return -ENXIO;
+	}
+	plat_data->phy_gate_cfg_close = property;
+
+	if (of_property_read_u32(node_prop,
+		"cdns,phy-gate-cfg", &property)) {
+		dev_err(&pdev->dev, "Couldn't determine gate config\n");
+		return -ENXIO;
+	}
+	plat_data->phy_gate_cfg = property;
+
+	if (of_property_read_u32(node_prop,
+		"cdns,phy-rd-del-select", &property)) {
+		dev_err(&pdev->dev, "Couldn't determine read delay select\n");
+		return -ENXIO;
+	}
+	plat_data->phy_rd_del_sel = property;
+
+	if (of_property_read_u32(node_prop,
+		"cdns,phy-clk-wr-delay", &property)) {
+		dev_err(&pdev->dev, "Couldn't determine clock write delay\n");
+		return -ENXIO;
+	}
+	plat_data->clk_wr_delay = property;
+
+	plat_data->dqs_last_data_drop = of_property_read_bool(node_prop,
+		"cdns,dqs-last-data-drop");
+	plat_data->use_lpbk_dqs = of_property_read_bool(node_prop,
+		"cdns,phy-use-lpbk-dqs");
+	plat_data->use_ext_lpbk_dqs = of_property_read_bool(node_prop,
+		"cdns,phy-use-ext-lpbk-dqs");
+
+	for_each_child_of_node(node_prop, node_child) {
+		if (!of_device_is_available(node_child))
+			continue;
+
+		if (of_property_read_u32(node_child, "reg", &cs)) {
+			dev_err(&pdev->dev, "Couldn't get memory chip select\n");
+			return -ENXIO;
+		} else if (cs >= CDNS_XSPI_MAX_BANKS) {
+			dev_err(&pdev->dev, "reg (cs) parameter value too large\n");
+			return -ENXIO;
+		}
+	}
+
+	return 0;
+}
+
+static void cdns_xspi_print_phy_config(struct cdns_xspi_dev *cdns_xspi)
+{
+	struct device *dev = cdns_xspi->dev;
+
+	dev_info(dev, "PHY configuration\n");
+	dev_info(dev, "   * xspi_dll_phy_ctrl: %08x\n",
+		readl(cdns_xspi->iobase + CDNS_XSPI_DLL_PHY_CTRL));
+	dev_info(dev, "   * phy_dq_timing: %08x\n",
+		readl(cdns_xspi->auxbase + CDNS_XSPI_CCP_PHY_DQ_TIMING));
+	dev_info(dev, "   * phy_dqs_timing: %08x\n",
+		readl(cdns_xspi->auxbase + CDNS_XSPI_CCP_PHY_DQS_TIMING));
+	dev_info(dev, "   * phy_gate_loopback_ctrl: %08x\n",
+		readl(cdns_xspi->auxbase + CDNS_XSPI_CCP_PHY_GATE_LPBCK_CTRL));
+	dev_info(dev, "   * phy_dll_slave_ctrl: %08x\n",
+		readl(cdns_xspi->auxbase + CDNS_XSPI_CCP_PHY_DLL_SLAVE_CTRL));
+}
+
+static int cdns_xspi_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct spi_master *master = NULL;
+	struct resource *res = NULL;
+	struct cdns_xspi_dev *cdns_xspi = NULL;
+	struct cdns_xspi_platform_data *plat_data = NULL;
+	int ret;
+
+	master = spi_alloc_master(dev, sizeof(*cdns_xspi));
+	if (!master) {
+		ret = -ENOMEM;
+		dev_err(dev, "Failed to allocate memory for spi_master\n");
+		goto err_no_mem;
+	}
+
+	master->mode_bits = SPI_3WIRE | SPI_TX_DUAL  | SPI_TX_QUAD  |
+		SPI_RX_DUAL | SPI_RX_QUAD | SPI_TX_OCTAL | SPI_RX_OCTAL |
+		SPI_MODE_0  | SPI_MODE_3;
+
+	master->mem_ops = &cadence_xspi_mem_ops;
+	master->setup = cdns_xspi_setup;
+	master->dev.of_node = pdev->dev.of_node;
+	master->bus_num = -1;
+
+	platform_set_drvdata(pdev, master);
+
+	plat_data = devm_kmalloc(dev, sizeof(*plat_data), GFP_KERNEL);
+	if (!plat_data) {
+		ret = -ENOMEM;
+		dev_err(dev, "Failed to allocate memory for platform_data\n");
+		goto err_spi_master;
+	}
+	pdev->dev.platform_data = plat_data;
+
+	cdns_xspi = spi_master_get_devdata(master);
+	cdns_xspi->pdev = pdev;
+	cdns_xspi->dev = &pdev->dev;
+	cdns_xspi->current_cs = 0;
+	cdns_xspi->plat_data = plat_data;
+
+	init_completion(&cdns_xspi->cmd_complete);
+	init_completion(&cdns_xspi->sdma_complete);
+
+	ret = cdns_xspi_of_get_plat_data(pdev);
+	if (ret) {
+		ret = -ENODEV;
+		dev_err(dev, "Failed to get platform data\n");
+		goto err_spi_master;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	cdns_xspi->iobase = devm_ioremap_resource(cdns_xspi->dev, res);
+	if (IS_ERR(cdns_xspi->iobase)) {
+		ret = PTR_ERR(cdns_xspi->iobase);
+		dev_err(dev, "Failed to remap controller base address\n");
+		goto err_spi_master;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	cdns_xspi->sdmabase = devm_ioremap_resource(cdns_xspi->dev, res);
+	if (IS_ERR(cdns_xspi->sdmabase)) {
+		ret = PTR_ERR(cdns_xspi->sdmabase);
+		dev_err(dev, "Failed to remap SDMA address\n");
+		goto err_spi_master;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+	cdns_xspi->auxbase = devm_ioremap_resource(cdns_xspi->dev, res);
+	if (IS_ERR(cdns_xspi->auxbase)) {
+		ret = PTR_ERR(cdns_xspi->auxbase);
+		dev_err(dev, "Failed to remap AUX address\n");
+		goto err_spi_master;
+	}
+
+	cdns_xspi->irq = platform_get_irq(pdev, 0);
+	if (cdns_xspi->irq < 0) {
+		ret = -ENXIO;
+		dev_err(dev, "Failed to get IRQ\n");
+		goto err_spi_master;
+	}
+
+	ret = devm_request_irq(dev, cdns_xspi->irq, cdns_xspi_irq_handler,
+		IRQF_SHARED, pdev->name, cdns_xspi);
+	if (ret) {
+		dev_err(dev, "Failed to request IRQ: %d\n", cdns_xspi->irq);
+		goto err_spi_master;
+	}
+
+	ret = cdns_xspi_phy_init(cdns_xspi);
+	if (ret) {
+		dev_err(dev, "Failed to initialize PHY\n");
+		goto err_spi_master;
+	}
+
+	cdns_xspi_print_phy_config(cdns_xspi);
+
+	ret = cdns_xspi_controller_init(cdns_xspi);
+	if (ret) {
+		dev_err(dev, "Failed to initialize controller\n");
+		goto err_spi_master;
+	}
+
+	master->num_chipselect = 1 << cdns_xspi->hw_num_banks;
+
+	ret = devm_spi_register_master(dev, master);
+	if (ret) {
+		dev_err(dev, "Failed to register SPI master\n");
+		goto err_spi_master;
+	}
+
+	dev_info(dev, "Successfully registered SPI master\n");
+
+	return 0;
+
+err_spi_master:
+	spi_master_put(master);
+
+err_no_mem:
+	dev_err(dev, "Failed to probe Cadence XSPI controller driver\n");
+
+	return ret;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id cdns_xspi_of_match[] = {
+	{
+		.compatible = "cdns,xspi-nor-fpga",
+	},
+	{ /* end of table */}
+};
+MODULE_DEVICE_TABLE(of, cdns_xspi_of_match);
+#else
+#define cdns_xspi_of_match NULL
+#endif /* CONFIG_OF */
+
+static struct platform_driver cdns_xspi_platform_driver = {
+	.probe          = cdns_xspi_probe,
+	.remove         = NULL,
+	.driver = {
+		.name = CDNS_XSPI_NAME,
+		.of_match_table = cdns_xspi_of_match,
+	},
+};
+
+module_platform_driver(cdns_xspi_platform_driver);
+
+MODULE_DESCRIPTION("Cadence XSPI Controller Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" CDNS_XSPI_NAME);
+MODULE_AUTHOR("Jayshri Pawar <jpawar@cadence.com>");
+MODULE_AUTHOR("Konrad Kociolek <konrad@cadence.com>");
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/2] Add dt-bindings documentation for Cadence XSPI controller
  2020-12-09  7:57 [PATCH 0/2] Driver for Cadence xSPI flash controller Jayshri Pawar
  2020-12-09  7:57 ` [PATCH 1/2] Add support for Cadence XSPI controller Jayshri Pawar
@ 2020-12-09  7:57 ` Jayshri Pawar
  1 sibling, 0 replies; 8+ messages in thread
From: Jayshri Pawar @ 2020-12-09  7:57 UTC (permalink / raw)
  To: linux-spi
  Cc: miquel.raynal, richard, vigneshr, linux-kernel, dkangude, mparab,
	sjakhade, jpawar, Konrad Kociolek

Add dt-bindings documentation for Cadence XSPI controller
to support SPI based flash memories.

Signed-off-by: Jayshri Pawar <jpawar@cadence.com>
Signed-off-by: Konrad Kociolek <konrad@cadence.com>
---
 .../devicetree/bindings/spi/cdns,xspi.yaml         | 164 +++++++++++++++++++++
 1 file changed, 164 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/spi/cdns,xspi.yaml

diff --git a/Documentation/devicetree/bindings/spi/cdns,xspi.yaml b/Documentation/devicetree/bindings/spi/cdns,xspi.yaml
new file mode 100644
index 0000000..a7d95b5
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/cdns,xspi.yaml
@@ -0,0 +1,164 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright 2020 Cadence
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/spi/cdns,xspi.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Cadence XSPI Controller
+
+maintainers:
+  - Jayshri Pawar <jpawar@cadence.com>
+  - Konrad Kociolek <konrad@cadence.com>
+
+description: |
+  The XSPI controller allows SPI protocol communication in
+  single, dual, quad or octal wire transmission modes for
+  read/write access to slaves such as SPI-NOR flash.
+
+properties:
+  compatible:
+    const: cdns,xspi-nor-fpga
+
+  reg:
+    items:
+      - description: address and lentgh of the controller register set
+      - description: address and lentgh of the Slave DMA data port
+      - description: address and lentgh of the auxiliary registers
+
+  interrupts:
+    maxItems: 1
+
+  cdns,dqs-last-data-drop:
+    type: boolean
+    description: |
+      This parameter should be set when the Flash Device being used
+      issues data on negative edge of Flash clock and returns them with
+      DQS and the PHY is configured to sample data in DQS mode.
+      If this param is set the controller internally requests this redundant
+      data at the end of the transfer cleaning up the PHY FIFO.
+
+  cdns,phy-data-select-oe-start:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: |
+      Adjusts the starting point of the DQ pad output enable window.
+      Lower numbers pull the rising edge earlier in time and larger
+      numbers cause the rising edge to be delayed. Each bit changes
+      the output enable time by a 1/2 cycle resolution.
+
+  cdns,phy-data-select-oe-end:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: |
+      Adjusts the ending point of the DQ pad output enable window.
+      Lower numbers pull the falling edge earlier in time and larger
+      numbers cause the falling edge to be delayed. Each bit changes
+      the output enable time by a 1/2 cycle resolution.
+
+  cdns,phy-dqs-select-oe-start:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: |
+      Adjusts the starting point of the DQS pad output enable window.
+      Lower numbers pull the rising edge earlier in time and larger
+      numbers cause the rising edge to be delayed. Each bit changes
+      the output enable time by a 1/2 cycle resolution.
+
+  cdns,phy-dqs-select-oe-end:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: |
+      Adjusts the ending point of the DQS pad output enable window.
+      Lower numbers pull the falling edge earlier in time and larger
+      numbers cause the falling edge to be delayed. Each bit changes
+      the output enable time by a 1/2 cycle resolution.
+
+  cdns,phy-gate-cfg-close:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: |
+      Normally the gate is closing then all bits of dfi_cebar are high
+      or when dfi_rd_pre_post_amble and rebar_dfi are high. This parameter
+      allows to extend the closing of the DQS gate. Recommended zero.
+
+  cdns,phy-gate-cfg:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: |
+      Coarse adjust of gate open time. This value is the number of cycles
+      to delay the dfi_rddata_en signal prior to opening the gate in
+      full cycle increments. Decreasing this value pulls the gate earlier
+      in time. This field should be programmed such that the gate signal
+      lands in the valid DQS gate window.
+
+  cdns,phy-rd-del-select:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: |
+      Defines the read data delay. Holds the number of cycles to delay
+      the dfi_rddata_en signal prior to enabling the read FIFO.
+      After this delay, the read pointers begin incrementing the read FIFO.
+
+  cdns,phy-clk-wr-delay:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: |
+      Controls the clk_wr delay line which adjusts the write DQ bit
+      timing in 1/256th steps of the clock period in normal DLL
+      locked mode. In bypass mode this field directly programs
+      the number of delay elements.
+
+  cdns,phy-use-lpbk-dqs:
+    type: boolean
+    description: |
+      This parameter chooses lpbk_dqs to capture data for reads.
+      Instead memory DQS will be used.
+
+  cdns,phy-use-ext-lpbk-dqs:
+    type: boolean
+    description: |
+      This parameter chooses external lpbk_dqs for data capture
+      (lpbk_dqs connected to the lpbk_dqs_IO pad). When not used
+      mem_rebar_pad is used for data read capture.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - cdns,phy-data-select-oe-start
+  - cdns,phy-data-select-oe-end
+  - cdns,phy-dqs-select-oe-start
+  - cdns,phy-dqs-select-oe-end
+  - cdns,phy-gate-cfg-close
+  - cdns,phy-gate-cfg
+  - cdns,phy-rd-del-select
+  - cdns,phy-clk-wr-delay
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    xspi: spi@a0010000 {
+        #address-cells = <1>;
+        #size-cells = <0>;
+        compatible = "cdns,xspi-nor-fpga";
+        reg = <0x0 0xa0010000 0x0 0x10000>,
+              <0x0 0xb0000000 0x0 0x10000>,
+              <0x0 0xa0020000 0x0 0x10000>;
+        interrupts = <0 90 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-parent = <&gic>;
+        cdns,dqs-last-data-drop;
+        cdns,phy-data-select-oe-start = <0>;
+        cdns,phy-data-select-oe-end = <4>;
+        cdns,phy-dqs-select-oe-start = <0>;
+        cdns,phy-dqs-select-oe-end = <1>;
+        cdns,phy-gate-cfg-close = <3>;
+        cdns,phy-gate-cfg = <0>;
+        cdns,phy-rd-del-select = <5>;
+        cdns,phy-clk-wr-delay = <64>;
+        cdns,phy-use-lpbk-dqs;
+        cdns,phy-use-ext-lpbk-dqs;
+        flash@0 {
+            compatible = "spi-nor", "micron,mt35xu512";
+            spi-max-frequency = <75000000>;
+            reg = <0>;
+        };
+        flash@1 {
+            compatible = "spi-nor", "micron,mt35xu512";
+            spi-max-frequency = <75000000>;
+            reg = <1>;
+        };
+    };
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/2] Add support for Cadence XSPI controller
  2020-12-09  7:57 ` [PATCH 1/2] Add support for Cadence XSPI controller Jayshri Pawar
@ 2020-12-09 10:28     ` kernel test robot
  2020-12-10 10:33     ` kernel test robot
  2020-12-12 12:18   ` Lukas Wunner
  2 siblings, 0 replies; 8+ messages in thread
From: kernel test robot @ 2020-12-09 10:28 UTC (permalink / raw)
  To: Jayshri Pawar, linux-spi
  Cc: kbuild-all, miquel.raynal, richard, vigneshr, linux-kernel,
	dkangude, mparab, sjakhade, jpawar, Konrad Kociolek

[-- Attachment #1: Type: text/plain, Size: 3361 bytes --]

Hi Jayshri,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on spi/for-next]
[also build test WARNING on v5.10-rc7 next-20201208]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Jayshri-Pawar/Driver-for-Cadence-xSPI-flash-controller/20201209-160406
base:   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next
config: sparc-allyesconfig (attached as .config)
compiler: sparc64-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/5b258ff21564ca007e3b54d865c3cfb9851ed00a
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Jayshri-Pawar/Driver-for-Cadence-xSPI-flash-controller/20201209-160406
        git checkout 5b258ff21564ca007e3b54d865c3cfb9851ed00a
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=sparc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   In file included from arch/sparc/include/asm/io.h:5,
                    from include/linux/io.h:13,
                    from drivers/spi/spi-cadence-xspi.c:15:
   drivers/spi/spi-cadence-xspi.c: In function 'cdns_xspi_send_stig_command':
>> arch/sparc/include/asm/io_64.h:179:2: warning: '*((void *)&cmd_regs+20)' is used uninitialized in this function [-Wuninitialized]
     179 |  __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_writel */"
         |  ^~~~~~~
   drivers/spi/spi-cadence-xspi.c:521:6: note: '*((void *)&cmd_regs+20)' was declared here
     521 |  u32 cmd_regs[5] = {0};
         |      ^~~~~~~~

vim +179 arch/sparc/include/asm/io_64.h

f5e706ad886b6a5 include/asm-sparc/io_64.h      Sam Ravnborg  2008-07-17  174  
79294d7eff89f65 arch/sparc/include/asm/io_64.h Sam Ravnborg  2014-07-20  175  #define writel writel
7c3969c3a4f3593 arch/sparc/include/asm/io_64.h Arnd Bergmann 2014-11-19  176  #define writel_relaxed writel
79294d7eff89f65 arch/sparc/include/asm/io_64.h Sam Ravnborg  2014-07-20  177  static inline void writel(u32 l, volatile void __iomem *addr)
f5e706ad886b6a5 include/asm-sparc/io_64.h      Sam Ravnborg  2008-07-17  178  {
f5e706ad886b6a5 include/asm-sparc/io_64.h      Sam Ravnborg  2008-07-17 @179  	__asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_writel */"
f5e706ad886b6a5 include/asm-sparc/io_64.h      Sam Ravnborg  2008-07-17  180  			     : /* no outputs */
f5e706ad886b6a5 include/asm-sparc/io_64.h      Sam Ravnborg  2008-07-17  181  			     : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
f5e706ad886b6a5 include/asm-sparc/io_64.h      Sam Ravnborg  2008-07-17  182  			     : "memory");
f5e706ad886b6a5 include/asm-sparc/io_64.h      Sam Ravnborg  2008-07-17  183  }
f5e706ad886b6a5 include/asm-sparc/io_64.h      Sam Ravnborg  2008-07-17  184  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 67969 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/2] Add support for Cadence XSPI controller
@ 2020-12-09 10:28     ` kernel test robot
  0 siblings, 0 replies; 8+ messages in thread
From: kernel test robot @ 2020-12-09 10:28 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 3420 bytes --]

Hi Jayshri,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on spi/for-next]
[also build test WARNING on v5.10-rc7 next-20201208]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Jayshri-Pawar/Driver-for-Cadence-xSPI-flash-controller/20201209-160406
base:   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next
config: sparc-allyesconfig (attached as .config)
compiler: sparc64-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/5b258ff21564ca007e3b54d865c3cfb9851ed00a
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Jayshri-Pawar/Driver-for-Cadence-xSPI-flash-controller/20201209-160406
        git checkout 5b258ff21564ca007e3b54d865c3cfb9851ed00a
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=sparc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   In file included from arch/sparc/include/asm/io.h:5,
                    from include/linux/io.h:13,
                    from drivers/spi/spi-cadence-xspi.c:15:
   drivers/spi/spi-cadence-xspi.c: In function 'cdns_xspi_send_stig_command':
>> arch/sparc/include/asm/io_64.h:179:2: warning: '*((void *)&cmd_regs+20)' is used uninitialized in this function [-Wuninitialized]
     179 |  __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_writel */"
         |  ^~~~~~~
   drivers/spi/spi-cadence-xspi.c:521:6: note: '*((void *)&cmd_regs+20)' was declared here
     521 |  u32 cmd_regs[5] = {0};
         |      ^~~~~~~~

vim +179 arch/sparc/include/asm/io_64.h

f5e706ad886b6a5 include/asm-sparc/io_64.h      Sam Ravnborg  2008-07-17  174  
79294d7eff89f65 arch/sparc/include/asm/io_64.h Sam Ravnborg  2014-07-20  175  #define writel writel
7c3969c3a4f3593 arch/sparc/include/asm/io_64.h Arnd Bergmann 2014-11-19  176  #define writel_relaxed writel
79294d7eff89f65 arch/sparc/include/asm/io_64.h Sam Ravnborg  2014-07-20  177  static inline void writel(u32 l, volatile void __iomem *addr)
f5e706ad886b6a5 include/asm-sparc/io_64.h      Sam Ravnborg  2008-07-17  178  {
f5e706ad886b6a5 include/asm-sparc/io_64.h      Sam Ravnborg  2008-07-17 @179  	__asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_writel */"
f5e706ad886b6a5 include/asm-sparc/io_64.h      Sam Ravnborg  2008-07-17  180  			     : /* no outputs */
f5e706ad886b6a5 include/asm-sparc/io_64.h      Sam Ravnborg  2008-07-17  181  			     : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
f5e706ad886b6a5 include/asm-sparc/io_64.h      Sam Ravnborg  2008-07-17  182  			     : "memory");
f5e706ad886b6a5 include/asm-sparc/io_64.h      Sam Ravnborg  2008-07-17  183  }
f5e706ad886b6a5 include/asm-sparc/io_64.h      Sam Ravnborg  2008-07-17  184  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 67969 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/2] Add support for Cadence XSPI controller
  2020-12-09  7:57 ` [PATCH 1/2] Add support for Cadence XSPI controller Jayshri Pawar
@ 2020-12-10 10:33     ` kernel test robot
  2020-12-10 10:33     ` kernel test robot
  2020-12-12 12:18   ` Lukas Wunner
  2 siblings, 0 replies; 8+ messages in thread
From: kernel test robot @ 2020-12-10 10:33 UTC (permalink / raw)
  To: Jayshri Pawar, linux-spi
  Cc: kbuild-all, miquel.raynal, richard, vigneshr, linux-kernel,
	dkangude, mparab, sjakhade, jpawar, Konrad Kociolek

[-- Attachment #1: Type: text/plain, Size: 2693 bytes --]

Hi Jayshri,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on spi/for-next]
[also build test WARNING on v5.10-rc7 next-20201209]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Jayshri-Pawar/Driver-for-Cadence-xSPI-flash-controller/20201209-160406
base:   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next
config: arm-randconfig-r006-20201210 (attached as .config)
compiler: arm-linux-gnueabi-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/5b258ff21564ca007e3b54d865c3cfb9851ed00a
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Jayshri-Pawar/Driver-for-Cadence-xSPI-flash-controller/20201209-160406
        git checkout 5b258ff21564ca007e3b54d865c3cfb9851ed00a
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arm 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   In file included from include/linux/io.h:13,
                    from drivers/spi/spi-cadence-xspi.c:15:
   drivers/spi/spi-cadence-xspi.c: In function 'cdns_xspi_send_stig_command':
>> arch/arm/include/asm/io.h:95:2: warning: '*((void *)&cmd_regs+20)' is used uninitialized in this function [-Wuninitialized]
      95 |  asm volatile("str %1, %0"
         |  ^~~
   drivers/spi/spi-cadence-xspi.c:521:6: note: '*((void *)&cmd_regs+20)' was declared here
     521 |  u32 cmd_regs[5] = {0};
         |      ^~~~~~~~

vim +95 arch/arm/include/asm/io.h

195bbcac2e5c12f Will Deacon    2012-08-24  91  
84c4d3a6d438f59 Thierry Reding 2014-07-28  92  #define __raw_writel __raw_writel
195bbcac2e5c12f Will Deacon    2012-08-24  93  static inline void __raw_writel(u32 val, volatile void __iomem *addr)
195bbcac2e5c12f Will Deacon    2012-08-24  94  {
195bbcac2e5c12f Will Deacon    2012-08-24 @95  	asm volatile("str %1, %0"
5bb5d66d89041b7 Peter Hurley   2015-04-13  96  		     : : "Qo" (*(volatile u32 __force *)addr), "r" (val));
195bbcac2e5c12f Will Deacon    2012-08-24  97  }
195bbcac2e5c12f Will Deacon    2012-08-24  98  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 28313 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/2] Add support for Cadence XSPI controller
@ 2020-12-10 10:33     ` kernel test robot
  0 siblings, 0 replies; 8+ messages in thread
From: kernel test robot @ 2020-12-10 10:33 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 2748 bytes --]

Hi Jayshri,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on spi/for-next]
[also build test WARNING on v5.10-rc7 next-20201209]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Jayshri-Pawar/Driver-for-Cadence-xSPI-flash-controller/20201209-160406
base:   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next
config: arm-randconfig-r006-20201210 (attached as .config)
compiler: arm-linux-gnueabi-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/5b258ff21564ca007e3b54d865c3cfb9851ed00a
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Jayshri-Pawar/Driver-for-Cadence-xSPI-flash-controller/20201209-160406
        git checkout 5b258ff21564ca007e3b54d865c3cfb9851ed00a
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arm 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   In file included from include/linux/io.h:13,
                    from drivers/spi/spi-cadence-xspi.c:15:
   drivers/spi/spi-cadence-xspi.c: In function 'cdns_xspi_send_stig_command':
>> arch/arm/include/asm/io.h:95:2: warning: '*((void *)&cmd_regs+20)' is used uninitialized in this function [-Wuninitialized]
      95 |  asm volatile("str %1, %0"
         |  ^~~
   drivers/spi/spi-cadence-xspi.c:521:6: note: '*((void *)&cmd_regs+20)' was declared here
     521 |  u32 cmd_regs[5] = {0};
         |      ^~~~~~~~

vim +95 arch/arm/include/asm/io.h

195bbcac2e5c12f Will Deacon    2012-08-24  91  
84c4d3a6d438f59 Thierry Reding 2014-07-28  92  #define __raw_writel __raw_writel
195bbcac2e5c12f Will Deacon    2012-08-24  93  static inline void __raw_writel(u32 val, volatile void __iomem *addr)
195bbcac2e5c12f Will Deacon    2012-08-24  94  {
195bbcac2e5c12f Will Deacon    2012-08-24 @95  	asm volatile("str %1, %0"
5bb5d66d89041b7 Peter Hurley   2015-04-13  96  		     : : "Qo" (*(volatile u32 __force *)addr), "r" (val));
195bbcac2e5c12f Will Deacon    2012-08-24  97  }
195bbcac2e5c12f Will Deacon    2012-08-24  98  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 28313 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/2] Add support for Cadence XSPI controller
  2020-12-09  7:57 ` [PATCH 1/2] Add support for Cadence XSPI controller Jayshri Pawar
  2020-12-09 10:28     ` kernel test robot
  2020-12-10 10:33     ` kernel test robot
@ 2020-12-12 12:18   ` Lukas Wunner
  2 siblings, 0 replies; 8+ messages in thread
From: Lukas Wunner @ 2020-12-12 12:18 UTC (permalink / raw)
  To: Jayshri Pawar
  Cc: linux-spi, miquel.raynal, richard, vigneshr, linux-kernel,
	dkangude, mparab, sjakhade, Konrad Kociolek

On Wed, Dec 09, 2020 at 08:57:57AM +0100, Jayshri Pawar wrote:
> +	master = spi_alloc_master(dev, sizeof(*cdns_xspi));
> +	if (!master) {
> +		ret = -ENOMEM;
> +		dev_err(dev, "Failed to allocate memory for spi_master\n");
> +		goto err_no_mem;
> +	}

Please use devm_spi_alloc_master() to simplify the probe error path.
It was introduced in v5.10-rc5 with commit 5e844cc37a5c and is also
available in 5.9-stable and 5.4-stable.

The memory allocater already emits an error message if it can't satisfy
a request.  Emitting an additional message here isn't really necessary.


> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	cdns_xspi->iobase = devm_ioremap_resource(cdns_xspi->dev, res);
> +	if (IS_ERR(cdns_xspi->iobase)) {
> +		ret = PTR_ERR(cdns_xspi->iobase);
> +		dev_err(dev, "Failed to remap controller base address\n");
> +		goto err_spi_master;
> +	}

Please use devm_platform_ioremap_resource().

Thanks,

Lukas

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2020-12-12 12:19 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-09  7:57 [PATCH 0/2] Driver for Cadence xSPI flash controller Jayshri Pawar
2020-12-09  7:57 ` [PATCH 1/2] Add support for Cadence XSPI controller Jayshri Pawar
2020-12-09 10:28   ` kernel test robot
2020-12-09 10:28     ` kernel test robot
2020-12-10 10:33   ` kernel test robot
2020-12-10 10:33     ` kernel test robot
2020-12-12 12:18   ` Lukas Wunner
2020-12-09  7:57 ` [PATCH 2/2] Add dt-bindings documentation " Jayshri Pawar

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.