]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
arm64: versal: Add OSPI driver support
authorSiva Durga Prasad Paladugu <siva.durga.paladugu@xilinx.com>
Sat, 11 Aug 2018 08:52:40 +0000 (14:22 +0530)
committerMichal Simek <michal.simek@xilinx.com>
Wed, 27 Feb 2019 07:50:51 +0000 (08:50 +0100)
This patch adds support for OSPI driver to Versal platforms.
It uses cadence qspi driver with octal support and defines
DMA hooks that are required for performing DMA read operations.

Signed-off-by: Siva Durga Prasad Paladugu <siva.durga.paladugu@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
MAINTAINERS
drivers/spi/Kconfig
drivers/spi/Makefile
drivers/spi/cadence_ospi_versal.c [new file with mode: 0644]
include/configs/xilinx_versal.h

index b4d0f148c119e6adae4c1a16298929ec20bca82b..9dcb99e1b14d9270dc3420da79cc65705977e4c8 100644 (file)
@@ -316,6 +316,7 @@ M:  Michal Simek <michal.simek@xilinx.com>
 S:     Maintained
 T:     git git://git.denx.de/u-boot-microblaze.git
 F:     arch/arm/mach-versal/
+F:     drivers/spi/cadence_ospi_versal.c
 
 ARM VERSATILE EXPRESS DRIVERS
 M:     Liviu Dudau <liviu.dudau@foss.arm.com>
index a7bb5b35c294d92edaf000c8d3b8873678eee7fd..4c27c05b7ef22845c386d12e93532090c569bef0 100644 (file)
@@ -87,6 +87,13 @@ config CADENCE_QSPI
          used to access the SPI NOR flash on platforms embedding this
          Cadence IP core.
 
+config CADENCE_OSPI_VERSAL
+       bool "Configure Versal OSPI"
+       depends on ARCH_VERSAL && CADENCE_QSPI
+       help
+         This option is used to enable Versal OSPI DMA operations which
+         are used for ospi flash read using cadence qspi controller.
+
 config DESIGNWARE_SPI
        bool "Designware SPI driver"
        help
index 392a92579578b61652ba7bdef44c0f9f9edeec34..5bf998854bb1bfc2b24f3923ae5a37c459de6210 100644 (file)
@@ -21,6 +21,7 @@ obj-$(CONFIG_BCM63XX_HSSPI) += bcm63xx_hsspi.o
 obj-$(CONFIG_BCM63XX_SPI) += bcm63xx_spi.o
 obj-$(CONFIG_BCMSTB_SPI) += bcmstb_spi.o
 obj-$(CONFIG_CADENCE_QSPI) += cadence_qspi.o cadence_qspi_apb.o
+obj-$(CONFIG_CADENCE_OSPI_VERSAL) += cadence_ospi_versal.o
 obj-$(CONFIG_CF_SPI) += cf_spi.o
 obj-$(CONFIG_DAVINCI_SPI) += davinci_spi.o
 obj-$(CONFIG_DESIGNWARE_SPI) += designware_spi.o
diff --git a/drivers/spi/cadence_ospi_versal.c b/drivers/spi/cadence_ospi_versal.c
new file mode 100644 (file)
index 0000000..ddcacd8
--- /dev/null
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) Copyright 2018 Xilinx
+ *
+ * Cadence QSPI controller DMA operations
+ */
+
+#include <clk.h>
+#include <common.h>
+#include <memalign.h>
+#include <wait_bit.h>
+#include <asm/io.h>
+#include "cadence_qspi.h"
+
+#define CQSPI_DMA_DST_ADDR_REG                 0x1800
+#define CQSPI_DMA_DST_SIZE_REG                 0x1804
+#define CQSPI_DMA_DST_STS_REG                  0x1808
+#define CQSPI_DMA_DST_CTRL_REG                 0x180C
+#define CQSPI_DMA_DST_I_STS_REG                        0x1814
+#define CQSPI_DMA_DST_I_ENBL_REG               0x1818
+#define CQSPI_DMA_DST_I_DISBL_REG              0x181C
+#define CQSPI_DMA_DST_CTRL2_REG                        0x1824
+#define CQSPI_DMA_DST_ADDR_MSB_REG             0x1828
+
+#define CQSPI_DMA_SRC_RD_ADDR_REG              0x1000
+
+#define CQSPI_REG_DMA_PERIPH_CFG               0x20
+#define CQSPI_REG_INDIR_TRIG_ADDR_RANGE                0x80
+#define CQSPI_DFLT_INDIR_TRIG_ADDR_RANGE       6
+#define CQSPI_DFLT_DMA_PERIPH_CFG              0x602
+#define CQSPI_DFLT_DST_CTRL_REG_VAL            0xF43FFA00
+
+#define CQSPI_DMA_DST_I_STS_DONE               BIT(1)
+#define CQSPI_DMA_TIMEOUT                      10000000
+
+void cadence_qspi_apb_dma_read(struct cadence_spi_platdata *plat,
+                              unsigned int n_rx, u8 *rxbuf)
+{
+       writel(CQSPI_DFLT_INDIR_TRIG_ADDR_RANGE,
+              plat->regbase + CQSPI_REG_INDIR_TRIG_ADDR_RANGE);
+       writel(CQSPI_DFLT_DMA_PERIPH_CFG,
+              plat->regbase + CQSPI_REG_DMA_PERIPH_CFG);
+       writel((unsigned long)rxbuf, plat->regbase + CQSPI_DMA_DST_ADDR_REG);
+       writel(0x0, plat->regbase + CQSPI_DMA_SRC_RD_ADDR_REG);
+       writel(roundup(n_rx, 4), plat->regbase + CQSPI_DMA_DST_SIZE_REG);
+       flush_dcache_range((unsigned long)rxbuf, (unsigned long)rxbuf + n_rx);
+       writel(CQSPI_DFLT_DST_CTRL_REG_VAL,
+              plat->regbase + CQSPI_DMA_DST_CTRL_REG);
+}
+
+int cadence_qspi_apb_wait_for_dma_cmplt(struct cadence_spi_platdata *plat)
+{
+       u32 timeout = CQSPI_DMA_TIMEOUT;
+
+       while (!(readl(plat->regbase + CQSPI_DMA_DST_I_STS_REG) &
+                CQSPI_DMA_DST_I_STS_DONE) && timeout--)
+               udelay(1);
+
+       if (!timeout) {
+               printf("DMA timeout\n");
+               return -ETIMEDOUT;
+       }
+
+       writel(readl(plat->regbase + CQSPI_DMA_DST_I_STS_REG),
+              plat->regbase + CQSPI_DMA_DST_I_STS_REG);
+       return 0;
+}
index bfe4c43449ac0badceb3dca5c9bb588d9a6ec7a1..ce548adcd4147cbc713dca78fcb2785df0f5b444 100644 (file)
 # define COUNTER_FREQUENCY     CONFIG_COUNTER_FREQUENCY
 #endif
 
+/*
+ * TODO: This has to be be calculated later
+ * using clock framework.
+ */
+#define CONFIG_CQSPI_REF_CLK   200000000
+
 /* Serial setup */
 #define CONFIG_ARM_DCC
 #define CONFIG_CPU_ARMV8
@@ -66,6 +72,8 @@
 
 #define CONFIG_CLOCKS
 
+#define CONFIG_SF_DEFAULT_SPEED        30000000
+
 #define ENV_MEM_LAYOUT_SETTINGS \
        "fdt_high=10000000\0" \
        "initrd_high=10000000\0" \