From: Wenyou Yang <wenyou.yang@microchip.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v3 8/8] sf: add driver for Atmel QSPI controller
Date: Tue, 25 Jul 2017 15:01:02 +0800 [thread overview]
Message-ID: <20170725070102.1344-9-wenyou.yang@microchip.com> (raw)
In-Reply-To: <20170725070102.1344-1-wenyou.yang@microchip.com>
From: Cyrille Pitchen <cyrille.pitchen@atmel.com>
This patch adds support to the Atmel Quad SPI controller.
Signed-off-by: Cyrille Pitchen <cyrille.pitchen@atmel.com>
Signed-off-by: Wenyou Yang <wenyou.yang@microchip.com>
---
Changes in v3: None
Changes in v2:
- Rebase on the latest u-boot/master(2710d54f5).
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 8a8e8e480f..b3e8cb941e 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 9f8b86de76..358db2b065 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 0000000000..0af7a4dc0a
--- /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 = dev_of_offset(bus);
+ 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 0000000000..ee1a14bd72
--- /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.13.0
next prev parent reply other threads:[~2017-07-25 7:01 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-07-25 7:00 [U-Boot] [PATCH v3 0/8] sf: improve support of (Q)SPI flash memories Wenyou Yang
2017-07-25 7:00 ` [U-Boot] [PATCH v3 1/8] spi: add support of SPI flash commands Wenyou Yang
2017-08-30 13:50 ` Jagan Teki
2017-09-01 0:10 ` Wenyou.Yang at microchip.com
2017-07-25 7:00 ` [U-Boot] [PATCH v3 2/8] sf: describe all SPI flash commands with 'struct spi_flash_command' Wenyou Yang
2017-08-30 14:03 ` Jagan Teki
2017-07-25 7:00 ` [U-Boot] [PATCH v3 3/8] sf: select the relevant SPI flash protocol for read and write commands Wenyou Yang
2017-07-25 7:00 ` [U-Boot] [PATCH v3 4/8] sf: differentiate Page Program 1-1-4 and 1-4-4 Wenyou Yang
2017-07-25 7:00 ` [U-Boot] [PATCH v3 5/8] sf: add 'addr_len' member to 'struct spi_flash' Wenyou Yang
2017-07-25 7:01 ` [U-Boot] [PATCH v3 6/8] sf: add new option to support SPI flash above 16MiB Wenyou Yang
2017-07-25 7:01 ` [U-Boot] [PATCH v3 7/8] sf: add support to Microchip SST26 QSPI memories Wenyou Yang
2017-07-25 7:01 ` Wenyou Yang [this message]
2017-08-30 13:58 ` [U-Boot] [PATCH v3 8/8] sf: add driver for Atmel QSPI controller Jagan Teki
2017-07-31 7:29 ` [U-Boot] [PATCH v3 0/8] sf: improve support of (Q)SPI flash memories Yang, Wenyou
2017-08-11 1:02 ` Yang, Wenyou
2017-08-11 5:14 ` Jagan Teki
2017-08-25 1:17 ` Yang, Wenyou
2017-08-25 16:07 ` Jagan Teki
2017-08-25 16:13 ` Marek Vasut
2017-08-25 16:28 ` Jagan Teki
2017-08-25 16:45 ` Marek Vasut
2017-08-25 23:05 ` Bin Meng
2017-08-26 6:14 ` Jagan Teki
2017-08-26 8:36 ` Marek Vasut
2017-08-26 19:12 ` Tom Rini
2017-08-26 6:34 ` Jagan Teki
2017-08-30 1:58 ` Yang, Wenyou
2017-08-30 6:33 ` Jagan Teki
2017-08-30 3:25 ` Yang, Wenyou
2017-08-30 3:43 ` Bin Meng
2017-08-30 5:27 ` Yang, Wenyou
2017-08-30 5:41 ` Bin Meng
2017-08-30 5:51 ` Yang, Wenyou
2017-08-30 6:30 ` Jagan Teki
2017-08-30 7:47 ` Bin Meng
2017-08-30 13:25 ` Jagan Teki
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170725070102.1344-9-wenyou.yang@microchip.com \
--to=wenyou.yang@microchip.com \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.