]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
spi: zynq_qspi: Move the zynq qspi driver to driver model
authorSiva Durga Prasad Paladugu <siva.durga.paladugu@xilinx.com>
Mon, 3 Aug 2015 10:53:15 +0000 (16:23 +0530)
committerMichal Simek <michal.simek@xilinx.com>
Mon, 10 Aug 2015 05:31:55 +0000 (07:31 +0200)
Changes for the zynq qspi driver to support the SPI driver
model framework.

Signed-off-by: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
15 files changed:
configs/zynq_afx_qspi_RSA_defconfig
configs/zynq_afx_qspi_defconfig
configs/zynq_cse_qspi_defconfig
configs/zynq_zc702_defconfig
configs/zynq_zc706_defconfig
configs/zynq_zc70x_RSA_defconfig
configs/zynq_zc70x_defconfig
configs/zynq_zc770_xm010_RSA_defconfig
configs/zynq_zc770_xm010_defconfig
configs/zynq_zc770_xm013_RSA_defconfig
configs/zynq_zc770_xm013_defconfig
configs/zynq_zed_RSA_defconfig
configs/zynq_zed_defconfig
drivers/spi/zynq_qspi.c
include/configs/zynq-common.h

index 1aee4769161f2394852824c0bd3a5ca777089686..c6aa8e9ab63a9bd5deea536764f410e4a88a3a6e 100644 (file)
@@ -9,3 +9,5 @@ CONFIG_SYS_EXTRA_OPTIONS="AFX_QSPI"
 # CONFIG_CMD_IMLS is not set
 CONFIG_CMD_ZYNQ_RSA=y
 CONFIG_OF_EMBED=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_BAR=y
index 7d9d4cfcbd97ffec3a4955421555d17af64e9b65..c367d490d029adc9272045b3aa8e7da33977c37a 100644 (file)
@@ -5,3 +5,5 @@ CONFIG_DEFAULT_DEVICE_TREE="zynq-afx-qspi"
 CONFIG_SYS_EXTRA_OPTIONS="AFX_QSPI"
 # CONFIG_CMD_IMLS is not set
 CONFIG_OF_EMBED=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_BAR=y
index 3957a671c7db321311d7b5c17b85c693769f5443..70c65c0fd7ddc59c50fb44faa76b0b6962f15b84 100644 (file)
@@ -7,3 +7,5 @@ CONFIG_SYS_EXTRA_OPTIONS="CSE_QSPI"
 # CONFIG_CMD_BOOTM is not set
 # CONFIG_CMD_GO is not set
 CONFIG_OF_EMBED=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_BAR=y
index 936eec27f55fba6ad15c168441f91dee52ff6362..b435dfb3330caabd8aabdfa81e4d05a25a0e803c 100644 (file)
@@ -8,6 +8,7 @@ CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_SIGNATURE=y
 # CONFIG_CMD_IMLS is not set
-# CONFIG_CMD_FLASH is not set
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_OF_EMBED=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_BAR=y
index db11e6fe5b2050ad7c00ecc0fcaad231fbfc4f92..af9bc6192db2514456430101d61d5d566d6db948 100644 (file)
@@ -11,3 +11,5 @@ CONFIG_FIT_SIGNATURE=y
 # CONFIG_CMD_FLASH is not set
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_OF_EMBED=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_BAR=y
index 25813d2a1e03acb0d9dd98473285209afb0be4cc..35ff12b3db638603e7a1625bd02fef7949a1eb6d 100644 (file)
@@ -12,3 +12,5 @@ CONFIG_FIT_SIGNATURE=y
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_ZYNQ_RSA=y
 CONFIG_OF_EMBED=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_BAR=y
index abb02b1349f734a54e3413e02b157f6cffeebda6..571facf1f841efcf585b7adf7e0edc57d4eee9a5 100644 (file)
@@ -11,3 +11,5 @@ CONFIG_FIT_SIGNATURE=y
 # CONFIG_CMD_FLASH is not set
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_OF_EMBED=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_BAR=y
index db64432ddbbb2ca7f77194ca8af965583a0a06af..dd02d8cf4f282bb092cc7dc2357e18ed2f5dcf7f 100644 (file)
@@ -13,3 +13,5 @@ CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM010"
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_ZYNQ_RSA=y
 CONFIG_OF_EMBED=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_BAR=y
index 52511a759aee316082d791ffd379e466b1f30f35..e2f37fbe26c8731977d496ca686a875323ca7c91 100644 (file)
@@ -13,3 +13,4 @@ CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM010"
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_OF_EMBED=y
 CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_BAR=y
index 6dbe02a894ca24f70791e1fd14ca0616ce8ab9c3..8f65f717db46a914e4ba25ca14b66b7148087d85 100644 (file)
@@ -13,3 +13,5 @@ CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM013"
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_ZYNQ_RSA=y
 CONFIG_OF_EMBED=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_BAR=y
index 8f10d325a50c6070ca4137f8856970bb3ae49bae..bb7e10ed4b0e757140f74c813f4f3bef58b1b3ac 100644 (file)
@@ -12,3 +12,5 @@ CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM013"
 # CONFIG_CMD_FLASH is not set
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_OF_EMBED=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_BAR=y
index 4fe5df94ca954ddbd2a34ef714834624a943eb35..d0c2949f60161c141d19f6b85cbfcb72a2700222 100644 (file)
@@ -12,3 +12,5 @@ CONFIG_FIT_SIGNATURE=y
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_ZYNQ_RSA=y
 CONFIG_OF_EMBED=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_BAR=y
index 44885a17fe35de8ef98c791adc923e61ddafc0d1..e575096c355e8b30b2ab930016f6fba5d60a7c35 100644 (file)
@@ -11,3 +11,5 @@ CONFIG_FIT_SIGNATURE=y
 # CONFIG_CMD_FLASH is not set
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_OF_EMBED=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_BAR=y
index aee898770b8aa98e7101b7ba5f865320d298d577..de9d752a5b6986276dca279ce0aebfe3be7acc05 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <common.h>
 #include <malloc.h>
+#include <dm.h>
 #include <ubi_uboot.h>
 #include <spi.h>
 #include <spi_flash.h>
@@ -34,6 +35,7 @@
 #define ZYNQ_QSPI_CONFIG_MCS_MASK      (1 << 14)  /* Manual chip select */
 #define ZYNQ_QSPI_CONFIG_PCS_MASK      (1 << 10)  /* Peri chip select */
 #define ZYNQ_QSPI_CONFIG_FW_MASK       (0x3 << 6) /* FIFO width */
+#define ZYNQ_QSPI_CONFIG_BAUD_DIV_MASK (0x7 << 3) /* Baud rate div */
 #define ZYNQ_QSPI_CONFIG_MSTREN_MASK   (1 << 0)   /* Mode select */
 #define ZYNQ_QSPI_CONFIG_MANSRT_MASK   0x00010000 /* Manual TX Start */
 #define ZYNQ_QSPI_CONFIG_CPHA_MASK     0x00000004 /* Clock Phase Control */
@@ -120,44 +122,42 @@ struct zynq_qspi_regs {
        u32 midr;       /* 0xFC */
 };
 
-#define zynq_qspi_base ((struct zynq_qspi_regs *)ZYNQ_QSPI_BASEADDR)
 
-struct zynq_qspi {
-       u32 input_clk_hz;
+struct zynq_qspi_platdata {
+       struct zynq_qspi_regs *regs;
+       u32 frequency;          /* input frequency */
        u32 speed_hz;
+//     u32 is_dual;
+};
+
+struct zynq_qspi_priv {
+       struct zynq_qspi_regs *regs;
+       u8 mode;
+       u32 freq;
        const void *txbuf;
        void *rxbuf;
+       unsigned len;
        int bytes_to_transfer;
        int bytes_to_receive;
        unsigned int is_inst;
        unsigned int is_dual;
-       unsigned int is_dio;
-       unsigned int u_page;
+        unsigned int is_dio;
+        unsigned int u_page;
+       unsigned cs_change:1;
 };
 
-struct spi_device {
-       struct zynq_qspi master;
-       u32 max_speed_hz;
-       u8 chip_select;
-       u8 mode;
-       u8 bits_per_word;
-};
+static int zynq_qspi_ofdata_to_platdata(struct udevice *bus)
+{
+       struct zynq_qspi_platdata *plat = bus->platdata;
 
-struct spi_transfer {
-       const void *tx_buf;
-       void *rx_buf;
-       unsigned len;
-       unsigned cs_change:1;
-       u8 bits_per_word;
-       u16 delay_usecs;
-       u32 speed_hz;
-};
+       debug("%s\n", __func__);
+       plat->regs = (struct zynq_qspi_regs *)ZYNQ_QSPI_BASEADDR;
 
-struct zynq_qspi_slave {
-       struct spi_slave slave;
-       struct spi_device qspi;
-};
-#define to_zynq_qspi_slave(s) container_of(s, struct zynq_qspi_slave, slave)
+       plat->frequency = 166666666;
+       plat->speed_hz = plat->frequency / 2;
+
+       return 0;
+}
 
 /*
  * zynq_qspi_init_hw - Initialize the hardware
@@ -180,66 +180,222 @@ struct zynq_qspi_slave {
  *     - Set the little endian mode of TX FIFO and
  *     - Enable the QSPI controller
  */
-static void zynq_qspi_init_hw(int is_dual, int is_dio, unsigned int cs)
+static void zynq_qspi_init_hw(struct zynq_qspi_priv *priv)
 {
        u32 config_reg;
+       struct zynq_qspi_regs *regs = priv->regs;
 
-       writel(~ZYNQ_QSPI_ENABLE_ENABLE_MASK, &zynq_qspi_base->enbr);
-       writel(0x7F, &zynq_qspi_base->idisr);
+       writel(~ZYNQ_QSPI_ENABLE_ENABLE_MASK, &regs->enbr);
+       writel(0x7F, &regs->idisr);
 
        /* Disable linear mode as the boot loader may have used it */
-       writel(0x0, &zynq_qspi_base->lcr);
+       writel(0x0, &regs->lcr);
 
        /* Clear the TX and RX threshold reg */
-       writel(0x1, &zynq_qspi_base->txftr);
-       writel(ZYNQ_QSPI_RXFIFO_THRESHOLD, &zynq_qspi_base->rxftr);
+       writel(0x1, &regs->txftr);
+       writel(ZYNQ_QSPI_RXFIFO_THRESHOLD, &regs->rxftr);
 
        /* Clear the RX FIFO */
-       while (readl(&zynq_qspi_base->isr) & ZYNQ_QSPI_IXR_RXNEMTY_MASK)
-               readl(&zynq_qspi_base->drxr);
+       while (readl(&regs->isr) & ZYNQ_QSPI_IXR_RXNEMTY_MASK)
+               readl(&regs->drxr);
+
+       debug("%s is_dual:0x%x, is_dio:0x%x\n", __func__, priv->is_dual, priv->is_dio);
 
-       writel(0x7F, &zynq_qspi_base->isr);
-       config_reg = readl(&zynq_qspi_base->confr);
+       writel(0x7F, &regs->isr);
+       config_reg = readl(&regs->confr);
        config_reg &= ~ZYNQ_QSPI_CONFIG_MSA_MASK;
        config_reg |= ZYNQ_QSPI_CONFIG_IFMODE_MASK |
                ZYNQ_QSPI_CONFIG_MCS_MASK | ZYNQ_QSPI_CONFIG_PCS_MASK |
                ZYNQ_QSPI_CONFIG_FW_MASK | ZYNQ_QSPI_CONFIG_MSTREN_MASK;
-       if (is_dual == SF_DUAL_STACKED_FLASH)
+       if (priv->is_dual == SF_DUAL_STACKED_FLASH)
                config_reg |= 0x10;
-       writel(config_reg, &zynq_qspi_base->confr);
+       writel(config_reg, &regs->confr);
 
-       if (is_dual == SF_DUAL_PARALLEL_FLASH) {
-               if (is_dio == SF_DUALIO_FLASH)
+       if (priv->is_dual == SF_DUAL_PARALLEL_FLASH) {
+               if (priv->is_dio == SF_DUALIO_FLASH)
                        /* Enable two memories on seperate buses */
                        writel((ZYNQ_QSPI_LCFG_TWO_MEM_MASK |
                                ZYNQ_QSPI_LCFG_SEP_BUS_MASK |
                                (1 << ZYNQ_QSPI_LCFG_DUMMY_SHIFT) |
                                ZYNQ_QSPI_FR_DUALIO_CODE),
-                               &zynq_qspi_base->lcr);
+                               &regs->lcr);
                else
                        /* Enable two memories on seperate buses */
                        writel((ZYNQ_QSPI_LCFG_TWO_MEM_MASK |
                                ZYNQ_QSPI_LCFG_SEP_BUS_MASK |
                                (1 << ZYNQ_QSPI_LCFG_DUMMY_SHIFT) |
                                ZYNQ_QSPI_FR_QOUT_CODE),
-                               &zynq_qspi_base->lcr);
-       } else if (is_dual == SF_DUAL_STACKED_FLASH) {
-               if (is_dio == SF_DUALIO_FLASH)
+                               &regs->lcr);
+       } else if (priv->is_dual == SF_DUAL_STACKED_FLASH) {
+               if (priv->is_dio == SF_DUALIO_FLASH)
                        /* Configure two memories on shared bus
                         * by enabling lower mem */
                        writel((ZYNQ_QSPI_LCFG_TWO_MEM_MASK |
                                (1 << ZYNQ_QSPI_LCFG_DUMMY_SHIFT) |
                                ZYNQ_QSPI_FR_DUALIO_CODE),
-                               &zynq_qspi_base->lcr);
+                               &regs->lcr);
                else
                        /* Configure two memories on shared bus
                         * by enabling lower mem */
                        writel((ZYNQ_QSPI_LCFG_TWO_MEM_MASK |
                                (1 << ZYNQ_QSPI_LCFG_DUMMY_SHIFT) |
                                ZYNQ_QSPI_FR_QOUT_CODE),
-                               &zynq_qspi_base->lcr);
+                               &regs->lcr);
        }
-       writel(ZYNQ_QSPI_ENABLE_ENABLE_MASK, &zynq_qspi_base->enbr);
+       writel(ZYNQ_QSPI_ENABLE_ENABLE_MASK, &regs->enbr);
+}
+
+/*
+ * zynq_qspi_check_is_dual_flash - checking for dual or single qspi
+ *
+ * This function will check the type of the flash whether it supports
+ * single or dual qspi based on the MIO configuration done by FSBL.
+ *
+ * User needs to correctly configure the MIO's based on the
+ * number of qspi flashes present on the board.
+ *
+ * function will return -1, if there is no MIO configuration for
+ * qspi flash.
+ */
+static void zynq_qspi_check_is_dual_flash(struct zynq_qspi_priv *priv)
+{
+       int lower_mio = 0, upper_mio = 0, upper_mio_cs1 = 0;
+
+       priv->is_dual = -1;
+       priv->is_dio = 0;
+       lower_mio = zynq_slcr_get_mio_pin_status("qspi0");
+       if (lower_mio == ZYNQ_QSPI_MIO_NUM_QSPI0) {
+               priv->is_dual = SF_SINGLE_FLASH;
+       } else {
+               lower_mio = zynq_slcr_get_mio_pin_status("qspi0_dio");
+               if (lower_mio == ZYNQ_QSPI_MIO_NUM_QSPI0_DIO) {
+                       debug("QSPI in Single 2-bit\n");
+                       priv->is_dio = SF_DUALIO_FLASH;
+                       priv->is_dual = SF_SINGLE_FLASH;
+               }
+       }
+
+       if (priv->is_dio != SF_DUALIO_FLASH) {
+               upper_mio_cs1 = zynq_slcr_get_mio_pin_status("qspi1_cs");
+               if ((lower_mio == ZYNQ_QSPI_MIO_NUM_QSPI0) &&
+                   (upper_mio_cs1 == ZYNQ_QSPI_MIO_NUM_QSPI1_CS))
+                       priv->is_dual = SF_DUAL_STACKED_FLASH;
+
+               upper_mio = zynq_slcr_get_mio_pin_status("qspi1");
+               if ((lower_mio == ZYNQ_QSPI_MIO_NUM_QSPI0) &&
+                   (upper_mio_cs1 == ZYNQ_QSPI_MIO_NUM_QSPI1_CS) &&
+                   (upper_mio == ZYNQ_QSPI_MIO_NUM_QSPI1))
+                       priv->is_dual = SF_DUAL_PARALLEL_FLASH;
+       } else {
+               upper_mio_cs1 = zynq_slcr_get_mio_pin_status("qspi1_cs_dio");
+               if ((lower_mio == ZYNQ_QSPI_MIO_NUM_QSPI0_DIO) &&
+                   (upper_mio_cs1 == ZYNQ_QSPI_MIO_NUM_QSPI1_CS_DIO)) {
+                       debug("QSPI in DualStacked 2-bit\n");
+                       priv->is_dual = SF_DUAL_STACKED_FLASH;
+               }
+               upper_mio = zynq_slcr_get_mio_pin_status("qspi1_dio");
+               if ((lower_mio == ZYNQ_QSPI_MIO_NUM_QSPI0_DIO) &&
+                   (upper_mio_cs1 == ZYNQ_QSPI_MIO_NUM_QSPI1_CS_DIO) &&
+                   (upper_mio == ZYNQ_QSPI_MIO_NUM_QSPI1_DIO)) {
+                       debug("QSPI in DualParallel 2-bit\n");
+                       priv->is_dual = SF_DUAL_PARALLEL_FLASH;
+               }
+       }
+}
+
+static int zynq_qspi_child_pre_probe(struct udevice *bus)
+{
+       struct spi_slave *slave = dev_get_parentdata(bus);
+       struct zynq_qspi_priv *priv = dev_get_priv(bus->parent);
+
+       slave->option = priv->is_dual;
+       slave->dio = priv->is_dio;
+       slave->op_mode_rx = SPI_OPM_RX_QOF;
+       slave->op_mode_tx = SPI_OPM_TX_QPP;
+
+       return 0;
+}
+
+static int zynq_qspi_probe(struct udevice *bus)
+{
+       struct zynq_qspi_platdata *plat = dev_get_platdata(bus);
+       struct zynq_qspi_priv *priv = dev_get_priv(bus);
+
+       debug("zynq_qspi_probe:  bus:%p, priv:%p \n", bus, priv);
+
+       priv->regs = plat->regs;
+       zynq_qspi_check_is_dual_flash(priv);
+
+       if (priv->is_dual == -1) {
+               debug("%s: No QSPI device detected based on MIO settings\n",
+                     __func__);
+               return -1;
+       }
+
+       /* init the zynq spi hw */
+       zynq_qspi_init_hw(priv);
+
+       return 0;
+}
+
+static int zynq_qspi_set_speed(struct udevice *bus, uint speed)
+{
+       struct zynq_qspi_platdata *plat = bus->platdata;
+       struct zynq_qspi_priv *priv = dev_get_priv(bus);
+       struct zynq_qspi_regs *regs = priv->regs;
+       uint32_t confr;
+       u8 baud_rate_val = 0;
+
+       debug("%s\n", __func__);
+       if (speed > plat->frequency)
+               speed = plat->frequency;
+
+       /* Set the clock frequency */
+       confr = readl(&regs->confr);
+       if (speed == 0) {
+               /* Set baudrate x8, if the freq is 0 */
+               baud_rate_val = 0x2;
+       } else if (plat->speed_hz != speed) {
+               while ((baud_rate_val < 8) &&
+                      ((plat->frequency /
+                      (2 << baud_rate_val)) > speed))
+                       baud_rate_val++;
+
+               plat->speed_hz = speed / (2 << baud_rate_val);
+       }
+       confr &= ~ZYNQ_QSPI_CONFIG_BAUD_DIV_MASK;
+       confr |= (baud_rate_val << 3);
+
+       writel(confr, &regs->confr);
+       priv->freq = speed;
+
+       debug("zynq_spi_set_speed: regs=%p, mode=%d\n", priv->regs, priv->freq);
+
+       return 0;
+}
+
+static int zynq_qspi_set_mode(struct udevice *bus, uint mode)
+{
+       struct zynq_qspi_priv *priv = dev_get_priv(bus);
+       struct zynq_qspi_regs *regs = priv->regs;
+       uint32_t confr;
+
+       debug("%s\n", __func__);
+       /* Set the SPI Clock phase and polarities */
+       confr = readl(&regs->confr);
+       confr &= ~(ZYNQ_QSPI_CONFIG_CPHA_MASK | ZYNQ_QSPI_CONFIG_CPOL_MASK);
+
+       if (priv->mode & SPI_CPHA)
+               confr |= ZYNQ_QSPI_CONFIG_CPHA_MASK;
+       if (priv->mode & SPI_CPOL)
+               confr |= ZYNQ_QSPI_CONFIG_CPOL_MASK;
+
+       writel(confr, &regs->confr);
+       priv->mode = mode;
+
+       debug("zynq_spi_set_mode: regs=%p, mode=%d\n", priv->regs, priv->mode);
+
+       return 0;
 }
 
 /*
@@ -248,43 +404,43 @@ static void zynq_qspi_init_hw(int is_dual, int is_dio, unsigned int cs)
  * @data:      The 32 bit variable where data is stored
  * @size:      Number of bytes to be copied from data to RX buffer
  */
-static void zynq_qspi_copy_read_data(struct zynq_qspi *zqspi, u32 data, u8 size)
+static void zynq_qspi_copy_read_data(struct zynq_qspi_priv *priv, u32 data, u8 size)
 {
        u8 byte3;
 
        debug("%s: data 0x%04x rxbuf addr: 0x%08x size %d\n", __func__ ,
-             data, (unsigned)(zqspi->rxbuf), size);
+             data, (unsigned)(priv->rxbuf), size);
 
-       if (zqspi->rxbuf) {
+       if (priv->rxbuf) {
                switch (size) {
                case 1:
-                       *((u8 *)zqspi->rxbuf) = data;
-                       zqspi->rxbuf += 1;
+                       *((u8 *)priv->rxbuf) = data;
+                       priv->rxbuf += 1;
                        break;
                case 2:
-                       *((u16 *)zqspi->rxbuf) = data;
-                       zqspi->rxbuf += 2;
+                       *((u16 *)priv->rxbuf) = data;
+                       priv->rxbuf += 2;
                        break;
                case 3:
-                       *((u16 *)zqspi->rxbuf) = data;
-                       zqspi->rxbuf += 2;
+                       *((u16 *)priv->rxbuf) = data;
+                       priv->rxbuf += 2;
                        byte3 = (u8)(data >> 16);
-                       *((u8 *)zqspi->rxbuf) = byte3;
-                       zqspi->rxbuf += 1;
+                       *((u8 *)priv->rxbuf) = byte3;
+                       priv->rxbuf += 1;
                        break;
                case 4:
                        /* Can not assume word aligned buffer */
-                       memcpy(zqspi->rxbuf, &data, size);
-                       zqspi->rxbuf += 4;
+                       memcpy(priv->rxbuf, &data, size);
+                       priv->rxbuf += 4;
                        break;
                default:
                        /* This will never execute */
                        break;
                }
        }
-       zqspi->bytes_to_receive -= size;
-       if (zqspi->bytes_to_receive < 0)
-               zqspi->bytes_to_receive = 0;
+       priv->bytes_to_receive -= size;
+       if (priv->bytes_to_receive < 0)
+               priv->bytes_to_receive = 0;
 }
 
 /*
@@ -293,32 +449,32 @@ static void zynq_qspi_copy_read_data(struct zynq_qspi *zqspi, u32 data, u8 size)
  * @data:      Pointer to the 32 bit variable where data is to be copied
  * @size:      Number of bytes to be copied from TX buffer to data
  */
-static void zynq_qspi_copy_write_data(struct zynq_qspi *zqspi,
+static void zynq_qspi_copy_write_data(struct  zynq_qspi_priv *priv,
                u32 *data, u8 size)
 {
-       if (zqspi->txbuf) {
+       if (priv->txbuf) {
                switch (size) {
                case 1:
-                       *data = *((u8 *)zqspi->txbuf);
-                       zqspi->txbuf += 1;
+                       *data = *((u8 *)priv->txbuf);
+                       priv->txbuf += 1;
                        *data |= 0xFFFFFF00;
                        break;
                case 2:
-                       *data = *((u16 *)zqspi->txbuf);
-                       zqspi->txbuf += 2;
+                       *data = *((u16 *)priv->txbuf);
+                       priv->txbuf += 2;
                        *data |= 0xFFFF0000;
                        break;
                case 3:
-                       *data = *((u16 *)zqspi->txbuf);
-                       zqspi->txbuf += 2;
-                       *data |= (*((u8 *)zqspi->txbuf) << 16);
-                       zqspi->txbuf += 1;
+                       *data = *((u16 *)priv->txbuf);
+                       priv->txbuf += 2;
+                       *data |= (*((u8 *)priv->txbuf) << 16);
+                       priv->txbuf += 1;
                        *data |= 0xFF000000;
                        break;
                case 4:
                        /* Can not assume word aligned buffer */
-                       memcpy(data, zqspi->txbuf, size);
-                       zqspi->txbuf += 4;
+                       memcpy(data, priv->txbuf, size);
+                       priv->txbuf += 4;
                        break;
                default:
                        /* This will never execute */
@@ -329,11 +485,11 @@ static void zynq_qspi_copy_write_data(struct zynq_qspi *zqspi,
        }
 
        debug("%s: data 0x%08x txbuf addr: 0x%08x size %d\n", __func__,
-             *data, (u32)zqspi->txbuf, size);
+             *data, (u32)priv->txbuf, size);
 
-       zqspi->bytes_to_transfer -= size;
-       if (zqspi->bytes_to_transfer < 0)
-               zqspi->bytes_to_transfer = 0;
+       priv->bytes_to_transfer -= size;
+       if (priv->bytes_to_transfer < 0)
+               priv->bytes_to_transfer = 0;
 }
 
 /*
@@ -341,134 +497,63 @@ static void zynq_qspi_copy_write_data(struct zynq_qspi *zqspi,
  * @qspi:      Pointer to the spi_device structure
  * @is_on:     Select(1) or deselect (0) the chip select line
  */
-static void zynq_qspi_chipselect(struct spi_device *qspi, int is_on)
+static void zynq_qspi_chipselect(struct  zynq_qspi_priv *priv, int is_on)
 {
        u32 config_reg;
+       struct zynq_qspi_regs *regs = priv->regs;
 
        debug("%s: is_on: %d\n", __func__, is_on);
 
-       config_reg = readl(&zynq_qspi_base->confr);
+       config_reg = readl(&regs->confr);
 
        if (is_on) {
                /* Select the slave */
                config_reg &= ~ZYNQ_QSPI_CONFIG_SSCTRL_MASK;
-               config_reg |= (((~(0x0001 << qspi->chip_select)) << 10) &
+               config_reg |= (((~(0x0001 << 0)) << 10) &
                                ZYNQ_QSPI_CONFIG_SSCTRL_MASK);
        } else
                /* Deselect the slave */
                config_reg |= ZYNQ_QSPI_CONFIG_SSCTRL_MASK;
 
-       writel(config_reg, &zynq_qspi_base->confr);
-}
-
-/*
- * zynq_qspi_setup_transfer - Configure QSPI controller for specified transfer
- * @qspi:      Pointer to the spi_device structure
- * @transfer:  Pointer to the spi_transfer structure which provides information
- *             about next transfer setup parameters
- *
- * Sets the operational mode of QSPI controller for the next QSPI transfer and
- * sets the requested clock frequency.
- *
- * returns:    0 on success and -1 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_setup_transfer(struct spi_device *qspi,
-               struct spi_transfer *transfer)
-{
-       struct zynq_qspi *zqspi = &qspi->master;
-       u8 bits_per_word;
-       u32 config_reg;
-       u32 req_hz;
-       u32 baud_rate_val = 0;
-
-       debug("%s: qspi: 0x%08x transfer: 0x%08x\n", __func__,
-             (u32)qspi, (u32)transfer);
-
-       bits_per_word = (transfer) ?
-                       transfer->bits_per_word : qspi->bits_per_word;
-       req_hz = (transfer) ? transfer->speed_hz : qspi->max_speed_hz;
-
-       if (qspi->mode & ~MODEBITS) {
-               printf("%s: Unsupported mode bits %x\n",
-                      __func__, qspi->mode & ~MODEBITS);
-               return -1;
-       }
-
-       if (bits_per_word != 32)
-               bits_per_word = 32;
-
-       config_reg = readl(&zynq_qspi_base->confr);
-
-       /* Set the QSPI clock phase and clock polarity */
-       config_reg &= (~ZYNQ_QSPI_CONFIG_CPHA_MASK) &
-                               (~ZYNQ_QSPI_CONFIG_CPOL_MASK);
-       if (qspi->mode & SPI_CPHA)
-               config_reg |= ZYNQ_QSPI_CONFIG_CPHA_MASK;
-       if (qspi->mode & SPI_CPOL)
-               config_reg |= ZYNQ_QSPI_CONFIG_CPOL_MASK;
-
-       /* Set the clock frequency */
-       if (zqspi->speed_hz != req_hz) {
-               baud_rate_val = 0;
-               while ((baud_rate_val < 7) &&
-                       (zqspi->input_clk_hz / (2 << baud_rate_val)) > req_hz) {
-                               baud_rate_val++;
-               }
-               config_reg &= 0xFFFFFFC7;
-               config_reg |= (baud_rate_val << 3);
-               zqspi->speed_hz = req_hz;
-       }
-
-       writel(config_reg, &zynq_qspi_base->confr);
-
-       debug("%s: mode %d, %u bits/w, %u clock speed\n", __func__,
-             qspi->mode & MODEBITS, qspi->bits_per_word, zqspi->speed_hz);
-
-       return 0;
+       writel(config_reg, &regs->confr);
 }
 
 /*
  * zynq_qspi_fill_tx_fifo - Fills the TX FIFO with as many bytes as possible
  * @zqspi:     Pointer to the zynq_qspi structure
  */
-static void zynq_qspi_fill_tx_fifo(struct zynq_qspi *zqspi, u32 size)
+static void zynq_qspi_fill_tx_fifo(struct zynq_qspi_priv *priv, u32 size)
 {
        u32 data = 0;
        u32 fifocount = 0;
        unsigned len, offset;
+       struct zynq_qspi_regs *regs = priv->regs;
        static const unsigned offsets[4] = {
                ZYNQ_QSPI_TXD_00_00_OFFSET, ZYNQ_QSPI_TXD_00_01_OFFSET,
                ZYNQ_QSPI_TXD_00_10_OFFSET, ZYNQ_QSPI_TXD_00_11_OFFSET };
 
        while ((fifocount < size) &&
-                       (zqspi->bytes_to_transfer > 0)) {
-               if (zqspi->bytes_to_transfer >= 4) {
-                       if (zqspi->txbuf) {
-                               memcpy(&data, zqspi->txbuf, 4);
-                               zqspi->txbuf += 4;
+                       (priv->bytes_to_transfer > 0)) {
+               if (priv->bytes_to_transfer >= 4) {
+                       if (priv->txbuf) {
+                               memcpy(&data, priv->txbuf, 4);
+                               priv->txbuf += 4;
                        } else {
                                data = 0;
                        }
-                       writel(data, &zynq_qspi_base->txd0r);
-                       zqspi->bytes_to_transfer -= 4;
+                       writel(data, &regs->txd0r);
+                       priv->bytes_to_transfer -= 4;
                        fifocount++;
                } else {
                        /* Write TXD1, TXD2, TXD3 only if TxFIFO is empty. */
-                       if (!(readl(&zynq_qspi_base->isr)
+                       if (!(readl(&regs->isr)
                                        & ZYNQ_QSPI_IXR_TXNFULL_MASK) &&
-                                       !zqspi->rxbuf)
+                                       !priv->rxbuf)
                                return;
-                       len = zqspi->bytes_to_transfer;
-                       zynq_qspi_copy_write_data(zqspi, &data, len);
-                       offset = (zqspi->rxbuf) ? offsets[0] : offsets[len];
-                       writel(data, &zynq_qspi_base->confr + (offset / 4));
+                       len = priv->bytes_to_transfer;
+                       zynq_qspi_copy_write_data(priv, &data, len);
+                       offset = (priv->rxbuf) ? offsets[0] : offsets[len];
+                       writel(data, &regs->confr + (offset / 4));
                }
        }
 }
@@ -487,31 +572,32 @@ static void zynq_qspi_fill_tx_fifo(struct zynq_qspi *zqspi, u32 size)
  * returns:    0 for poll timeout
  *             1 transfer operation complete
  */
-static int zynq_qspi_irq_poll(struct zynq_qspi *zqspi)
+static int zynq_qspi_irq_poll(struct zynq_qspi_priv *priv)
 {
        int max_loop;
        u32 intr_status;
        u32 rxindex = 0;
        u32 rxcount;
+       struct zynq_qspi_regs *regs = priv->regs;
 
-       debug("%s: zqspi: 0x%08x\n", __func__, (u32)zqspi);
+       debug("%s: zqspi: 0x%08x\n", __func__, (u32)priv);
 
        /* Poll until any of the interrupt status bits are set */
        max_loop = 0;
        do {
-               intr_status = readl(&zynq_qspi_base->isr);
+               intr_status = readl(&regs->isr);
                max_loop++;
        } while ((intr_status == 0) && (max_loop < 100000));
 
        if (intr_status == 0) {
-               printf("%s: Timeout\n", __func__);
+               debug("%s: Timeout\n", __func__);
                return 0;
        }
 
-       writel(intr_status, &zynq_qspi_base->isr);
+       writel(intr_status, &regs->isr);
 
        /* Disable all interrupts */
-       writel(ZYNQ_QSPI_IXR_ALL_MASK, &zynq_qspi_base->idisr);
+       writel(ZYNQ_QSPI_IXR_ALL_MASK, &regs->idisr);
        if ((intr_status & ZYNQ_QSPI_IXR_TXNFULL_MASK) ||
            (intr_status & ZYNQ_QSPI_IXR_RXNEMTY_MASK)) {
                /*
@@ -519,42 +605,42 @@ static int zynq_qspi_irq_poll(struct zynq_qspi *zqspi)
                 * the THRESHOLD value set to 1, so this bit indicates Tx FIFO
                 * is empty
                 */
-               rxcount = zqspi->bytes_to_receive - zqspi->bytes_to_transfer;
+               rxcount = priv->bytes_to_receive - priv->bytes_to_transfer;
                rxcount = (rxcount % 4) ? ((rxcount/4)+1) : (rxcount/4);
                while ((rxindex < rxcount) &&
                                (rxindex < ZYNQ_QSPI_RXFIFO_THRESHOLD)) {
                        /* Read out the data from the RX FIFO */
                        u32 data;
-                       data = readl(&zynq_qspi_base->drxr);
+                       data = readl(&regs->drxr);
 
-                       if (zqspi->bytes_to_receive >= 4) {
-                               if (zqspi->rxbuf) {
-                                       memcpy(zqspi->rxbuf, &data, 4);
-                                       zqspi->rxbuf += 4;
+                       if (priv->bytes_to_receive >= 4) {
+                               if (priv->rxbuf) {
+                                       memcpy(priv->rxbuf, &data, 4);
+                                       priv->rxbuf += 4;
                                }
-                               zqspi->bytes_to_receive -= 4;
+                               priv->bytes_to_receive -= 4;
                        } else {
-                               zynq_qspi_copy_read_data(zqspi, data,
-                                       zqspi->bytes_to_receive);
+                               zynq_qspi_copy_read_data(priv, data,
+                                       priv->bytes_to_receive);
                        }
                        rxindex++;
                }
 
-               if (zqspi->bytes_to_transfer) {
+               if (priv->bytes_to_transfer) {
                        /* There is more data to send */
-                       zynq_qspi_fill_tx_fifo(zqspi,
+                       zynq_qspi_fill_tx_fifo(priv,
                                               ZYNQ_QSPI_RXFIFO_THRESHOLD);
 
-                       writel(ZYNQ_QSPI_IXR_ALL_MASK, &zynq_qspi_base->ier);
+                       writel(ZYNQ_QSPI_IXR_ALL_MASK, &regs->ier);
                } else {
                        /*
                         * If transfer and receive is completed then only send
                         * complete signal
                         */
-                       if (!zqspi->bytes_to_receive) {
+                       if (!priv->bytes_to_receive) {
                                /* return operation complete */
                                writel(ZYNQ_QSPI_IXR_ALL_MASK,
-                                      &zynq_qspi_base->idisr);
+                                      &regs->idisr);
                                return 1;
                        }
                }
@@ -574,30 +660,27 @@ static int zynq_qspi_irq_poll(struct zynq_qspi *zqspi)
  *
  * returns:    Number of bytes transferred in the last transfer
  */
-static int zynq_qspi_start_transfer(struct spi_device *qspi,
-                       struct spi_transfer *transfer)
+static int zynq_qspi_start_transfer(struct zynq_qspi_priv *priv)
 {
-       struct zynq_qspi *zqspi = &qspi->master;
        static u8 current_u_page;
        u32 data = 0;
+       struct zynq_qspi_regs *regs = priv->regs;
 
        debug("%s: qspi: 0x%08x transfer: 0x%08x len: %d\n", __func__,
-             (u32)qspi, (u32)transfer, transfer->len);
+             (u32)priv, (u32)priv, priv->len);
 
-       zqspi->txbuf = transfer->tx_buf;
-       zqspi->rxbuf = transfer->rx_buf;
-       zqspi->bytes_to_transfer = transfer->len;
-       zqspi->bytes_to_receive = transfer->len;
+       priv->bytes_to_transfer = priv->len;
+       priv->bytes_to_receive = priv->len;
 
-       if (zqspi->is_inst && (zqspi->is_dual == SF_DUAL_STACKED_FLASH) &&
-           (current_u_page != zqspi->u_page)) {
-               if (zqspi->u_page) {
-                       if (zqspi->is_dio == SF_DUALIO_FLASH)
+       if (priv->is_inst && (priv->is_dual == SF_DUAL_STACKED_FLASH) &&
+           (current_u_page != priv->u_page)) {
+               if (priv->u_page) {
+                       if (priv->is_dio == SF_DUALIO_FLASH)
                                writel((ZYNQ_QSPI_LCFG_TWO_MEM_MASK |
                                        ZYNQ_QSPI_LCFG_U_PAGE |
                                        (1 << ZYNQ_QSPI_LCFG_DUMMY_SHIFT) |
                                        ZYNQ_QSPI_FR_DUALIO_CODE),
-                                       &zynq_qspi_base->lcr);
+                                       &regs->lcr);
                        else
                                /* Configure two memories on shared bus
                                 * by enabling upper mem
@@ -606,13 +689,13 @@ static int zynq_qspi_start_transfer(struct spi_device *qspi,
                                        ZYNQ_QSPI_LCFG_U_PAGE |
                                        (1 << ZYNQ_QSPI_LCFG_DUMMY_SHIFT) |
                                        ZYNQ_QSPI_FR_QOUT_CODE),
-                                       &zynq_qspi_base->lcr);
+                                       &regs->lcr);
                } else {
-                       if (zqspi->is_dio == SF_DUALIO_FLASH)
+                       if (priv->is_dio == SF_DUALIO_FLASH)
                                writel((ZYNQ_QSPI_LCFG_TWO_MEM_MASK |
                                        (1 << ZYNQ_QSPI_LCFG_DUMMY_SHIFT) |
                                        ZYNQ_QSPI_FR_DUALIO_CODE),
-                                       &zynq_qspi_base->lcr);
+                                       &regs->lcr);
                        else
                                /* Configure two memories on shared bus
                                 * by enabling lower mem
@@ -620,252 +703,109 @@ static int zynq_qspi_start_transfer(struct spi_device *qspi,
                                writel((ZYNQ_QSPI_LCFG_TWO_MEM_MASK |
                                        (1 << ZYNQ_QSPI_LCFG_DUMMY_SHIFT) |
                                        ZYNQ_QSPI_FR_QOUT_CODE),
-                                       &zynq_qspi_base->lcr);
+                                       &regs->lcr);
                }
-               current_u_page = zqspi->u_page;
+               current_u_page = priv->u_page;
        }
 
-       if (transfer->len < 4)
-               zynq_qspi_fill_tx_fifo(zqspi, transfer->len);
+       if (priv->len < 4)
+               zynq_qspi_fill_tx_fifo(priv, priv->len);
        else
-               zynq_qspi_fill_tx_fifo(zqspi, ZYNQ_QSPI_FIFO_DEPTH);
+               zynq_qspi_fill_tx_fifo(priv, ZYNQ_QSPI_FIFO_DEPTH);
 
-       writel(ZYNQ_QSPI_IXR_ALL_MASK, &zynq_qspi_base->ier);
+       writel(ZYNQ_QSPI_IXR_ALL_MASK, &regs->ier);
        /* Start the transfer by enabling manual start bit */
 
        /* wait for completion */
        do {
-               data = zynq_qspi_irq_poll(zqspi);
+               data = zynq_qspi_irq_poll(priv);
        } while (data == 0);
 
-       return (transfer->len) - (zqspi->bytes_to_transfer);
+       return (priv->len) - (priv->bytes_to_transfer);
 }
 
-static int zynq_qspi_transfer(struct spi_device *qspi,
-               struct spi_transfer *transfer)
+static int zynq_qspi_transfer(struct zynq_qspi_priv *priv)
 {
-       struct zynq_qspi *zqspi = &qspi->master;
        unsigned cs_change = 1;
        int status = 0;
 
        debug("%s\n", __func__);
 
        while (1) {
-               if (transfer->bits_per_word || transfer->speed_hz) {
-                       status = zynq_qspi_setup_transfer(qspi, transfer);
-                       if (status < 0)
-                               break;
-               }
 
                /* Select the chip if required */
                if (cs_change)
-                       zynq_qspi_chipselect(qspi, 1);
+                       zynq_qspi_chipselect(priv, 1);
 
-               cs_change = transfer->cs_change;
+               cs_change = priv->cs_change;
 
-               if (!transfer->tx_buf && !transfer->rx_buf && transfer->len) {
+               if (!priv->txbuf && !priv->rxbuf && priv->len) {
                        status = -1;
                        break;
                }
 
                /* Request the transfer */
-               if (transfer->len) {
-                       status = zynq_qspi_start_transfer(qspi, transfer);
-                       zqspi->is_inst = 0;
+               if (priv->len) {
+                       status = zynq_qspi_start_transfer(priv);
+                       priv->is_inst = 0;
                }
 
-               if (status != transfer->len) {
+               if (status != priv->len) {
                        if (status > 0)
                                status = -EMSGSIZE;
+                       debug("zynq_qspi_transfer:%d len:%d\n", status, priv->len);
                        break;
                }
                status = 0;
 
-               if (transfer->delay_usecs)
-                       udelay(transfer->delay_usecs);
-
                if (cs_change)
                        /* Deselect the chip */
-                       zynq_qspi_chipselect(qspi, 0);
+                       zynq_qspi_chipselect(priv, 0);
 
                break;
        }
 
-       zynq_qspi_setup_transfer(qspi, NULL);
-
        return 0;
 }
 
-/*
- * zynq_qspi_check_is_dual_flash - checking for dual or single qspi
- *
- * This function will check the type of the flash whether it supports
- * single or dual qspi based on the MIO configuration done by FSBL.
- *
- * User needs to correctly configure the MIO's based on the
- * number of qspi flashes present on the board.
- *
- * function will return -1, if there is no MIO configuration for
- * qspi flash.
- */
-static int zynq_qspi_check_is_dual_flash(int *is_dio)
+static int zynq_qspi_claim_bus(struct udevice *dev)
 {
-       int is_dual = -1;
-       int lower_mio = 0, upper_mio = 0, upper_mio_cs1 = 0;
+       struct udevice *bus = dev->parent;
+       struct zynq_qspi_priv *priv = dev_get_priv(bus);
+       struct zynq_qspi_regs *regs = priv->regs;
 
-       lower_mio = zynq_slcr_get_mio_pin_status("qspi0");
-       if (lower_mio == ZYNQ_QSPI_MIO_NUM_QSPI0) {
-               is_dual = SF_SINGLE_FLASH;
-       } else {
-               lower_mio = zynq_slcr_get_mio_pin_status("qspi0_dio");
-               if (lower_mio == ZYNQ_QSPI_MIO_NUM_QSPI0_DIO) {
-                       debug("QSPI in Single 2-bit\n");
-                       *is_dio = SF_DUALIO_FLASH;
-                       is_dual = SF_SINGLE_FLASH;
-               }
-       }
-
-       if (*is_dio != SF_DUALIO_FLASH) {
-               upper_mio_cs1 = zynq_slcr_get_mio_pin_status("qspi1_cs");
-               if ((lower_mio == ZYNQ_QSPI_MIO_NUM_QSPI0) &&
-                   (upper_mio_cs1 == ZYNQ_QSPI_MIO_NUM_QSPI1_CS))
-                       is_dual = SF_DUAL_STACKED_FLASH;
-
-               upper_mio = zynq_slcr_get_mio_pin_status("qspi1");
-               if ((lower_mio == ZYNQ_QSPI_MIO_NUM_QSPI0) &&
-                   (upper_mio_cs1 == ZYNQ_QSPI_MIO_NUM_QSPI1_CS) &&
-                   (upper_mio == ZYNQ_QSPI_MIO_NUM_QSPI1))
-                       is_dual = SF_DUAL_PARALLEL_FLASH;
-       } else {
-               upper_mio_cs1 = zynq_slcr_get_mio_pin_status("qspi1_cs_dio");
-               if ((lower_mio == ZYNQ_QSPI_MIO_NUM_QSPI0_DIO) &&
-                   (upper_mio_cs1 == ZYNQ_QSPI_MIO_NUM_QSPI1_CS_DIO)) {
-                       debug("QSPI in DualStacked 2-bit\n");
-                       is_dual = SF_DUAL_STACKED_FLASH;
-               }
-               upper_mio = zynq_slcr_get_mio_pin_status("qspi1_dio");
-               if ((lower_mio == ZYNQ_QSPI_MIO_NUM_QSPI0_DIO) &&
-                   (upper_mio_cs1 == ZYNQ_QSPI_MIO_NUM_QSPI1_CS_DIO) &&
-                   (upper_mio == ZYNQ_QSPI_MIO_NUM_QSPI1_DIO)) {
-                       debug("QSPI in DualParallel 2-bit\n");
-                       is_dual = SF_DUAL_PARALLEL_FLASH;
-               }
-       }
-
-       return is_dual;
-}
-
-int spi_cs_is_valid(unsigned int bus, unsigned int cs)
-{
-       /* 1 bus with 2 chipselect */
-       return bus == 0 && cs < 2;
-}
-
-void spi_cs_activate(struct spi_slave *slave)
-{
-       debug("%s: slave 0x%08x\n", __func__, (unsigned)slave);
-}
-
-void spi_cs_deactivate(struct spi_slave *slave)
-{
-       debug("%s: slave 0x%08x\n", __func__, (unsigned)slave);
-}
-
-void spi_init()
-{
        debug("%s\n", __func__);
-}
-
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
-               unsigned int max_hz, unsigned int mode)
-{
-       int is_dual;
-       int is_dio = 0;
-       unsigned int lqspi_frequency;
-       struct zynq_qspi_slave *qspi;
-
-       debug("%s: bus: %d cs: %d max_hz: %d mode: %d\n",
-             __func__, bus, cs, max_hz, mode);
-
-       if (!spi_cs_is_valid(bus, cs))
-               return NULL;
-
-       is_dual = zynq_qspi_check_is_dual_flash(&is_dio);
-
-       if (is_dual == -1) {
-               printf("%s: No QSPI device detected based on MIO settings\n",
-                      __func__);
-               return NULL;
-       }
-
-       zynq_qspi_init_hw(is_dual, is_dio, cs);
+       writel(ZYNQ_QSPI_ENABLE_ENABLE_MASK, &regs->enbr);
 
-       qspi = spi_alloc_slave(struct zynq_qspi_slave, bus, cs);
-       if (!qspi) {
-               printf("%s: Fail to allocate zynq_qspi_slave\n", __func__);
-               return NULL;
-       }
-
-       lqspi_frequency = zynq_clk_get_rate(lqspi_clk);
-       if (!lqspi_frequency) {
-               debug("Defaulting to 200000000 Hz qspi clk");
-               qspi->qspi.master.input_clk_hz = 200000000;
-       } else {
-               qspi->qspi.master.input_clk_hz = lqspi_frequency;
-               debug("Qspi clk frequency set to %d Hz\n", lqspi_frequency);
-       }
-
-       qspi->slave.option = is_dual;
-       qspi->slave.dio = is_dio;
-       qspi->slave.op_mode_rx = SPI_OPM_RX_QOF;
-       qspi->slave.op_mode_tx = SPI_OPM_TX_QPP;
-       lqspi_frequency = qspi->qspi.master.input_clk_hz / 2;
-       qspi->qspi.max_speed_hz = min(max_hz, lqspi_frequency);
-       qspi->qspi.master.is_dio = is_dio;
-       qspi->qspi.master.is_dual = is_dual;
-       qspi->qspi.mode = mode;
-       qspi->qspi.chip_select = 0;
-       qspi->qspi.bits_per_word = 32;
-       zynq_qspi_setup_transfer(&qspi->qspi, NULL);
-
-       return &qspi->slave;
+       return 0;
 }
 
-void spi_free_slave(struct spi_slave *slave)
+static int zynq_qspi_release_bus(struct udevice *dev)
 {
-       struct zynq_qspi_slave *qspi;
-
-       debug("%s: slave: 0x%08x\n", __func__, (u32)slave);
+       struct udevice *bus = dev->parent;
+       struct zynq_qspi_priv *priv = dev_get_priv(bus);
+       struct zynq_qspi_regs *regs = priv->regs;
 
-       qspi = to_zynq_qspi_slave(slave);
-       free(qspi);
-}
+       debug("%s\n", __func__);
+       writel(~ZYNQ_QSPI_ENABLE_ENABLE_MASK, &regs->enbr);
 
-int spi_claim_bus(struct spi_slave *slave)
-{
-       debug("%s: slave: 0x%08x\n", __func__, (u32)slave);
        return 0;
 }
 
-void spi_release_bus(struct spi_slave *slave)
-{
-       debug("%s: slave: 0x%08x\n", __func__, (u32)slave);
-}
-
-int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
+static int zynq_qspi_xfer(struct udevice *dev, unsigned int bitlen, const void *dout,
                void *din, unsigned long flags)
 {
-       struct zynq_qspi_slave *qspi;
-       struct spi_transfer transfer;
+       struct udevice *bus = dev->parent;
+       struct zynq_qspi_priv *priv = dev_get_priv(bus);
 
+       debug("%s", __func__);
        debug("%s: slave: 0x%08x bitlen: %d dout: 0x%08x ", __func__,
-             (u32)slave, bitlen, (u32)dout);
+             (u32)priv, bitlen, (u32)dout);
        debug("din: 0x%08x flags: 0x%lx\n", (u32)din, flags);
 
-       qspi = (struct zynq_qspi_slave *)slave;
-       transfer.tx_buf = dout;
-       transfer.rx_buf = din;
-       transfer.len = bitlen / 8;
+       priv->txbuf = dout;
+       priv->rxbuf = din;
+       priv->len = bitlen / 8;
 
        /*
         * Festering sore.
@@ -873,25 +813,46 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
         * transmit must contain a device command.
         */
        if (dout && flags & SPI_XFER_BEGIN)
-               qspi->qspi.master.is_inst = 1;
+               priv->is_inst = 1;
        else
-               qspi->qspi.master.is_inst = 0;
+               priv->is_inst = 0;
 
        if (flags & SPI_XFER_END)
-               transfer.cs_change = 1;
+               priv->cs_change = 1;
        else
-               transfer.cs_change = 0;
+               priv->cs_change = 0;
 
        if (flags & SPI_XFER_U_PAGE)
-               qspi->qspi.master.u_page = 1;
+               priv->u_page = 1;
        else
-               qspi->qspi.master.u_page = 0;
-
-       transfer.delay_usecs = 0;
-       transfer.bits_per_word = 32;
-       transfer.speed_hz = qspi->qspi.max_speed_hz;
+               priv->u_page = 0;
 
-       zynq_qspi_transfer(&qspi->qspi, &transfer);
+       zynq_qspi_transfer(priv);
 
        return 0;
 }
+
+static const struct dm_spi_ops zynq_qspi_ops = {
+       .claim_bus      = zynq_qspi_claim_bus,
+       .release_bus    = zynq_qspi_release_bus,
+       .xfer           = zynq_qspi_xfer,
+       .set_speed      = zynq_qspi_set_speed,
+       .set_mode       = zynq_qspi_set_mode,
+};
+
+static const struct udevice_id zynq_qspi_ids[] = {
+       { .compatible = "xlnx,zynq-qspi-1.0" },
+       { }
+};
+
+U_BOOT_DRIVER(zynq_qspi) = {
+       .name   = "zynq_qspi",
+       .id     = UCLASS_SPI,
+       .of_match = zynq_qspi_ids,
+       .ops    = &zynq_qspi_ops,
+       .ofdata_to_platdata = zynq_qspi_ofdata_to_platdata,
+       .platdata_auto_alloc_size = sizeof(struct zynq_qspi_platdata),
+       .priv_auto_alloc_size = sizeof(struct zynq_qspi_priv),
+       .probe  = zynq_qspi_probe,
+       .child_pre_probe = zynq_qspi_child_pre_probe,
+};
index d311f475cf6e4cf480edd4f93958e37c186b69e7..3a7bfd32c6097ebaeb967379458ee0aee84c793c 100644 (file)
 # define CONFIG_CMD_FS_GENERIC
 #endif
 
-#undef CONFIG_ZYNQ_QSPI /* Temporary solution till DM is added */
 /* QSPI */
 #ifdef CONFIG_ZYNQ_QSPI
 # define CONFIG_SF_DEFAULT_SPEED       30000000
-# define CONFIG_SPI_FLASH_BAR
 # define CONFIG_SPI_FLASH_SPANSION
 # define CONFIG_SPI_FLASH_STMICRO
 # define CONFIG_SPI_FLASH_WINBOND
 #define CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR        0
 
 /* qspi mode is working fine */
+#if 0
 #ifdef CONFIG_ZYNQ_QSPI
 #define CONFIG_SPL_SPI_SUPPORT
 #define CONFIG_SPL_SPI_LOAD
 #define CONFIG_SPL_SPI_FLASH_SUPPORT
 #define CONFIG_SYS_SPI_U_BOOT_OFFS     0x100000
 #endif
+#endif
 
 #ifdef DEBUG
 #define CONFIG_SPL_RAM_DEVICE