This patch adds support to the Atmel Quad SPI controller.

Signed-off-by: Cyrille Pitchen <cyrille.pitc...@atmel.com>
---
 drivers/spi/Kconfig      |   7 +
 drivers/spi/Makefile     |   1 +
 drivers/spi/atmel_qspi.c | 404 +++++++++++++++++++++++++++++++++++++++++++++++
 drivers/spi/atmel_qspi.h | 169 ++++++++++++++++++++
 4 files changed, 581 insertions(+)
 create mode 100644 drivers/spi/atmel_qspi.c
 create mode 100644 drivers/spi/atmel_qspi.h

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index f3f7dbe0897b..73f2e5c26bfb 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -32,6 +32,13 @@ config ATH79_SPI
          uses driver model and requires a device tree binding to operate.
          please refer to doc/device-tree-bindings/spi/spi-ath79.txt.
 
+config ATMEL_QSPI
+       bool "Atmel QSPI driver"
+       depends on ARCH_AT91
+       help
+         Enable the Ateml Quad-SPI (QSPI) driver. This driver can only be
+         used to access SPI NOR flashes.
+
 config ATMEL_SPI
        bool "Atmel SPI driver"
        depends on ARCH_AT91
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index c090562c7732..af75fa41c82f 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -18,6 +18,7 @@ endif
 obj-$(CONFIG_ALTERA_SPI) += altera_spi.o
 obj-$(CONFIG_ATH79_SPI) += ath79_spi.o
 obj-$(CONFIG_ATMEL_DATAFLASH_SPI) += atmel_dataflash_spi.o
+obj-$(CONFIG_ATMEL_QSPI) += atmel_qspi.o
 obj-$(CONFIG_ATMEL_SPI) += atmel_spi.o
 obj-$(CONFIG_CADENCE_QSPI) += cadence_qspi.o cadence_qspi_apb.o
 obj-$(CONFIG_CF_SPI) += cf_spi.o
diff --git a/drivers/spi/atmel_qspi.c b/drivers/spi/atmel_qspi.c
new file mode 100644
index 000000000000..6c265d0a4714
--- /dev/null
+++ b/drivers/spi/atmel_qspi.c
@@ -0,0 +1,404 @@
+/*
+ * Copyright (C) 2017 Atmel Corporation
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <errno.h>
+#include <spi.h>
+#include <asm/io.h>
+#include <mach/clk.h>
+#include "atmel_qspi.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static void atmel_qspi_memcpy_fromio(void *dst, unsigned long src, size_t len)
+{
+       u8 *d = (u8 *)dst;
+
+       while (len--) {
+               *d++ = readb(src);
+               src++;
+       }
+}
+
+static void atmel_qspi_memcpy_toio(unsigned long dst, const void *src,
+                                  size_t len)
+{
+       const u8 *s = (const u8 *)src;
+
+       while (len--) {
+               writeb(*s, dst);
+               dst++;
+               s++;
+       }
+}
+
+static int atmel_qspi_set_ifr_tfrtype(u8 flags, u32 *ifr)
+{
+       u32 ifr_tfrtype;
+
+       switch (flags & SPI_FCMD_TYPE) {
+       case SPI_FCMD_READ:
+               ifr_tfrtype = QSPI_IFR_TFRTYPE_READ_MEMORY;
+               break;
+
+       case SPI_FCMD_WRITE:
+               ifr_tfrtype = QSPI_IFR_TFRTYPE_WRITE_MEMORY;
+               break;
+
+       case SPI_FCMD_ERASE:
+       case SPI_FCMD_WRITE_REG:
+               ifr_tfrtype = QSPI_IFR_TFRTYPE_WRITE;
+               break;
+
+       case SPI_FCMD_READ_REG:
+               ifr_tfrtype = QSPI_IFR_TFRTYPE_READ;
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       *ifr = (*ifr & ~QSPI_IFR_TFRTYPE) | ifr_tfrtype;
+       return 0;
+}
+
+static int atmel_qpsi_set_ifr_width(enum spi_flash_protocol proto, u32 *ifr)
+{
+       u32 ifr_width;
+
+       switch (proto) {
+       case SPI_FPROTO_1_1_1:
+               ifr_width = QSPI_IFR_WIDTH_SINGLE_BIT_SPI;
+               break;
+
+       case SPI_FPROTO_1_1_2:
+               ifr_width = QSPI_IFR_WIDTH_DUAL_OUTPUT;
+               break;
+
+       case SPI_FPROTO_1_2_2:
+               ifr_width = QSPI_IFR_WIDTH_DUAL_IO;
+               break;
+
+       case SPI_FPROTO_2_2_2:
+               ifr_width = QSPI_IFR_WIDTH_DUAL_CMD;
+               break;
+
+       case SPI_FPROTO_1_1_4:
+               ifr_width = QSPI_IFR_WIDTH_QUAD_OUTPUT;
+               break;
+
+       case SPI_FPROTO_1_4_4:
+               ifr_width = QSPI_IFR_WIDTH_QUAD_IO;
+               break;
+
+       case SPI_FPROTO_4_4_4:
+               ifr_width = QSPI_IFR_WIDTH_QUAD_CMD;
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       *ifr = (*ifr & ~QSPI_IFR_WIDTH) | ifr_width;
+       return 0;
+}
+
+static int atmel_qspi_xfer(struct udevice *dev, unsigned int bitlen,
+                          const void *dout, void *din, unsigned long flags)
+{
+       /* This controller can only be used with SPI NOR flashes. */
+       return -EINVAL;
+}
+
+static int atmel_qspi_set_speed(struct udevice *bus, uint hz)
+{
+       struct atmel_qspi_priv *aq = dev_get_priv(bus);
+       u32 scr, scbr, mask, new_value;
+
+       /* Compute the QSPI baudrate */
+       scbr = DIV_ROUND_UP(aq->bus_clk_rate, hz);
+       if (scbr > 0)
+               scbr--;
+
+       new_value = QSPI_SCR_SCBR_(scbr);
+       mask = QSPI_SCR_SCBR;
+
+       scr = qspi_readl(aq, QSPI_SCR);
+       if ((scr & mask) == new_value)
+               return 0;
+
+       scr = (scr & ~mask) | new_value;
+       qspi_writel(aq, QSPI_SCR, scr);
+
+       return 0;
+}
+
+static int atmel_qspi_set_mode(struct udevice *bus, uint mode)
+{
+       struct atmel_qspi_priv *aq = dev_get_priv(bus);
+       u32 scr, mask, new_value;
+
+       new_value = (QSPI_SCR_CPOL_((mode & SPI_CPOL) != 0) |
+                    QSPI_SCR_CPHA_((mode & SPI_CPHA) != 0));
+       mask = (QSPI_SCR_CPOL | QSPI_SCR_CPHA);
+
+       scr = qspi_readl(aq, QSPI_SCR);
+       if ((scr & mask) == new_value)
+               return 0;
+
+       scr = (scr & ~mask) | new_value;
+       qspi_writel(aq, QSPI_SCR, scr);
+
+       return 0;
+}
+
+static bool
+atmel_qspi_is_flash_command_supported(struct udevice *dev,
+                                     const struct spi_flash_command *cmd)
+{
+       return true;
+}
+
+static int atmel_qspi_exec_flash_command(struct udevice *dev,
+                                        const struct spi_flash_command *cmd)
+{
+       struct udevice *bus = dev_get_parent(dev);
+       struct atmel_qspi_priv *aq = dev_get_priv(bus);
+       unsigned int iar, icr, ifr;
+       unsigned int offset;
+       unsigned int imr, sr;
+       unsigned long memaddr;
+       int err;
+
+       iar = 0;
+       icr = 0;
+       ifr = 0;
+
+       err = atmel_qspi_set_ifr_tfrtype(cmd->flags, &ifr);
+       if (err)
+               return err;
+
+       err = atmel_qpsi_set_ifr_width(cmd->proto, &ifr);
+       if (err)
+               return err;
+
+       /* Compute instruction parameters */
+       icr |= QSPI_ICR_INST_(cmd->inst);
+       ifr |= QSPI_IFR_INSTEN;
+
+       /* Compute address parameters. */
+       switch (cmd->addr_len) {
+       case 4:
+               ifr |= QSPI_IFR_ADDRL_32_BIT;
+               /*break;*/ /* fall through the 24bit (3 byte) address case */
+       case 3:
+               iar = cmd->data_len ? 0 : cmd->addr;
+               ifr |= QSPI_IFR_ADDREN;
+               offset = cmd->addr;
+               break;
+       case 0:
+               offset = 0;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* Compute option parameters. */
+       if (cmd->num_mode_cycles) {
+               unsigned int mode_cycle_bits, mode_bits;
+
+               icr |= QSPI_ICR_OPT_(cmd->mode);
+               ifr |= QSPI_IFR_OPTEN;
+
+               switch (ifr & QSPI_IFR_WIDTH) {
+               case QSPI_IFR_WIDTH_SINGLE_BIT_SPI:
+               case QSPI_IFR_WIDTH_DUAL_OUTPUT:
+               case QSPI_IFR_WIDTH_QUAD_OUTPUT:
+                       mode_cycle_bits = 1;
+                       break;
+               case QSPI_IFR_WIDTH_DUAL_IO:
+               case QSPI_IFR_WIDTH_DUAL_CMD:
+                       mode_cycle_bits = 2;
+                       break;
+               case QSPI_IFR_WIDTH_QUAD_IO:
+               case QSPI_IFR_WIDTH_QUAD_CMD:
+                       mode_cycle_bits = 4;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+
+               mode_bits = cmd->num_mode_cycles * mode_cycle_bits;
+               switch (mode_bits) {
+               case 1:
+                       ifr |= QSPI_IFR_OPTL_1BIT;
+                       break;
+
+               case 2:
+                       ifr |= QSPI_IFR_OPTL_2BIT;
+                       break;
+
+               case 4:
+                       ifr |= QSPI_IFR_OPTL_4BIT;
+                       break;
+
+               case 8:
+                       ifr |= QSPI_IFR_OPTL_8BIT;
+                       break;
+
+               default:
+                       return -EINVAL;
+               }
+       }
+
+       /* Set the number of dummy cycles. */
+       if (cmd->num_wait_states)
+               ifr |= QSPI_IFR_NBDUM_(cmd->num_wait_states);
+
+       /* Set data enable. */
+       if (cmd->data_len)
+               ifr |= QSPI_IFR_DATAEN;
+
+       /* Clear pending interrupts. */
+       (void)qspi_readl(aq, QSPI_SR);
+
+       /* Set QSPI Instruction Frame registers. */
+       qspi_writel(aq, QSPI_IAR, iar);
+       qspi_writel(aq, QSPI_ICR, icr);
+       qspi_writel(aq, QSPI_IFR, ifr);
+
+       /* Skip to the final steps if there is no data. */
+       if (!cmd->data_len)
+               goto no_data;
+
+       /* Dummy read of QSPI_IFR to synchronize APB and AHB accesses. */
+       (void)qspi_readl(aq, QSPI_IFR);
+
+       /* Stop here for Continuous Read. */
+       memaddr = (unsigned long)(aq->membase + offset);
+       if (cmd->tx_data)
+               /* Write data. */
+               atmel_qspi_memcpy_toio(memaddr, cmd->tx_data, cmd->data_len);
+       else if (cmd->rx_data)
+               /* Read data. */
+               atmel_qspi_memcpy_fromio(cmd->rx_data, memaddr, cmd->data_len);
+
+       /* Release the chip-select. */
+       qspi_writel(aq, QSPI_CR, QSPI_CR_LASTXFER);
+
+no_data:
+       /* Poll INSTruction End and Chip Select Rise flags. */
+       imr = QSPI_SR_INSTRE | QSPI_SR_CSR;
+       sr = 0;
+       while (sr != (QSPI_SR_INSTRE | QSPI_SR_CSR))
+               sr |= qspi_readl(aq, QSPI_SR) & imr;
+
+       return 0;
+}
+
+
+static const struct dm_spi_ops atmel_qspi_ops = {
+       .xfer                           = atmel_qspi_xfer,
+       .set_speed                      = atmel_qspi_set_speed,
+       .set_mode                       = atmel_qspi_set_mode,
+       .is_flash_command_supported     = atmel_qspi_is_flash_command_supported,
+       .exec_flash_command             = atmel_qspi_exec_flash_command,
+};
+
+static int atmel_qspi_enable_clk(struct udevice *bus)
+{
+       struct atmel_qspi_priv *aq = dev_get_priv(bus);
+       struct clk clk;
+       ulong clk_rate;
+       int ret;
+
+       ret = clk_get_by_index(bus, 0, &clk);
+       if (ret)
+               return -EINVAL;
+
+       ret = clk_enable(&clk);
+       if (ret)
+               goto free_clock;
+
+       clk_rate = clk_get_rate(&clk);
+       if (!clk_rate) {
+               ret = -EINVAL;
+               goto free_clock;
+       }
+
+       aq->bus_clk_rate = clk_rate;
+
+free_clock:
+       clk_free(&clk);
+
+       return ret;
+}
+
+static int atmel_qspi_probe(struct udevice *bus)
+{
+       const struct atmel_qspi_platdata *plat = dev_get_platdata(bus);
+       struct atmel_qspi_priv *aq = dev_get_priv(bus);
+       u32 mr;
+       int ret;
+
+       ret = atmel_qspi_enable_clk(bus);
+       if (ret)
+               return ret;
+
+       aq->regbase = plat->regbase;
+       aq->membase = plat->membase;
+
+       /* Reset the QSPI controler */
+       qspi_writel(aq, QSPI_CR, QSPI_CR_SWRST);
+
+       /* Set the QSPI controller in Serial Memory Mode */
+       mr = (QSPI_MR_NBBITS_8_BIT |
+             QSPI_MR_SMM_MEMORY |
+             QSPI_MR_CSMODE_LASTXFER);
+       qspi_writel(aq, QSPI_MR, mr);
+
+       /* Enable the QSPI controller */
+       qspi_writel(aq, QSPI_CR, QSPI_CR_QSPIEN);
+
+       return 0;
+}
+
+static int atmel_qspi_ofdata_to_platdata(struct udevice *bus)
+{
+       struct atmel_qspi_platdata *plat = dev_get_platdata(bus);
+       const void *blob = gd->fdt_blob;
+       int node = bus->of_offset;
+       u32 data[4];
+       int ret;
+
+       ret = fdtdec_get_int_array(blob, node, "reg", data, ARRAY_SIZE(data));
+       if (ret) {
+               printf("Error: Can't get base addresses (ret=%d)!\n", ret);
+               return -ENODEV;
+       }
+       plat->regbase = (void *)data[0];
+       plat->membase = (void *)data[2];
+
+       return 0;
+}
+
+static const struct udevice_id atmel_qspi_ids[] = {
+       { .compatible = "atmel,sama5d2-qspi" },
+       { }
+};
+
+U_BOOT_DRIVER(atmel_qspi) = {
+       .name           = "atmel_qspi",
+       .id             = UCLASS_SPI,
+       .of_match       = atmel_qspi_ids,
+       .ops            = &atmel_qspi_ops,
+       .ofdata_to_platdata = atmel_qspi_ofdata_to_platdata,
+       .platdata_auto_alloc_size = sizeof(struct atmel_qspi_platdata),
+       .priv_auto_alloc_size = sizeof(struct atmel_qspi_priv),
+       .probe          = atmel_qspi_probe,
+};
diff --git a/drivers/spi/atmel_qspi.h b/drivers/spi/atmel_qspi.h
new file mode 100644
index 000000000000..ee1a14bd726d
--- /dev/null
+++ b/drivers/spi/atmel_qspi.h
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2016
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef __ATMEL_QSPI_H__
+#define __ATMEL_QSPI_H__
+
+/*
+ * Register Definitions
+ */
+#define        QSPI_CR         0x00    /* Control Register */
+#define        QSPI_MR         0x04    /* Mode Register */
+#define        QSPI_RDR        0x08    /* Receive Data Register */
+#define        QSPI_TDR        0x0c    /* Transmit Data Register */
+#define        QSPI_SR         0x10    /* Status Register */
+#define        QSPI_IER        0x14    /* Interrupt Enable Register */
+#define        QSPI_IDR        0x18    /* Interrupt Disable Register */
+#define        QSPI_IMR        0x1c    /* Interrupt Mask Register */
+#define        QSPI_SCR        0x20    /* Serial Clock Register */
+#define        QSPI_IAR        0x30    /* Instruction Address Register */
+#define        QSPI_ICR        0x34    /* Instruction Code Register */
+#define        QSPI_IFR        0x38    /* Instruction Frame Register */
+/* 0x3c Reserved */
+#define        QSPI_SMR        0x40    /* Scrambling Mode Register */
+#define        QSPI_SKR        0x44    /* Scrambling Key Register */
+/* 0x48 ~ 0xe0 */
+#define        QSPI_WPMR       0xe4    /* Write Protection Mode Register */
+#define        QSPI_WPSR       0xe8    /* Write Protection Status Register */
+/* 0xec ~ 0xf8 Reserved */
+/* 0xfc Reserved */
+
+/*
+ * Register Field Definitions
+ */
+/* QSPI_CR */
+#define        QSPI_CR_QSPIEN          BIT(0)  /* QSPI Enable */
+#define        QSPI_CR_QSPIDIS         BIT(1)  /* QSPI Disable */
+#define        QSPI_CR_SWRST           BIT(7)  /* QSPI Software Reset */
+#define        QSPI_CR_LASTXFER        BIT(24) /* Last Transfer */
+
+/* QSPI_MR */
+#define        QSPI_MR_SMM             BIT(0)  /* Serial Memort Mode */
+#define                QSPI_MR_SMM_SPI         0
+#define                QSPI_MR_SMM_MEMORY      QSPI_MR_SMM
+#define        QSPI_MR_LLB             BIT(1)  /* Local Localback Enable */
+#define                QSPI_MR_LLB_DISABLED    0
+#define                QSPI_MR_LLB_ENABLED     QSPI_MR_LLB
+#define        QSPI_MR_WDRBT           BIT(2)  /* Wait Data Read Before 
Transfer */
+#define                QSPI_MR_WDRBT_DISABLED  0
+#define                QSPI_MR_WDRBT_ENABLED   QSPI_MR_WDRBT
+#define        QSPI_MR_SMRM            BIT(3)  /* Serial Memory Register Mode 
*/
+#define                QSPI_MR_SMRM_AHB        0
+#define                QSPI_MR_SMRM_APB        QSPI_MR_SMRM
+#define        QSPI_MR_CSMODE          GENMASK(5, 4)   /* Chip Select Mode */
+#define                QSPI_MR_CSMODE_NOT_RELOADED     (0x0u << 4)
+#define                QSPI_MR_CSMODE_LASTXFER         (0x1u << 4)
+#define                QSPI_MR_CSMODE_SYSTEMATICALLY   (0x2u << 4)
+#define        QSPI_MR_NBBITS          GENMASK(11, 8)  /*
+                                                * Number of Bits Per
+                                                * Transfer
+                                                */
+#define                QSPI_MR_NBBITS_8_BIT            (0x0u << 8)
+#define                QSPI_MR_NBBITS_16_BIT           (0x8u << 8)
+#define        QSPI_MR_DLYBCT          GENMASK(23, 16) /*
+                                                * Delay Between Consecutive
+                                                * Transfers
+                                                */
+#define        QSPI_MR_DLYCS           GENMASK(31, 24) /* Minimum Inactive QCS 
Delay */
+
+/* QSPI_SR */
+#define        QSPI_SR_RDRF            BIT(0)  /* Receive Data Register Full */
+#define        QSPI_SR_TDRE            BIT(1)  /* Transmit Data Register Empty 
*/
+#define        QSPI_SR_TXEMPTY         BIT(2)  /* Transmission Registers Empty 
*/
+#define        QSPI_SR_OVRES           BIT(3)  /* Overrun Error Status */
+#define        QSPI_SR_CSR             BIT(8)  /* Chip Select Rise */
+#define        QSPI_SR_CSS             BIT(9)  /* Chip Select Status */
+#define        QSPI_SR_INSTRE          BIT(10) /* Instruction End Status */
+#define        QSPI_SR_QSPIENS         BIT(24) /* QSPI Enable Status */
+
+/* QSPI_SCR */
+#define        QSPI_SCR_CPOL           BIT(0)  /* Clock Polarity */
+#define        QSPI_SCR_CPOL_(x)       ((x) << 0)
+#define        QSPI_SCR_CPHA           BIT(1)  /* Clock Phase */
+#define        QSPI_SCR_CPHA_(x)       ((x) << 1)
+#define        QSPI_SCR_SCBR           GENMASK(15, 8)  /* Serial Clock Baud 
Rate */
+#define        QSPI_SCR_SCBR_(x)       (((x) << 8) & QSPI_SCR_SCBR)
+#define QSPI_SCR_DLYBS         GENMASK(23, 16)
+#define        QSPI_SCR_DLYBS_(x)      (((x) << 16) & QSPI_SCR_DLYBS)  /*
+                                                                * Delay Before
+                                                                * QSCK
+                                                                */
+
+/* QSPI_ICR */
+#define QSPI_ICR_INST          GENMASK(7, 0)
+#define        QSPI_ICR_INST_(x)       (((x) << 0) & QSPI_ICR_INST)    /*
+                                                                * Instruction
+                                                                * Code
+                                                                */
+#define QSPI_ICR_OPT           GENMASK(23, 16)
+#define        QSPI_ICR_OPT_(x)        (((x) << 16) & QSPI_ICR_OPT)    /*
+                                                                * Option
+                                                                * Code
+                                                                */
+
+/* QSPI_IFR */
+#define        QSPI_IFR_WIDTH          GENMASK(2, 0)   /*
+                                                * Width of Instruction Code,
+                                                * Address, Option Code and Data
+                                                */
+#define                QSPI_IFR_WIDTH_SINGLE_BIT_SPI   (0x0u << 0)
+#define                QSPI_IFR_WIDTH_DUAL_OUTPUT      (0x1u << 0)
+#define                QSPI_IFR_WIDTH_QUAD_OUTPUT      (0x2u << 0)
+#define                QSPI_IFR_WIDTH_DUAL_IO          (0x3u << 0)
+#define                QSPI_IFR_WIDTH_QUAD_IO          (0x4u << 0)
+#define                QSPI_IFR_WIDTH_DUAL_CMD         (0x5u << 0)
+#define                QSPI_IFR_WIDTH_QUAD_CMD         (0x6u << 0)
+#define QSPI_IFR_WIDTH_(x)     (((x) << 0) & QSPI_IFR_WIDTH)
+#define        QSPI_IFR_INSTEN         BIT(4)  /* Instruction Enable*/
+#define        QSPI_IFR_ADDREN         BIT(5)  /* Address Enable*/
+#define        QSPI_IFR_OPTEN          BIT(6)  /* Option Enable*/
+#define        QSPI_IFR_DATAEN         BIT(7)  /* Data Enable*/
+#define        QSPI_IFR_OPTL           GENMASK(9, 8)   /* Option Code Length */
+#define                QSPI_IFR_OPTL_1BIT              (0x0u << 8)
+#define                QSPI_IFR_OPTL_2BIT              (0x1u << 8)
+#define                QSPI_IFR_OPTL_4BIT              (0x2u << 8)
+#define                QSPI_IFR_OPTL_8BIT              (0x3u << 8)
+#define        QSPI_IFR_ADDRL          BIT(10) /* Address Length */
+#define                QSPI_IFR_ADDRL_24_BIT           0
+#define                QSPI_IFR_ADDRL_32_BIT           QSPI_IFR_ADDRL
+#define        QSPI_IFR_TFRTYPE        GENMASK(13, 12) /* Data Transfer Type */
+#define                QSPI_IFR_TFRTYPE_READ           (0x0u << 12)
+#define                QSPI_IFR_TFRTYPE_READ_MEMORY    (0x1u << 12)
+#define                QSPI_IFR_TFRTYPE_WRITE          (0x2u << 12)
+#define                QSPI_IFR_TFRTYPE_WRITE_MEMORY   (0x3u << 12)
+#define QSPI_IFR_TFRTYPE_(x)   (((x) << 12) & QSPI_IFR_TFRTYPE)
+#define        QSPI_IFR_CRM            BIT(14) /* Continuous Read Mode */
+#define QSPI_IFR_NBDUM         GENMASK(20, 16)
+#define        QSPI_IFR_NBDUM_(x)      (((x) << 16) & QSPI_IFR_NBDUM)  /*
+                                                                * Number Of
+                                                                * Dummy Cycles
+                                                                */
+
+
+struct atmel_qspi_platdata {
+       void            *regbase;
+       void            *membase;
+};
+
+struct atmel_qspi_priv {
+       ulong           bus_clk_rate;
+       void            *regbase;
+       void            *membase;
+};
+
+#include <asm/io.h>
+
+static inline u32 qspi_readl(struct atmel_qspi_priv *aq, u32 reg)
+{
+       return readl(aq->regbase + reg);
+}
+
+static inline void qspi_writel(struct atmel_qspi_priv *aq, u32 reg, u32 value)
+{
+       writel(value, aq->regbase + reg);
+}
+
+#endif /* __ATMEL_QSPI_H__ */
-- 
2.7.4

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to