[U-Boot,v2,3/3] spi: xilinx_spi: Added support to read JEDEC-id twice at the boot time

Message ID 1528783453-7375-4-git-send-email-vipul.kumar@xilinx.com
State Superseded
Delegated to: Jagannadha Sutradharudu Teki
Headers show
Series
  • spi:xilinx_spi: Modify xilinx spi driver
Related show

Commit Message

Vipul Kumar June 12, 2018, 6:04 a.m.
This patch is for the startup block issue in the spi controller.
SPI clock is passing through STARTUP block to FLASH. STARTUP block
don't provide clock as soon as QSPI provides command. So, first
command fails.

This patch added support to read JEDEC id in xilinx_spi_xfer ().

Signed-off-by: Vipul Kumar <vipul.kumar@xilinx.com>
---
 drivers/spi/xilinx_spi.c | 41 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

--
2.7.4

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.

Patch

diff --git a/drivers/spi/xilinx_spi.c b/drivers/spi/xilinx_spi.c
index 70a110a..08c2883 100644
--- a/drivers/spi/xilinx_spi.c
+++ b/drivers/spi/xilinx_spi.c
@@ -199,6 +199,40 @@  static u32 xilinx_spi_read_rxfifo(struct udevice *bus, u8 *rxp, u32 rxbytes)
        return i;
 }

+static void xilinx_startup_block(struct udevice *dev, unsigned int bytes,
+                                const void *dout, void *din)
+{
+       struct udevice *bus = dev_get_parent(dev);
+       struct xilinx_spi_priv *priv = dev_get_priv(bus);
+       struct xilinx_spi_regs *regs = priv->regs;
+       struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
+       const unsigned char *txp = dout;
+       unsigned char *rxp = din;
+       static int startup;
+       u32 reg, count;
+       u32 txbytes = bytes;
+       u32 rxbytes = bytes;
+
+       /*
+        * This loop runs two times. First time to send the command.
+        * Second time to transfer data. After transferring data,
+        * it sets txp to the initial value for the normal operation.
+        */
+       for ( ; startup < 2; startup++) {
+               count = xilinx_spi_fill_txfifo(bus, txp, txbytes);
+               reg = readl(&regs->spicr) & ~SPICR_MASTER_INHIBIT;
+               writel(reg, &regs->spicr);
+               count = xilinx_spi_read_rxfifo(bus, rxp, rxbytes);
+               txp = din;
+
+               if (startup) {
+                       spi_cs_deactivate(dev);
+                       spi_cs_activate(dev, slave_plat->cs);
+                       txp = dout;
+               }
+       }
+}
+
 static int xilinx_spi_xfer(struct udevice *dev, unsigned int bitlen,
                            const void *dout, void *din, unsigned long flags)
 {
@@ -231,6 +265,13 @@  static int xilinx_spi_xfer(struct udevice *dev, unsigned int bitlen,
        if (flags & SPI_XFER_BEGIN)
                spi_cs_activate(dev, slave_plat->cs);

+       /*
+        * This is the work around for the startup block issue in
+        * the spi controller. SPI clock is passing through STARTUP
+        * block to FLASH. STARTUP block don't provide clock as soon
+        * as QSPI provides command. So first command fails.
+        */
+       xilinx_startup_block(dev, bytes, dout, din);

        while (txbytes && rxbytes) {
                count = xilinx_spi_fill_txfifo(bus, txp, txbytes);