All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/7] zynqmp_gqspi driver updates
@ 2021-01-18 12:32 Ashok Reddy Soma
  2021-01-18 12:32 ` [PATCH 1/7] spi: zynqmp_gqspi: do not round immediate_data field Ashok Reddy Soma
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Ashok Reddy Soma @ 2021-01-18 12:32 UTC (permalink / raw)
  To: u-boot

This patch series updates xilinx qspi driver with below fixes/enhancements

 - Fix rounding off issue in DMA transfers
 - Fix DMA transfers to be word aligned
 - Add support for IO mode
 - Fix write issues in QSPI single mode
 - Fix zynqmp tapdelays
 - Add Versal tapdelays
 - Update tapdelay for >100Mhz for Versal

This is resend for the people in CC, as i had trouble with my email
server earlier.



Ashok Reddy Soma (3):
  spi: zynqmp_gqspi: Add support for IO mode
  spi: zynqmp_gqspi: Fix write issues in single mode
  spi: zynqmp_gqspi: Add tap delays for Versal qspi

Siva Durga Prasad Paladugu (1):
  spi: zynqmp_gqspi: Fix tap delay values

T Karthik Reddy (1):
  spi: zynqmp_gqspi: Update tapdelay value

Wojciech Tatarski (2):
  spi: zynqmp_gqspi: do not round immediate_data field
  spi: zynqmp_gqspi: DMA transfers should be word aligned

 drivers/spi/zynqmp_gqspi.c | 230 +++++++++++++++++++++++++++++--------
 1 file changed, 180 insertions(+), 50 deletions(-)

--
2.17.1

This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

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

* [PATCH 1/7] spi: zynqmp_gqspi: do not round immediate_data field
  2021-01-18 12:32 [PATCH 0/7] zynqmp_gqspi driver updates Ashok Reddy Soma
@ 2021-01-18 12:32 ` Ashok Reddy Soma
  2021-01-18 12:32 ` [PATCH 2/7] spi: zynqmp_gqspi: DMA transfers should be word aligned Ashok Reddy Soma
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Ashok Reddy Soma @ 2021-01-18 12:32 UTC (permalink / raw)
  To: u-boot

From: Wojciech Tatarski <wtatarski@antmicro.com>

Immediate_data is 8 bit value in generic FIFO command. When fields
data_xfer=1 and exponent=0 this field specifies the absolute number of data
bytes to read into the RXFIFO. Values from range 0xfd to 0xff are rounded
up to 0x100. It causes overwriting the next bit field which is data_xfer.
According to Zynq Ultrascale TRM only DMA transfers should be word aligned.
So there is no reason to round up the immediate_data field.

Signed-off-by: Wojciech Tatarski <wtatarski@antmicro.com>
Signed-off-by: Tomasz Gorochowik <tgorochowik@antmicro.com>
Tested-by: Siva Durga Prasad Paladugu <siva.durga.paladugu@xilinx.com>
Signed-off-by: Ashok Reddy Soma <ashok.reddy.soma@xilinx.com>
---

 drivers/spi/zynqmp_gqspi.c | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/spi/zynqmp_gqspi.c b/drivers/spi/zynqmp_gqspi.c
index efcbd0557f..3e0dbb2c7b 100644
--- a/drivers/spi/zynqmp_gqspi.c
+++ b/drivers/spi/zynqmp_gqspi.c
@@ -524,7 +524,7 @@ static int zynqmp_qspi_start_dma(struct zynqmp_qspi_priv *priv,
                                 u32 gen_fifo_cmd, u32 *buf)
 {
        u32 addr;
-       u32 size, len;
+       u32 size;
        u32 actuallen = priv->len;
        int ret = 0;
        struct zynqmp_qspi_dma_regs *dma_regs = priv->dma_regs;
@@ -537,12 +537,7 @@ static int zynqmp_qspi_start_dma(struct zynqmp_qspi_priv *priv,
        flush_dcache_range(addr, addr + size);

        while (priv->len) {
-               len = zynqmp_qspi_calc_exp(priv, &gen_fifo_cmd);
-               if (!(gen_fifo_cmd & GQSPI_GFIFO_EXP_MASK) &&
-                   (len % ARCH_DMA_MINALIGN)) {
-                       gen_fifo_cmd &= ~GENMASK(7, 0);
-                       gen_fifo_cmd |= roundup(len, ARCH_DMA_MINALIGN);
-               }
+               zynqmp_qspi_calc_exp(priv, &gen_fifo_cmd);
                zynqmp_qspi_fill_gen_fifo(priv, gen_fifo_cmd);

                debug("GFIFO_CMD_RX:0x%x\n", gen_fifo_cmd);
--
2.17.1

This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

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

* [PATCH 2/7] spi: zynqmp_gqspi: DMA transfers should be word aligned
  2021-01-18 12:32 [PATCH 0/7] zynqmp_gqspi driver updates Ashok Reddy Soma
  2021-01-18 12:32 ` [PATCH 1/7] spi: zynqmp_gqspi: do not round immediate_data field Ashok Reddy Soma
@ 2021-01-18 12:32 ` Ashok Reddy Soma
  2021-01-18 12:32 ` [PATCH 3/7] spi: zynqmp_gqspi: Add support for IO mode Ashok Reddy Soma
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Ashok Reddy Soma @ 2021-01-18 12:32 UTC (permalink / raw)
  To: u-boot

From: Wojciech Tatarski <wtatarski@antmicro.com>

According to Zynq Ultrascale TRM all the data transfers are word aligned.
So there is no reason to round up size of DMA transfer to ARCH_DMA_MINALIGN
(0x40)

Signed-off-by: Wojciech Tatarski <wtatarski@antmicro.com>
Signed-off-by: Tomasz Gorochowik <tgorochowik@antmicro.com>
Tested-by: Siva Durga Prasad Paladugu <siva.durga.paladugu@xilinx.com>
Signed-off-by: Ashok Reddy Soma <ashok.reddy.soma@xilinx.com>
---

 drivers/spi/zynqmp_gqspi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/zynqmp_gqspi.c b/drivers/spi/zynqmp_gqspi.c
index 3e0dbb2c7b..81c5e2b22f 100644
--- a/drivers/spi/zynqmp_gqspi.c
+++ b/drivers/spi/zynqmp_gqspi.c
@@ -530,10 +530,10 @@ static int zynqmp_qspi_start_dma(struct zynqmp_qspi_priv *priv,
        struct zynqmp_qspi_dma_regs *dma_regs = priv->dma_regs;

        writel((unsigned long)buf, &dma_regs->dmadst);
-       writel(roundup(priv->len, ARCH_DMA_MINALIGN), &dma_regs->dmasize);
+       writel(roundup(priv->len, GQSPI_DMA_ALIGN), &dma_regs->dmasize);
        writel(GQSPI_DMA_DST_I_STS_MASK, &dma_regs->dmaier);
        addr = (unsigned long)buf;
-       size = roundup(priv->len, ARCH_DMA_MINALIGN);
+       size = roundup(priv->len, GQSPI_DMA_ALIGN);
        flush_dcache_range(addr, addr + size);

        while (priv->len) {
--
2.17.1

This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

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

* [PATCH 3/7] spi: zynqmp_gqspi: Add support for IO mode
  2021-01-18 12:32 [PATCH 0/7] zynqmp_gqspi driver updates Ashok Reddy Soma
  2021-01-18 12:32 ` [PATCH 1/7] spi: zynqmp_gqspi: do not round immediate_data field Ashok Reddy Soma
  2021-01-18 12:32 ` [PATCH 2/7] spi: zynqmp_gqspi: DMA transfers should be word aligned Ashok Reddy Soma
@ 2021-01-18 12:32 ` Ashok Reddy Soma
  2021-01-18 12:32 ` [PATCH 4/7] spi: zynqmp_gqspi: Fix tap delay values Ashok Reddy Soma
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Ashok Reddy Soma @ 2021-01-18 12:32 UTC (permalink / raw)
  To: u-boot

Add support for device tree "has-io-mode" flag.
The driver will be in IO mode when "has-io-mode" is passed from device
tree instead of DMA.

Signed-off-by: Ashok Reddy Soma <ashok.reddy.soma@xilinx.com>
---

 drivers/spi/zynqmp_gqspi.c | 140 ++++++++++++++++++++++++++++++++-----
 1 file changed, 123 insertions(+), 17 deletions(-)

diff --git a/drivers/spi/zynqmp_gqspi.c b/drivers/spi/zynqmp_gqspi.c
index 81c5e2b22f..ae7b70aa57 100644
--- a/drivers/spi/zynqmp_gqspi.c
+++ b/drivers/spi/zynqmp_gqspi.c
@@ -16,11 +16,13 @@
 #include <malloc.h>
 #include <memalign.h>
 #include <spi.h>
+#include <spi_flash.h>
 #include <ubi_uboot.h>
 #include <wait_bit.h>
 #include <dm/device_compat.h>
-#include <linux/bitops.h>
-#include <linux/err.h>
+#include <linux/mtd/spi-nor.h>
+#include "../mtd/spi/sf_internal.h"
+#include <zynqmp_firmware.h>

 #define GQSPI_GFIFO_STRT_MODE_MASK     BIT(29)
 #define GQSPI_CONFIG_MODE_EN_MASK      (3 << 30)
@@ -38,6 +40,7 @@
 #define GQSPI_IXR_TXFULL_MASK          0x00000008 /* QSPI TX FIFO is full */
 #define GQSPI_IXR_RXNEMTY_MASK         0x00000010 /* QSPI RX FIFO Not Empty */
 #define GQSPI_IXR_GFEMTY_MASK          0x00000080 /* QSPI Generic FIFO Empty */
+#define GQSPI_IXR_GFNFULL_MASK         0x00000200 /* QSPI GENFIFO not full */
 #define GQSPI_IXR_ALL_MASK             (GQSPI_IXR_TXNFULL_MASK | \
                                         GQSPI_IXR_RXNEMTY_MASK)

@@ -75,6 +78,7 @@

 #define GQSPI_GFIFO_SELECT             BIT(0)
 #define GQSPI_FIFO_THRESHOLD           1
+#define GQSPI_GENFIFO_THRESHOLD                31

 #define SPI_XFER_ON_BOTH               0
 #define SPI_XFER_ON_LOWER              1
@@ -161,6 +165,7 @@ struct zynqmp_qspi_plat {
        struct zynqmp_qspi_dma_regs *dma_regs;
        u32 frequency;
        u32 speed_hz;
+       unsigned int io_mode;
 };

 struct zynqmp_qspi_priv {
@@ -173,8 +178,11 @@ struct zynqmp_qspi_priv {
        int bytes_to_receive;
        unsigned int is_inst;
        unsigned int cs_change:1;
+       unsigned int io_mode;
 };

+static u8 last_cmd;
+
 static int zynqmp_qspi_of_to_plat(struct udevice *bus)
 {
        struct zynqmp_qspi_plat *plat = dev_get_plat(bus);
@@ -186,6 +194,7 @@ static int zynqmp_qspi_of_to_plat(struct udevice *bus)
        plat->dma_regs = (struct zynqmp_qspi_dma_regs *)
                          (dev_read_addr(bus) + GQSPI_DMA_REG_OFFSET);

+       plat->io_mode = dev_read_bool(bus, "has-io-mode");
        return 0;
 }

@@ -198,14 +207,20 @@ static void zynqmp_qspi_init_hw(struct zynqmp_qspi_priv *priv)
        writel(GQSPI_GFIFO_ALL_INT_MASK, &regs->idisr);
        writel(GQSPI_FIFO_THRESHOLD, &regs->txftr);
        writel(GQSPI_FIFO_THRESHOLD, &regs->rxftr);
+       writel(GQSPI_GENFIFO_THRESHOLD, &regs->gqfthr);
        writel(GQSPI_GFIFO_ALL_INT_MASK, &regs->isr);
+       writel(0x0, &regs->enbr);

        config_reg = readl(&regs->confr);
-       config_reg &= ~(GQSPI_GFIFO_STRT_MODE_MASK |
-                       GQSPI_CONFIG_MODE_EN_MASK);
-       config_reg |= GQSPI_CONFIG_DMA_MODE |
-                     GQSPI_GFIFO_WP_HOLD |
-                     GQSPI_DFLT_BAUD_RATE_DIV;
+       config_reg &= ~(GQSPI_CONFIG_MODE_EN_MASK);
+       config_reg |= GQSPI_GFIFO_WP_HOLD | GQSPI_DFLT_BAUD_RATE_DIV;
+       if (priv->io_mode) {
+               config_reg |= GQSPI_GFIFO_STRT_MODE_MASK;
+       } else {
+               config_reg &= ~(GQSPI_GFIFO_STRT_MODE_MASK);
+               config_reg |= GQSPI_CONFIG_DMA_MODE;
+       }
+
        writel(config_reg, &regs->confr);

        writel(GQSPI_ENABLE_ENABLE_MASK, &regs->enbr);
@@ -215,8 +230,7 @@ static u32 zynqmp_qspi_bus_select(struct zynqmp_qspi_priv *priv)
 {
        u32 gqspi_fifo_reg = 0;

-       gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS |
-                        GQSPI_GFIFO_CS_LOWER;
+       gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS | GQSPI_GFIFO_CS_LOWER;

        return gqspi_fifo_reg;
 }
@@ -227,6 +241,7 @@ static void zynqmp_qspi_fill_gen_fifo(struct zynqmp_qspi_priv *priv,
        struct zynqmp_qspi_regs *regs = priv->regs;
        int ret = 0;

+       /* Wait until the fifo is not full to write the new command */
        ret = wait_for_bit_le32(&regs->isr, GQSPI_IXR_GFEMTY_MASK, 1,
                                GQSPI_TIMEOUT, 1);
        if (ret)
@@ -343,6 +358,7 @@ static int zynqmp_qspi_probe(struct udevice *bus)

        priv->regs = plat->regs;
        priv->dma_regs = plat->dma_regs;
+       priv->io_mode = plat->io_mode;

        ret = clk_get_by_index(bus, 0, &clk);
        if (ret < 0) {
@@ -363,7 +379,7 @@ static int zynqmp_qspi_probe(struct udevice *bus)
                return ret;
        }
        plat->frequency = clock;
-       plat->speed_hz = plat->frequency / 2;
+       plat->speed_hz = plat->frequency;

        /* init the zynq spi hw */
        zynqmp_qspi_init_hw(priv);
@@ -395,7 +411,7 @@ static int zynqmp_qspi_set_mode(struct udevice *bus, uint mode)

 static int zynqmp_qspi_fill_tx_fifo(struct zynqmp_qspi_priv *priv, u32 size)
 {
-       u32 data;
+       u32 data, config_reg, ier;
        int ret = 0;
        struct zynqmp_qspi_regs *regs = priv->regs;
        u32 *buf = (u32 *)priv->tx_buf;
@@ -404,6 +420,17 @@ static int zynqmp_qspi_fill_tx_fifo(struct zynqmp_qspi_priv *priv, u32 size)
        debug("TxFIFO: 0x%x, size: 0x%x\n", readl(&regs->isr),
              size);

+       config_reg = readl(&regs->confr);
+       /* Manual start if needed */
+       if (config_reg & GQSPI_GEN_FIFO_STRT_MOD) {
+               config_reg |= GQSPI_STRT_GEN_FIFO;
+               writel(config_reg, &regs->confr);
+               /* Enable interrupts */
+               ier = readl(&regs->ier);
+               ier |= GQSPI_IXR_ALL_MASK;
+               writel(ier, &regs->ier);
+       }
+
        while (size) {
                ret = wait_for_bit_le32(&regs->isr, GQSPI_IXR_TXNFULL_MASK, 1,
                                        GQSPI_TIMEOUT, 1);
@@ -445,12 +472,20 @@ static int zynqmp_qspi_fill_tx_fifo(struct zynqmp_qspi_priv *priv, u32 size)

 static void zynqmp_qspi_genfifo_cmd(struct zynqmp_qspi_priv *priv)
 {
+       u8 command = 1;
        u32 gen_fifo_cmd;
        u32 bytecount = 0;

        while (priv->len) {
                gen_fifo_cmd = zynqmp_qspi_bus_select(priv);
-               gen_fifo_cmd |= GQSPI_GFIFO_TX | GQSPI_SPI_MODE_SPI;
+               gen_fifo_cmd |= GQSPI_GFIFO_TX;
+
+               if (command) {
+                       command = 0;
+                       last_cmd = *(u8 *)priv->tx_buf;
+               }
+
+               gen_fifo_cmd |= GQSPI_SPI_MODE_SPI;
                gen_fifo_cmd |= *(u8 *)priv->tx_buf;
                bytecount++;
                priv->len--;
@@ -499,7 +534,10 @@ static int zynqmp_qspi_genfifo_fill_tx(struct zynqmp_qspi_priv *priv)
        gen_fifo_cmd |= GQSPI_GFIFO_TX |
                        GQSPI_GFIFO_DATA_XFR_MASK;

-       gen_fifo_cmd |= GQSPI_SPI_MODE_SPI;
+       if (last_cmd == SPINOR_OP_PP_1_1_4)
+               gen_fifo_cmd |= GQSPI_SPI_MODE_QSPI;
+       else
+               gen_fifo_cmd |= GQSPI_SPI_MODE_SPI;

        while (priv->len) {
                len = zynqmp_qspi_calc_exp(priv, &gen_fifo_cmd);
@@ -520,6 +558,66 @@ static int zynqmp_qspi_genfifo_fill_tx(struct zynqmp_qspi_priv *priv)
        return ret;
 }

+static int zynqmp_qspi_start_io(struct zynqmp_qspi_priv *priv,
+                               u32 gen_fifo_cmd, u32 *buf)
+{
+       u32 len;
+       u32 actuallen = priv->len;
+       u32 config_reg, ier, isr;
+       u32 timeout = GQSPI_TIMEOUT;
+       struct zynqmp_qspi_regs *regs = priv->regs;
+       u32 last_bits;
+       u32 *traverse = buf;
+
+       while (priv->len) {
+               len = zynqmp_qspi_calc_exp(priv, &gen_fifo_cmd);
+               /* If exponent bit is set, reset immediate to be 2^len */
+               if (gen_fifo_cmd & GQSPI_GFIFO_EXP_MASK)
+                       priv->bytes_to_receive = (1 << len);
+               else
+                       priv->bytes_to_receive = len;
+               zynqmp_qspi_fill_gen_fifo(priv, gen_fifo_cmd);
+               debug("GFIFO_CMD_RX:0x%x\n", gen_fifo_cmd);
+               /* Manual start */
+               config_reg = readl(&regs->confr);
+               config_reg |= GQSPI_STRT_GEN_FIFO;
+               writel(config_reg, &regs->confr);
+               /* Enable RX interrupts for IO mode */
+               ier = readl(&regs->ier);
+               ier |= GQSPI_IXR_ALL_MASK;
+               writel(ier, &regs->ier);
+               while (priv->bytes_to_receive && timeout) {
+                       isr = readl(&regs->isr);
+                       if (isr & GQSPI_IXR_RXNEMTY_MASK) {
+                               if (priv->bytes_to_receive >= 4) {
+                                       *traverse = readl(&regs->drxr);
+                                       traverse++;
+                                       priv->bytes_to_receive -= 4;
+                               } else {
+                                       last_bits = readl(&regs->drxr);
+                                       memcpy(traverse, &last_bits,
+                                              priv->bytes_to_receive);
+                                       priv->bytes_to_receive = 0;
+                               }
+                               timeout = GQSPI_TIMEOUT;
+                       } else {
+                               udelay(1);
+                               timeout--;
+                       }
+               }
+
+               debug("buf:0x%lx, rxbuf:0x%lx, *buf:0x%x len: 0x%x\n",
+                     (unsigned long)buf, (unsigned long)priv->rx_buf,
+                     *buf, actuallen);
+               if (!timeout) {
+                       printf("IO timeout: %d\n", readl(&regs->isr));
+                       return -1;
+               }
+       }
+
+       return 0;
+}
+
 static int zynqmp_qspi_start_dma(struct zynqmp_qspi_priv *priv,
                                 u32 gen_fifo_cmd, u32 *buf)
 {
@@ -572,16 +670,24 @@ static int zynqmp_qspi_genfifo_fill_rx(struct zynqmp_qspi_priv *priv)
        gen_fifo_cmd |= GQSPI_GFIFO_RX |
                        GQSPI_GFIFO_DATA_XFR_MASK;

-       gen_fifo_cmd |= GQSPI_SPI_MODE_SPI;
+       if (last_cmd == SPINOR_OP_READ_1_1_4)
+               gen_fifo_cmd |= GQSPI_SPI_MODE_QSPI;
+       else if (last_cmd == SPINOR_OP_READ_1_1_2)
+               gen_fifo_cmd |= GQSPI_SPI_MODE_DUAL_SPI;
+       else
+               gen_fifo_cmd |= GQSPI_SPI_MODE_SPI;

        /*
         * Check if receive buffer is aligned to 4 byte and length
         * is multiples of four byte as we are using dma to receive.
         */
-       if (!((unsigned long)priv->rx_buf & (GQSPI_DMA_ALIGN - 1)) &&
-           !(actuallen % GQSPI_DMA_ALIGN)) {
+       if ((!((unsigned long)priv->rx_buf & (GQSPI_DMA_ALIGN - 1)) &&
+            !(actuallen % GQSPI_DMA_ALIGN)) || priv->io_mode) {
                buf = (u32 *)priv->rx_buf;
-               return zynqmp_qspi_start_dma(priv, gen_fifo_cmd, buf);
+               if (priv->io_mode)
+                       return zynqmp_qspi_start_io(priv, gen_fifo_cmd, buf);
+               else
+                       return zynqmp_qspi_start_dma(priv, gen_fifo_cmd, buf);
        }

        ALLOC_CACHE_ALIGN_BUFFER(u8, tmp, roundup(priv->len,
--
2.17.1

This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

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

* [PATCH 4/7] spi: zynqmp_gqspi: Fix tap delay values
  2021-01-18 12:32 [PATCH 0/7] zynqmp_gqspi driver updates Ashok Reddy Soma
                   ` (2 preceding siblings ...)
  2021-01-18 12:32 ` [PATCH 3/7] spi: zynqmp_gqspi: Add support for IO mode Ashok Reddy Soma
@ 2021-01-18 12:32 ` Ashok Reddy Soma
  2021-01-18 12:32 ` [PATCH 5/7] spi: zynqmp_gqspi: Fix write issues in single mode Ashok Reddy Soma
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Ashok Reddy Soma @ 2021-01-18 12:32 UTC (permalink / raw)
  To: u-boot

From: Siva Durga Prasad Paladugu <siva.durga.paladugu@xilinx.com>

There is no need of read modify write for tapdelay settings
ans hence remove the read operations while setting tapdelays.
Also, correct tapdelay value settings at 40MHZ by modifying
the if check to <= instead of <.

Signed-off-by: Siva Durga Prasad Paladugu <siva.durga.paladugu@xilinx.com>
Signed-off-by: Ashok Reddy Soma <ashok.reddy.soma@xilinx.com>
---

 drivers/spi/zynqmp_gqspi.c | 27 +++++++++++----------------
 1 file changed, 11 insertions(+), 16 deletions(-)

diff --git a/drivers/spi/zynqmp_gqspi.c b/drivers/spi/zynqmp_gqspi.c
index ae7b70aa57..136c20f09e 100644
--- a/drivers/spi/zynqmp_gqspi.c
+++ b/drivers/spi/zynqmp_gqspi.c
@@ -282,24 +282,19 @@ void zynqmp_qspi_set_tapdelay(struct udevice *bus, u32 baudrateval)
        debug("%s, req_hz:%d, clk_rate:%d, baudrateval:%d\n",
              __func__, reqhz, clk_rate, baudrateval);

-       if (reqhz < GQSPI_FREQ_40MHZ) {
-               zynqmp_mmio_read(IOU_TAPDLY_BYPASS_OFST, &tapdlybypass);
-               tapdlybypass |= (TAP_DLY_BYPASS_LQSPI_RX_VALUE <<
-                               TAP_DLY_BYPASS_LQSPI_RX_SHIFT);
+       if (reqhz <= GQSPI_FREQ_40MHZ) {
+               tapdlybypass = TAP_DLY_BYPASS_LQSPI_RX_VALUE <<
+                               TAP_DLY_BYPASS_LQSPI_RX_SHIFT;
        } else if (reqhz <= GQSPI_FREQ_100MHZ) {
-               zynqmp_mmio_read(IOU_TAPDLY_BYPASS_OFST, &tapdlybypass);
-               tapdlybypass |= (TAP_DLY_BYPASS_LQSPI_RX_VALUE <<
-                               TAP_DLY_BYPASS_LQSPI_RX_SHIFT);
-               lpbkdlyadj = readl(&regs->lpbkdly);
-               lpbkdlyadj |= (GQSPI_LPBK_DLY_ADJ_LPBK_MASK);
-               datadlyadj = readl(&regs->gqspidlyadj);
-               datadlyadj |= ((GQSPI_USE_DATA_DLY << GQSPI_USE_DATA_DLY_SHIFT)
-                               | (GQSPI_DATA_DLY_ADJ_VALUE <<
-                                       GQSPI_DATA_DLY_ADJ_SHIFT));
+               tapdlybypass = TAP_DLY_BYPASS_LQSPI_RX_VALUE <<
+                               TAP_DLY_BYPASS_LQSPI_RX_SHIFT;
+               lpbkdlyadj = GQSPI_LPBK_DLY_ADJ_LPBK_MASK;
+               datadlyadj = (GQSPI_USE_DATA_DLY << GQSPI_USE_DATA_DLY_SHIFT) |
+                             (GQSPI_DATA_DLY_ADJ_VALUE <<
+                              GQSPI_DATA_DLY_ADJ_SHIFT);
        } else if (reqhz <= GQSPI_FREQ_150MHZ) {
-               lpbkdlyadj = readl(&regs->lpbkdly);
-               lpbkdlyadj |= ((GQSPI_LPBK_DLY_ADJ_LPBK_MASK) |
-                               GQSPI_LPBK_DLY_ADJ_DLY_0);
+               lpbkdlyadj = GQSPI_LPBK_DLY_ADJ_LPBK_MASK |
+                             GQSPI_LPBK_DLY_ADJ_DLY_0;
        }

        zynqmp_mmio_write(IOU_TAPDLY_BYPASS_OFST, IOU_TAPDLY_BYPASS_MASK,
--
2.17.1

This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

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

* [PATCH 5/7] spi: zynqmp_gqspi: Fix write issues in single mode
  2021-01-18 12:32 [PATCH 0/7] zynqmp_gqspi driver updates Ashok Reddy Soma
                   ` (3 preceding siblings ...)
  2021-01-18 12:32 ` [PATCH 4/7] spi: zynqmp_gqspi: Fix tap delay values Ashok Reddy Soma
@ 2021-01-18 12:32 ` Ashok Reddy Soma
  2021-01-18 12:32 ` [PATCH 6/7] spi: zynqmp_gqspi: Add tap delays for Versal qspi Ashok Reddy Soma
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Ashok Reddy Soma @ 2021-01-18 12:32 UTC (permalink / raw)
  To: u-boot

Add dummy write to genfifo register in chipselect.

Enable manual start in zynqmp_qspi_fill_gen_fifo().

Also enable GQSPI_IXR_GFNFULL_MASK and check for it instead of
GQSPI_IXR_GFEMTY_MASK.

Signed-off-by: Ashok Reddy Soma <ashok.reddy.soma@xilinx.com>
---

 drivers/spi/zynqmp_gqspi.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/zynqmp_gqspi.c b/drivers/spi/zynqmp_gqspi.c
index 136c20f09e..f50a7304ea 100644
--- a/drivers/spi/zynqmp_gqspi.c
+++ b/drivers/spi/zynqmp_gqspi.c
@@ -239,10 +239,21 @@ static void zynqmp_qspi_fill_gen_fifo(struct zynqmp_qspi_priv *priv,
                                      u32 gqspi_fifo_reg)
 {
        struct zynqmp_qspi_regs *regs = priv->regs;
+       u32 config_reg, ier;
        int ret = 0;

+       config_reg = readl(&regs->confr);
+       /* Manual start if needed */
+       config_reg |= GQSPI_STRT_GEN_FIFO;
+       writel(config_reg, &regs->confr);
+
+       /* Enable interrupts */
+       ier = readl(&regs->ier);
+       ier |= GQSPI_IXR_GFNFULL_MASK;
+       writel(ier, &regs->ier);
+
        /* Wait until the fifo is not full to write the new command */
-       ret = wait_for_bit_le32(&regs->isr, GQSPI_IXR_GFEMTY_MASK, 1,
+       ret = wait_for_bit_le32(&regs->isr, GQSPI_IXR_GFNFULL_MASK, 1,
                                GQSPI_TIMEOUT, 1);
        if (ret)
                printf("%s Timeout\n", __func__);
@@ -265,6 +276,9 @@ static void zynqmp_qspi_chipselect(struct zynqmp_qspi_priv *priv, int is_on)

        debug("GFIFO_CMD_CS: 0x%x\n", gqspi_fifo_reg);

+       /* Dummy generic FIFO entry */
+       zynqmp_qspi_fill_gen_fifo(priv, 0);
+
        zynqmp_qspi_fill_gen_fifo(priv, gqspi_fifo_reg);
 }

--
2.17.1

This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

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

* [PATCH 6/7] spi: zynqmp_gqspi: Add tap delays for Versal qspi
  2021-01-18 12:32 [PATCH 0/7] zynqmp_gqspi driver updates Ashok Reddy Soma
                   ` (4 preceding siblings ...)
  2021-01-18 12:32 ` [PATCH 5/7] spi: zynqmp_gqspi: Fix write issues in single mode Ashok Reddy Soma
@ 2021-01-18 12:32 ` Ashok Reddy Soma
  2021-01-18 12:32 ` [PATCH 7/7] spi: zynqmp_gqspi: Update tapdelay value Ashok Reddy Soma
  2021-01-18 12:39 ` [PATCH 0/7] zynqmp_gqspi driver updates Bin Meng
  7 siblings, 0 replies; 9+ messages in thread
From: Ashok Reddy Soma @ 2021-01-18 12:32 UTC (permalink / raw)
  To: u-boot

This patch adds tap delays for qspi in Versal platform.
Use IS_ENABLED() to address for ZynqMP and Versal and re-align the
tapdelays code.

Signed-off-by: Ashok Reddy Soma <ashok.reddy.soma@xilinx.com>
---

 drivers/spi/zynqmp_gqspi.c | 54 ++++++++++++++++++++++++++------------
 1 file changed, 37 insertions(+), 17 deletions(-)

diff --git a/drivers/spi/zynqmp_gqspi.c b/drivers/spi/zynqmp_gqspi.c
index f50a7304ea..e9726912b7 100644
--- a/drivers/spi/zynqmp_gqspi.c
+++ b/drivers/spi/zynqmp_gqspi.c
@@ -102,8 +102,10 @@
 #define TAP_DLY_BYPASS_LQSPI_RX_VALUE  0x1
 #define TAP_DLY_BYPASS_LQSPI_RX_SHIFT  2
 #define GQSPI_DATA_DLY_ADJ_OFST                0x000001F8
-#define IOU_TAPDLY_BYPASS_OFST         0xFF180390
+#define IOU_TAPDLY_BYPASS_OFST !IS_ENABLED(CONFIG_ARCH_VERSAL) ? \
+                               0xFF180390 : 0xF103003C
 #define GQSPI_LPBK_DLY_ADJ_LPBK_MASK   0x00000020
+#define GQSPI_FREQ_37_5MHZ             37500000
 #define GQSPI_FREQ_40MHZ               40000000
 #define GQSPI_FREQ_100MHZ              100000000
 #define GQSPI_FREQ_150MHZ              150000000
@@ -296,23 +298,41 @@ void zynqmp_qspi_set_tapdelay(struct udevice *bus, u32 baudrateval)
        debug("%s, req_hz:%d, clk_rate:%d, baudrateval:%d\n",
              __func__, reqhz, clk_rate, baudrateval);

-       if (reqhz <= GQSPI_FREQ_40MHZ) {
-               tapdlybypass = TAP_DLY_BYPASS_LQSPI_RX_VALUE <<
-                               TAP_DLY_BYPASS_LQSPI_RX_SHIFT;
-       } else if (reqhz <= GQSPI_FREQ_100MHZ) {
-               tapdlybypass = TAP_DLY_BYPASS_LQSPI_RX_VALUE <<
-                               TAP_DLY_BYPASS_LQSPI_RX_SHIFT;
-               lpbkdlyadj = GQSPI_LPBK_DLY_ADJ_LPBK_MASK;
-               datadlyadj = (GQSPI_USE_DATA_DLY << GQSPI_USE_DATA_DLY_SHIFT) |
-                             (GQSPI_DATA_DLY_ADJ_VALUE <<
-                              GQSPI_DATA_DLY_ADJ_SHIFT);
-       } else if (reqhz <= GQSPI_FREQ_150MHZ) {
-               lpbkdlyadj = GQSPI_LPBK_DLY_ADJ_LPBK_MASK |
-                             GQSPI_LPBK_DLY_ADJ_DLY_0;
+       if (!IS_ENABLED(CONFIG_ARCH_VERSAL)) {
+               if (reqhz <= GQSPI_FREQ_40MHZ) {
+                       tapdlybypass = TAP_DLY_BYPASS_LQSPI_RX_VALUE <<
+                                       TAP_DLY_BYPASS_LQSPI_RX_SHIFT;
+               } else if (reqhz <= GQSPI_FREQ_100MHZ) {
+                       tapdlybypass = TAP_DLY_BYPASS_LQSPI_RX_VALUE <<
+                                       TAP_DLY_BYPASS_LQSPI_RX_SHIFT;
+                       lpbkdlyadj = GQSPI_LPBK_DLY_ADJ_LPBK_MASK;
+                       datadlyadj = (GQSPI_USE_DATA_DLY <<
+                                     GQSPI_USE_DATA_DLY_SHIFT) |
+                                      (GQSPI_DATA_DLY_ADJ_VALUE <<
+                                       GQSPI_DATA_DLY_ADJ_SHIFT);
+               } else if (reqhz <= GQSPI_FREQ_150MHZ) {
+                       lpbkdlyadj = GQSPI_LPBK_DLY_ADJ_LPBK_MASK |
+                                     GQSPI_LPBK_DLY_ADJ_DLY_0;
+               }
+               zynqmp_mmio_write(IOU_TAPDLY_BYPASS_OFST,
+                                 IOU_TAPDLY_BYPASS_MASK, tapdlybypass);
+       } else {
+               if (reqhz <= GQSPI_FREQ_37_5MHZ) {
+                       tapdlybypass = TAP_DLY_BYPASS_LQSPI_RX_VALUE <<
+                                       TAP_DLY_BYPASS_LQSPI_RX_SHIFT;
+               } else if (reqhz <= GQSPI_FREQ_100MHZ) {
+                       tapdlybypass = TAP_DLY_BYPASS_LQSPI_RX_VALUE <<
+                                       TAP_DLY_BYPASS_LQSPI_RX_SHIFT;
+                       lpbkdlyadj = GQSPI_LPBK_DLY_ADJ_LPBK_MASK;
+                       datadlyadj = GQSPI_USE_DATA_DLY <<
+                                     GQSPI_USE_DATA_DLY_SHIFT;
+               } else if (reqhz <= GQSPI_FREQ_150MHZ) {
+                       lpbkdlyadj = GQSPI_LPBK_DLY_ADJ_LPBK_MASK |
+                                     (GQSPI_LPBK_DLY_ADJ_DLY_1 <<
+                                      GQSPI_LPBK_DLY_ADJ_DLY_1_SHIFT);
+               }
+               writel(tapdlybypass, IOU_TAPDLY_BYPASS_OFST);
        }
-
-       zynqmp_mmio_write(IOU_TAPDLY_BYPASS_OFST, IOU_TAPDLY_BYPASS_MASK,
-                         tapdlybypass);
        writel(lpbkdlyadj, &regs->lpbkdly);
        writel(datadlyadj, &regs->gqspidlyadj);
 }
--
2.17.1

This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

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

* [PATCH 7/7] spi: zynqmp_gqspi: Update tapdelay value
  2021-01-18 12:32 [PATCH 0/7] zynqmp_gqspi driver updates Ashok Reddy Soma
                   ` (5 preceding siblings ...)
  2021-01-18 12:32 ` [PATCH 6/7] spi: zynqmp_gqspi: Add tap delays for Versal qspi Ashok Reddy Soma
@ 2021-01-18 12:32 ` Ashok Reddy Soma
  2021-01-18 12:39 ` [PATCH 0/7] zynqmp_gqspi driver updates Bin Meng
  7 siblings, 0 replies; 9+ messages in thread
From: Ashok Reddy Soma @ 2021-01-18 12:32 UTC (permalink / raw)
  To: u-boot

From: T Karthik Reddy <t.karthik.reddy@xilinx.com>

Update GQSPI_LPBK_DLY_ADJ_DLY_1 tapdelay value for Versal for
frequencies above 100MHz.

Signed-off-by: T Karthik Reddy <t.karthik.reddy@xilinx.com>
Signed-off-by: Ashok Reddy Soma <ashok.reddy.soma@xilinx.com>
---

 drivers/spi/zynqmp_gqspi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/spi/zynqmp_gqspi.c b/drivers/spi/zynqmp_gqspi.c
index e9726912b7..0771541e12 100644
--- a/drivers/spi/zynqmp_gqspi.c
+++ b/drivers/spi/zynqmp_gqspi.c
@@ -92,7 +92,7 @@

 #define GQSPI_BAUD_DIV_SHIFT           2
 #define GQSPI_LPBK_DLY_ADJ_LPBK_SHIFT  5
-#define GQSPI_LPBK_DLY_ADJ_DLY_1       0x2
+#define GQSPI_LPBK_DLY_ADJ_DLY_1       0x1
 #define GQSPI_LPBK_DLY_ADJ_DLY_1_SHIFT 3
 #define GQSPI_LPBK_DLY_ADJ_DLY_0       0x3
 #define GQSPI_USE_DATA_DLY             0x1
--
2.17.1

This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

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

* [PATCH 0/7] zynqmp_gqspi driver updates
  2021-01-18 12:32 [PATCH 0/7] zynqmp_gqspi driver updates Ashok Reddy Soma
                   ` (6 preceding siblings ...)
  2021-01-18 12:32 ` [PATCH 7/7] spi: zynqmp_gqspi: Update tapdelay value Ashok Reddy Soma
@ 2021-01-18 12:39 ` Bin Meng
  7 siblings, 0 replies; 9+ messages in thread
From: Bin Meng @ 2021-01-18 12:39 UTC (permalink / raw)
  To: u-boot

On Mon, Jan 18, 2021 at 8:35 PM Ashok Reddy Soma
<ashok.reddy.soma@xilinx.com> wrote:
>
> This patch series updates xilinx qspi driver with below fixes/enhancements
>
>  - Fix rounding off issue in DMA transfers
>  - Fix DMA transfers to be word aligned
>  - Add support for IO mode
>  - Fix write issues in QSPI single mode
>  - Fix zynqmp tapdelays
>  - Add Versal tapdelays
>  - Update tapdelay for >100Mhz for Versal
>
> This is resend for the people in CC, as i had trouble with my email
> server earlier.
>
>
>
> Ashok Reddy Soma (3):
>   spi: zynqmp_gqspi: Add support for IO mode
>   spi: zynqmp_gqspi: Fix write issues in single mode
>   spi: zynqmp_gqspi: Add tap delays for Versal qspi
>
> Siva Durga Prasad Paladugu (1):
>   spi: zynqmp_gqspi: Fix tap delay values
>
> T Karthik Reddy (1):
>   spi: zynqmp_gqspi: Update tapdelay value
>
> Wojciech Tatarski (2):
>   spi: zynqmp_gqspi: do not round immediate_data field
>   spi: zynqmp_gqspi: DMA transfers should be word aligned
>
>  drivers/spi/zynqmp_gqspi.c | 230 +++++++++++++++++++++++++++++--------
>  1 file changed, 180 insertions(+), 50 deletions(-)
>

+Brandon Maier

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

end of thread, other threads:[~2021-01-18 12:39 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-18 12:32 [PATCH 0/7] zynqmp_gqspi driver updates Ashok Reddy Soma
2021-01-18 12:32 ` [PATCH 1/7] spi: zynqmp_gqspi: do not round immediate_data field Ashok Reddy Soma
2021-01-18 12:32 ` [PATCH 2/7] spi: zynqmp_gqspi: DMA transfers should be word aligned Ashok Reddy Soma
2021-01-18 12:32 ` [PATCH 3/7] spi: zynqmp_gqspi: Add support for IO mode Ashok Reddy Soma
2021-01-18 12:32 ` [PATCH 4/7] spi: zynqmp_gqspi: Fix tap delay values Ashok Reddy Soma
2021-01-18 12:32 ` [PATCH 5/7] spi: zynqmp_gqspi: Fix write issues in single mode Ashok Reddy Soma
2021-01-18 12:32 ` [PATCH 6/7] spi: zynqmp_gqspi: Add tap delays for Versal qspi Ashok Reddy Soma
2021-01-18 12:32 ` [PATCH 7/7] spi: zynqmp_gqspi: Update tapdelay value Ashok Reddy Soma
2021-01-18 12:39 ` [PATCH 0/7] zynqmp_gqspi driver updates Bin Meng

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.