Merge tag 'xilinx-for-v2021.04-rc3' of https://gitlab.denx.de/u-boot/custodians/u...
[platform/kernel/u-boot.git] / drivers / spi / zynq_qspi.c
index 241a363..cf6da53 100644 (file)
@@ -1,17 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * (C) Copyright 2013 Xilinx, Inc.
  * (C) Copyright 2015 Jagan Teki <jteki@openedev.com>
  *
  * Xilinx Zynq Quad-SPI(QSPI) controller driver (master mode only)
- *
- * SPDX-License-Identifier:    GPL-2.0+
  */
 
+#include <clk.h>
 #include <common.h>
 #include <dm.h>
+#include <dm/device_compat.h>
+#include <log.h>
 #include <malloc.h>
 #include <spi.h>
+#include <asm/global_data.h>
 #include <asm/io.h>
+#include <linux/bitops.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -20,16 +24,17 @@ DECLARE_GLOBAL_DATA_PTR;
 #define ZYNQ_QSPI_CR_MSA_MASK          BIT(15) /* Manual start enb */
 #define ZYNQ_QSPI_CR_MCS_MASK          BIT(14) /* Manual chip select */
 #define ZYNQ_QSPI_CR_PCS_MASK          BIT(10) /* Peri chip select */
-#define ZYNQ_QSPI_CR_FW_MASK           (0x3 << 6)      /* FIFO width */
-#define ZYNQ_QSPI_CR_SS_MASK           (0xF << 10)     /* Slave Select */
-#define ZYNQ_QSPI_CR_BAUD_MASK         (0x7 << 3)      /* Baud rate div */
+#define ZYNQ_QSPI_CR_FW_MASK           GENMASK(7, 6)   /* FIFO width */
+#define ZYNQ_QSPI_CR_SS_MASK           GENMASK(13, 10) /* Slave Select */
+#define ZYNQ_QSPI_CR_BAUD_MASK         GENMASK(5, 3)   /* Baud rate div */
 #define ZYNQ_QSPI_CR_CPHA_MASK         BIT(2)  /* Clock phase */
 #define ZYNQ_QSPI_CR_CPOL_MASK         BIT(1)  /* Clock polarity */
 #define ZYNQ_QSPI_CR_MSTREN_MASK       BIT(0)  /* Mode select */
 #define ZYNQ_QSPI_IXR_RXNEMPTY_MASK    BIT(4)  /* RX_FIFO_not_empty */
 #define ZYNQ_QSPI_IXR_TXOW_MASK                BIT(2)  /* TX_FIFO_not_full */
-#define ZYNQ_QSPI_IXR_ALL_MASK         0x7F            /* All IXR bits */
+#define ZYNQ_QSPI_IXR_ALL_MASK         GENMASK(6, 0)   /* All IXR bits */
 #define ZYNQ_QSPI_ENR_SPI_EN_MASK      BIT(0)  /* SPI Enable */
+#define ZYNQ_QSPI_LQSPICFG_LQMODE_MASK BIT(31) /* Linear QSPI Mode */
 
 /* zynq qspi Transmit Data Register */
 #define ZYNQ_QSPI_TXD_00_00_OFFSET     0x1C    /* Transmit 4-byte inst */
@@ -45,9 +50,7 @@ DECLARE_GLOBAL_DATA_PTR;
 #define ZYNQ_QSPI_CR_SS_SHIFT          10      /* Slave select shift */
 
 #define ZYNQ_QSPI_FIFO_DEPTH           63
-#ifndef CONFIG_SYS_ZYNQ_QSPI_WAIT
-#define CONFIG_SYS_ZYNQ_QSPI_WAIT      CONFIG_SYS_HZ/100       /* 10 ms */
-#endif
+#define ZYNQ_QSPI_WAIT                 (CONFIG_SYS_HZ / 100)   /* 10 ms */
 
 /* zynq qspi register set */
 struct zynq_qspi_regs {
@@ -68,10 +71,13 @@ struct zynq_qspi_regs {
        u32 txd1r;      /* 0x80 */
        u32 txd2r;      /* 0x84 */
        u32 txd3r;      /* 0x88 */
+       u32 reserved1[5];
+       u32 lqspicfg;   /* 0xA0 */
+       u32 lqspists;   /* 0xA4 */
 };
 
 /* zynq qspi platform data */
-struct zynq_qspi_platdata {
+struct zynq_qspi_plat {
        struct zynq_qspi_regs *regs;
        u32 frequency;          /* input frequency */
        u32 speed_hz;
@@ -93,26 +99,38 @@ struct zynq_qspi_priv {
        unsigned cs_change:1;
 };
 
-static int zynq_qspi_ofdata_to_platdata(struct udevice *bus)
+static int zynq_qspi_of_to_plat(struct udevice *bus)
 {
-       struct zynq_qspi_platdata *plat = bus->platdata;
+       struct zynq_qspi_plat *plat = dev_get_plat(bus);
        const void *blob = gd->fdt_blob;
-       int node = bus->of_offset;
+       int node = dev_of_offset(bus);
 
        plat->regs = (struct zynq_qspi_regs *)fdtdec_get_addr(blob,
                                                              node, "reg");
 
-       /* FIXME: Use 166MHz as a suitable default */
-       plat->frequency = fdtdec_get_int(blob, node, "spi-max-frequency",
-                                       166666666);
-       plat->speed_hz = plat->frequency / 2;
-
-       debug("%s: regs=%p max-frequency=%d\n", __func__,
-             plat->regs, plat->frequency);
-
        return 0;
 }
 
+/**
+ * zynq_qspi_init_hw - Initialize the hardware
+ * @priv:      Pointer to the zynq_qspi_priv structure
+ *
+ * The default settings of the QSPI controller's configurable parameters on
+ * reset are
+ *     - Master mode
+ *     - Baud rate divisor is set to 2
+ *     - Threshold value for TX FIFO not full interrupt is set to 1
+ *     - Flash memory interface mode enabled
+ *     - Size of the word to be transferred as 8 bit
+ * This function performs the following actions
+ *     - Disable and clear all the interrupts
+ *     - Enable manual slave select
+ *     - Enable auto start
+ *     - Deselect all the chip select lines
+ *     - Set the size of the word to be transferred as 32 bit
+ *     - Set the little endian mode of TX FIFO and
+ *     - Enable the QSPI controller
+ */
 static void zynq_qspi_init_hw(struct zynq_qspi_priv *priv)
 {
        struct zynq_qspi_regs *regs = priv->regs;
@@ -143,27 +161,58 @@ static void zynq_qspi_init_hw(struct zynq_qspi_priv *priv)
                ZYNQ_QSPI_CR_MSTREN_MASK;
        writel(confr, &regs->cr);
 
+       /* Disable the LQSPI feature */
+       confr = readl(&regs->lqspicfg);
+       confr &= ~ZYNQ_QSPI_LQSPICFG_LQMODE_MASK;
+       writel(confr, &regs->lqspicfg);
+
        /* Enable SPI */
        writel(ZYNQ_QSPI_ENR_SPI_EN_MASK, &regs->enr);
 }
 
 static int zynq_qspi_probe(struct udevice *bus)
 {
-       struct zynq_qspi_platdata *plat = dev_get_platdata(bus);
+       struct zynq_qspi_plat *plat = dev_get_plat(bus);
        struct zynq_qspi_priv *priv = dev_get_priv(bus);
+       struct clk clk;
+       unsigned long clock;
+       int ret;
 
        priv->regs = plat->regs;
        priv->fifo_depth = ZYNQ_QSPI_FIFO_DEPTH;
 
+       ret = clk_get_by_name(bus, "ref_clk", &clk);
+       if (ret < 0) {
+               dev_err(bus, "failed to get clock\n");
+               return ret;
+       }
+
+       clock = clk_get_rate(&clk);
+       if (IS_ERR_VALUE(clock)) {
+               dev_err(bus, "failed to get rate\n");
+               return clock;
+       }
+
+       ret = clk_enable(&clk);
+       if (ret) {
+               dev_err(bus, "failed to enable clock\n");
+               return ret;
+       }
+
        /* init the zynq spi hw */
        zynq_qspi_init_hw(priv);
 
+       plat->frequency = clock;
+       plat->speed_hz = plat->frequency / 2;
+
+       debug("%s: max-frequency=%d\n", __func__, plat->speed_hz);
+
        return 0;
 }
 
-/*
+/**
  * zynq_qspi_read_data - Copy data to RX buffer
- * @zqspi:     Pointer to the zynq_qspi structure
+ * @priv:      Pointer to the zynq_qspi_priv structure
  * @data:      The 32 bit variable where data is stored
  * @size:      Number of bytes to be copied from data to RX buffer
  */
@@ -206,9 +255,9 @@ static void zynq_qspi_read_data(struct zynq_qspi_priv *priv, u32 data, u8 size)
                priv->bytes_to_receive = 0;
 }
 
-/*
+/**
  * zynq_qspi_write_data - Copy data from TX buffer
- * @zqspi:     Pointer to the zynq_qspi structure
+ * @priv:      Pointer to the zynq_qspi_priv structure
  * @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
  */
@@ -255,6 +304,11 @@ static void zynq_qspi_write_data(struct  zynq_qspi_priv *priv,
                priv->bytes_to_transfer = 0;
 }
 
+/**
+ * zynq_qspi_chipselect - Select or deselect the chip select line
+ * @priv:      Pointer to the zynq_qspi_priv structure
+ * @is_on:     Select(1) or deselect (0) the chip select line
+ */
 static void zynq_qspi_chipselect(struct  zynq_qspi_priv *priv, int is_on)
 {
        u32 confr;
@@ -274,9 +328,10 @@ static void zynq_qspi_chipselect(struct  zynq_qspi_priv *priv, int is_on)
        writel(confr, &regs->cr);
 }
 
-/*
+/**
  * zynq_qspi_fill_tx_fifo - Fills the TX FIFO with as many bytes as possible
- * @zqspi:     Pointer to the zynq_qspi structure
+ * @priv:      Pointer to the zynq_qspi_priv structure
+ * @size:      Number of bytes to be copied to fifo
  */
 static void zynq_qspi_fill_tx_fifo(struct zynq_qspi_priv *priv, u32 size)
 {
@@ -314,9 +369,9 @@ static void zynq_qspi_fill_tx_fifo(struct zynq_qspi_priv *priv, u32 size)
        }
 }
 
-/*
+/**
  * zynq_qspi_irq_poll - Interrupt service routine of the QSPI controller
- * @zqspi:     Pointer to the zynq_qspi structure
+ * @priv:      Pointer to the zynq_qspi structure
  *
  * This function handles TX empty and Mode Fault interrupts only.
  * On TX empty interrupt this function reads the received data from RX FIFO and
@@ -340,7 +395,7 @@ static int zynq_qspi_irq_poll(struct zynq_qspi_priv *priv)
        do {
                status = readl(&regs->isr);
        } while ((status == 0) &&
-               (get_timer(timeout) < CONFIG_SYS_ZYNQ_QSPI_WAIT));
+               (get_timer(timeout) < ZYNQ_QSPI_WAIT));
 
        if (status == 0) {
                printf("zynq_qspi_irq_poll: Timeout!\n");
@@ -402,11 +457,9 @@ static int zynq_qspi_irq_poll(struct zynq_qspi_priv *priv)
        return 0;
 }
 
-/*
+/**
  * zynq_qspi_start_transfer - Initiates the QSPI transfer
- * @qspi:      Pointer to the spi_device structure
- * @transfer:  Pointer to the spi_transfer structure which provide information
- *             about next transfer parameters
+ * @priv:      Pointer to the zynq_qspi_priv structure
  *
  * This function fills the TX FIFO, starts the QSPI transfer, and waits for the
  * transfer to be completed.
@@ -478,7 +531,7 @@ static int zynq_qspi_transfer(struct zynq_qspi_priv *priv)
                break;
        }
 
-       return 0;
+       return status;
 }
 
 static int zynq_qspi_claim_bus(struct udevice *dev)
@@ -508,7 +561,7 @@ static int zynq_qspi_xfer(struct udevice *dev, unsigned int bitlen,
 {
        struct udevice *bus = dev->parent;
        struct zynq_qspi_priv *priv = dev_get_priv(bus);
-       struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
+       struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev);
 
        priv->cs = slave_plat->cs;
        priv->tx_buf = dout;
@@ -516,7 +569,7 @@ static int zynq_qspi_xfer(struct udevice *dev, unsigned int bitlen,
        priv->len = bitlen / 8;
 
        debug("zynq_qspi_xfer: bus:%i cs:%i bitlen:%i len:%i flags:%lx\n",
-             bus->seq, slave_plat->cs, bitlen, priv->len, flags);
+             dev_seq(bus), slave_plat->cs, bitlen, priv->len, flags);
 
        /*
         * Festering sore.
@@ -540,7 +593,7 @@ static int zynq_qspi_xfer(struct udevice *dev, unsigned int bitlen,
 
 static int zynq_qspi_set_speed(struct udevice *bus, uint speed)
 {
-       struct zynq_qspi_platdata *plat = bus->platdata;
+       struct zynq_qspi_plat *plat = dev_get_plat(bus);
        struct zynq_qspi_priv *priv = dev_get_priv(bus);
        struct zynq_qspi_regs *regs = priv->regs;
        uint32_t confr;
@@ -614,8 +667,8 @@ U_BOOT_DRIVER(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),
+       .of_to_plat = zynq_qspi_of_to_plat,
+       .plat_auto      = sizeof(struct zynq_qspi_plat),
+       .priv_auto      = sizeof(struct zynq_qspi_priv),
        .probe  = zynq_qspi_probe,
 };