>-----Original Message-----
>From: Kuldeep Singh <kuldeep.si...@nxp.com>
>Sent: Monday, December 16, 2019 5:19 PM
>To: u-boot@lists.denx.de
>Cc: ja...@amarulasolutions.com; Priyanka Jain <priyanka.j...@nxp.com>;
>s...@denx.de; Ashish Kumar <ashish.ku...@nxp.com>;
>frieder.schre...@kontron.de; Kuldeep Singh <kuldeep.si...@nxp.com>; Ashish
>Kumar <ashish.ku...@nxp.com>
>Subject: [Patch v2 1/7] spi: Transform the FSL QuadSPI driver to use the SPI 
>MEM
>API
>
>To support the SPI MEM API, instead of modifying the existing U-Boot
>driver, this patch adds a port of the existing Linux driver.
>This also has the advantage that porting changes and fixes from Linux
>will be easier.
>Porting of driver left most of the functions unchanged while few of the
>changes are:
>-Remove lock(mutexes) and irq handler as uboot is a single core execution.
>-Remove clock support as the changing spi speed is not supported in
>uboot and nor in linux.
>
>Currently tested on LS1088ARDB, LS1012ARDB, LS1046ARDB, LS1046AFRWY,
>LS1043AQDS, LS1021ATWR, LS2080ARDB
>
>Signed-off-by: Frieder Schrempf <frieder.schre...@kontron.de>
>Signed-off-by: Ashish Kumar <ashish.ku...@nxp.com>
>Signed-off-by: Kuldeep Singh <kuldeep.si...@nxp.com>
>---
> drivers/spi/fsl_qspi.c | 1562 +++++++++++++++-------------------------
> drivers/spi/fsl_qspi.h |  145 ----
> 2 files changed, 593 insertions(+), 1114 deletions(-)
> delete mode 100644 drivers/spi/fsl_qspi.h
>
>diff --git a/drivers/spi/fsl_qspi.c b/drivers/spi/fsl_qspi.c
>index 8e2a09df36..96178c06bc 100644
>--- a/drivers/spi/fsl_qspi.c
>+++ b/drivers/spi/fsl_qspi.c
>@@ -1,1142 +1,766 @@
> // SPDX-License-Identifier: GPL-2.0+
>+
> /*
>- * Copyright 2013-2015 Freescale Semiconductor, Inc.
>+ * Freescale QuadSPI driver.
>+ *
>+ * Copyright (C) 2013 Freescale Semiconductor, Inc.
>+ * Copyright (C) 2018 Bootlin
>+ * Copyright (C) 2018 exceet electronics GmbH
>+ * Copyright (C) 2018 Kontron Electronics GmbH
>+ * Copyright (C) 2019-2020 NXP
Please check copyright format
It seems the changes have been brought from Linux driver.
If yes, it would be good to mention that in File header
>  *
>- * Freescale Quad Serial Peripheral Interface (QSPI) driver
>+ * Based on the original fsl-quadspi.c spi-nor driver.
>+ * Transition to spi-mem in spi-fsl-qspi.c
>  */
>
> #include <common.h>
>-#include <malloc.h>
>-#include <spi.h>
> #include <asm/io.h>
>-#include <linux/sizes.h>
>-#include <linux/iopoll.h>
> #include <dm.h>
>-#include <errno.h>
>-#include <watchdog.h>
>-#include <wait_bit.h>
>-#include "fsl_qspi.h"
>+#include <linux/iopoll.h>
>+#include <linux/sizes.h>
>+#include <spi.h>
>+#include <spi-mem.h>
>
> DECLARE_GLOBAL_DATA_PTR;
>
>-#define OFFSET_BITS_MASK      GENMASK(23, 0)
>-
>-#define FLASH_STATUS_WEL      0x02
>-
>-/* SEQID */
>-#define SEQID_WREN            1
>-#define SEQID_FAST_READ               2
>-#define SEQID_RDSR            3
>-#define SEQID_SE              4
>-#define SEQID_CHIP_ERASE      5
>-#define SEQID_PP              6
>-#define SEQID_RDID            7
>-#define SEQID_BE_4K           8
>-#ifdef CONFIG_SPI_FLASH_BAR
>-#define SEQID_BRRD            9
>-#define SEQID_BRWR            10
>-#define SEQID_RDEAR           11
>-#define SEQID_WREAR           12
>-#endif
>-#define SEQID_WRAR            13
>-#define SEQID_RDAR            14
>-
>-/* QSPI CMD */
>-#define QSPI_CMD_PP           0x02    /* Page program (up to 256 bytes) */
>-#define QSPI_CMD_RDSR         0x05    /* Read status register */
>-#define QSPI_CMD_WREN         0x06    /* Write enable */
>-#define QSPI_CMD_FAST_READ    0x0b    /* Read data bytes (high
>frequency) */
>-#define QSPI_CMD_BE_4K                0x20    /* 4K erase */
>-#define QSPI_CMD_CHIP_ERASE   0xc7    /* Erase whole flash chip */
>-#define QSPI_CMD_SE           0xd8    /* Sector erase (usually 64KiB) */
>-#define QSPI_CMD_RDID         0x9f    /* Read JEDEC ID */
>-
>-/* Used for Micron, winbond and Macronix flashes */
>-#define       QSPI_CMD_WREAR          0xc5    /* EAR register write */
>-#define       QSPI_CMD_RDEAR          0xc8    /* EAR reigster read */
>-
>-/* Used for Spansion flashes only. */
>-#define       QSPI_CMD_BRRD           0x16    /* Bank register read
>*/
>-#define       QSPI_CMD_BRWR           0x17    /* Bank register write
>*/
>-
>-/* Used for Spansion S25FS-S family flash only. */
>-#define QSPI_CMD_RDAR         0x65    /* Read any device register */
>-#define QSPI_CMD_WRAR         0x71    /* Write any device register */
>-
>-/* 4-byte address QSPI CMD - used on Spansion and some Macronix flashes */
>-#define QSPI_CMD_FAST_READ_4B 0x0c    /* Read data bytes (high
>frequency) */
>-#define QSPI_CMD_PP_4B                0x12    /* Page program (up to 256
>bytes) */
>-#define QSPI_CMD_SE_4B                0xdc    /* Sector erase (usually 64KiB)
>*/
>-
>-/* fsl_qspi_platdata flags */
>-#define QSPI_FLAG_REGMAP_ENDIAN_BIG   BIT(0)
>-
>-/* default SCK frequency, unit: HZ */
>-#define FSL_QSPI_DEFAULT_SCK_FREQ     50000000
>-
>-/* QSPI max chipselect signals number */
>-#define FSL_QSPI_MAX_CHIPSELECT_NUM     4
>-
>-/* Controller needs driver to swap endian */
>+/*
>+ * The driver only uses one single LUT entry, that is updated on
>+ * each call of exec_op(). Index 0 is preset at boot with a basic
>+ * read operation, so let's use the last entry (15).
>+ */
>+#define       SEQID_LUT                       15
>+
>+/* Registers used by the driver */
>+#define QUADSPI_MCR                   0x00
>+#define QUADSPI_MCR_RESERVED_MASK     GENMASK(19, 16)
>+#define QUADSPI_MCR_MDIS_MASK         BIT(14)
>+#define QUADSPI_MCR_CLR_TXF_MASK      BIT(11)
>+#define QUADSPI_MCR_CLR_RXF_MASK      BIT(10)
>+#define QUADSPI_MCR_DDR_EN_MASK               BIT(7)
>+#define QUADSPI_MCR_END_CFG_MASK      GENMASK(3, 2)
>+#define QUADSPI_MCR_SWRSTHD_MASK      BIT(1)
>+#define QUADSPI_MCR_SWRSTSD_MASK      BIT(0)
>+
>+#define QUADSPI_IPCR                  0x08
>+#define QUADSPI_IPCR_SEQID(x)         ((x) << 24)
>+#define QUADSPI_FLSHCR                        0x0c
>+#define QUADSPI_FLSHCR_TCSS_MASK      GENMASK(3, 0)
>+#define QUADSPI_FLSHCR_TCSH_MASK      GENMASK(11, 8)
>+#define QUADSPI_FLSHCR_TDH_MASK               GENMASK(17, 16)
>+
>+#define QUADSPI_BUF3CR                        0x1c
>+#define QUADSPI_BUF3CR_ALLMST_MASK    BIT(31)
>+#define QUADSPI_BUF3CR_ADATSZ(x)      ((x) << 8)
>+#define QUADSPI_BUF3CR_ADATSZ_MASK    GENMASK(15, 8)
>+
>+#define QUADSPI_BFGENCR                       0x20
>+#define QUADSPI_BFGENCR_SEQID(x)      ((x) << 12)
>+
>+#define QUADSPI_BUF0IND                       0x30
>+#define QUADSPI_BUF1IND                       0x34
>+#define QUADSPI_BUF2IND                       0x38
>+#define QUADSPI_SFAR                  0x100
>+
>+#define QUADSPI_SMPR                  0x108
>+#define QUADSPI_SMPR_DDRSMP_MASK      GENMASK(18, 16)
>+#define QUADSPI_SMPR_FSDLY_MASK               BIT(6)
>+#define QUADSPI_SMPR_FSPHS_MASK               BIT(5)
>+#define QUADSPI_SMPR_HSENA_MASK               BIT(0)
>+
>+#define QUADSPI_RBCT                  0x110
>+#define QUADSPI_RBCT_WMRK_MASK                GENMASK(4, 0)
>+#define QUADSPI_RBCT_RXBRD_USEIPS     BIT(8)
>+
>+#define QUADSPI_TBDR                  0x154
>+
>+#define QUADSPI_SR                    0x15c
>+#define QUADSPI_SR_IP_ACC_MASK                BIT(1)
>+#define QUADSPI_SR_AHB_ACC_MASK               BIT(2)
>+
>+#define QUADSPI_FR                    0x160
>+#define QUADSPI_FR_TFF_MASK           BIT(0)
>+
>+#define QUADSPI_RSER                  0x164
>+#define QUADSPI_RSER_TFIE             BIT(0)
>+
>+#define QUADSPI_SPTRCLR                       0x16c
>+#define QUADSPI_SPTRCLR_IPPTRC                BIT(8)
>+#define QUADSPI_SPTRCLR_BFPTRC                BIT(0)
>+
>+#define QUADSPI_SFA1AD                        0x180
>+#define QUADSPI_SFA2AD                        0x184
>+#define QUADSPI_SFB1AD                        0x188
>+#define QUADSPI_SFB2AD                        0x18c
>+#define QUADSPI_RBDR(x)                       (0x200 + ((x) * 4))
>+
>+#define QUADSPI_LUTKEY                        0x300
>+#define QUADSPI_LUTKEY_VALUE          0x5AF05AF0
>+
>+#define QUADSPI_LCKCR                 0x304
>+#define QUADSPI_LCKER_LOCK            BIT(0)
>+#define QUADSPI_LCKER_UNLOCK          BIT(1)
>+
>+#define QUADSPI_LUT_BASE              0x310
>+#define QUADSPI_LUT_OFFSET            (SEQID_LUT * 4 * 4)
>+#define QUADSPI_LUT_REG(idx) \
>+      (QUADSPI_LUT_BASE + QUADSPI_LUT_OFFSET + (idx) * 4)
>+
>+/* Instruction set for the LUT register */
>+#define LUT_STOP              0
>+#define LUT_CMD                       1
>+#define LUT_ADDR              2
>+#define LUT_DUMMY             3
>+#define LUT_MODE              4
>+#define LUT_MODE2             5
>+#define LUT_MODE4             6
>+#define LUT_FSL_READ          7
>+#define LUT_FSL_WRITE         8
>+#define LUT_JMP_ON_CS         9
>+#define LUT_ADDR_DDR          10
>+#define LUT_MODE_DDR          11
>+#define LUT_MODE2_DDR         12
>+#define LUT_MODE4_DDR         13
>+#define LUT_FSL_READ_DDR      14
>+#define LUT_FSL_WRITE_DDR     15
>+#define LUT_DATA_LEARN                16
>+
>+/*
>+ * The PAD definitions for LUT register.
>+ *
>+ * The pad stands for the number of IO lines [0:3].
>+ * For example, the quad read needs four IO lines,
>+ * so you should use LUT_PAD(4).
>+ */
>+#define LUT_PAD(x) (fls(x) - 1)
>+
>+/*
>+ * Macro for constructing the LUT entries with the following
>+ * register layout:
>+ *
>+ *  ---------------------------------------------------
>+ *  | INSTR1 | PAD1 | OPRND1 | INSTR0 | PAD0 | OPRND0 |
>+ *  ---------------------------------------------------
>+ */
>+#define LUT_DEF(idx, ins, pad, opr)                                   \
>+      ((((ins) << 10) | ((pad) << 8) | (opr)) << (((idx) % 2) * 16))
>+
>+/* Controller needs driver to swap endianness */
> #define QUADSPI_QUIRK_SWAP_ENDIAN     BIT(0)
>
>-enum fsl_qspi_devtype {
>-      FSL_QUADSPI_VYBRID,
>-      FSL_QUADSPI_IMX6SX,
>-      FSL_QUADSPI_IMX6UL_7D,
>-      FSL_QUADSPI_IMX7ULP,
>-};
>+/* Controller needs 4x internal clock */
>+#define QUADSPI_QUIRK_4X_INT_CLK      BIT(1)
>
>-struct fsl_qspi_devtype_data {
>-      enum fsl_qspi_devtype devtype;
>-      u32 rxfifo;
>-      u32 txfifo;
>-      u32 ahb_buf_size;
>-      u32 driver_data;
>-};
>+/*
>+ * TKT253890, the controller needs the driver to fill the txfifo with
>+ * 16 bytes at least to trigger a data transfer, even though the extra
>+ * data won't be transferred.
>+ */
>+#define QUADSPI_QUIRK_TKT253890               BIT(2)
>
>-/**
>- * struct fsl_qspi_platdata - platform data for Freescale QSPI
>- *
>- * @flags: Flags for QSPI QSPI_FLAG_...
>- * @speed_hz: Default SCK frequency
>- * @reg_base: Base address of QSPI registers
>- * @amba_base: Base address of QSPI memory mapping
>- * @amba_total_size: size of QSPI memory mapping
>- * @flash_num: Number of active slave devices
>- * @num_chipselect: Number of QSPI chipselect signals
>+/* TKT245618, the controller cannot wake up from wait mode */
>+#define QUADSPI_QUIRK_TKT245618               BIT(3)
>+
>+/*
>+ * Controller adds QSPI_AMBA_BASE (base address of the mapped memory)
>+ * internally. No need to add it when setting SFXXAD and SFAR registers
>  */
>-struct fsl_qspi_platdata {
>-      u32 flags;
>-      u32 speed_hz;
>-      fdt_addr_t reg_base;
>-      fdt_addr_t amba_base;
>-      fdt_size_t amba_total_size;
>-      u32 flash_num;
>-      u32 num_chipselect;
>-};
>+#define QUADSPI_QUIRK_BASE_INTERNAL   BIT(4)
>
>-/**
>- * struct fsl_qspi_priv - private data for Freescale QSPI
>- *
>- * @flags: Flags for QSPI QSPI_FLAG_...
>- * @bus_clk: QSPI input clk frequency
>- * @speed_hz: Default SCK frequency
>- * @cur_seqid: current LUT table sequence id
>- * @sf_addr: flash access offset
>- * @amba_base: Base address of QSPI memory mapping of every CS
>- * @amba_total_size: size of QSPI memory mapping
>- * @cur_amba_base: Base address of QSPI memory mapping of current CS
>- * @flash_num: Number of active slave devices
>- * @num_chipselect: Number of QSPI chipselect signals
>- * @regs: Point to QSPI register structure for I/O access
>+/*
>+ * Controller uses TDH bits in register QUADSPI_FLSHCR.
>+ * They need to be set in accordance with the DDR/SDR mode.
>  */
>-struct fsl_qspi_priv {
>-      u32 flags;
>-      u32 bus_clk;
>-      u32 speed_hz;
>-      u32 cur_seqid;
>-      u32 sf_addr;
>-      u32 amba_base[FSL_QSPI_MAX_CHIPSELECT_NUM];
>-      u32 amba_total_size;
>-      u32 cur_amba_base;
>-      u32 flash_num;
>-      u32 num_chipselect;
>-      struct fsl_qspi_regs *regs;
>-      struct fsl_qspi_devtype_data *devtype_data;
>+#define QUADSPI_QUIRK_USE_TDH_SETTING BIT(5)
>+
>+struct fsl_qspi_devtype_data {
>+      unsigned int rxfifo;
>+      unsigned int txfifo;
>+      unsigned int ahb_buf_size;
>+      unsigned int quirks;
>+      bool little_endian;
> };
>
> static const struct fsl_qspi_devtype_data vybrid_data = {
>-      .devtype = FSL_QUADSPI_VYBRID,
>-      .rxfifo = 128,
>-      .txfifo = 64,
>-      .ahb_buf_size = 1024,
>-      .driver_data = QUADSPI_QUIRK_SWAP_ENDIAN,
>+      .rxfifo = SZ_128,
>+      .txfifo = SZ_64,
>+      .ahb_buf_size = SZ_1K,
>+      .quirks = QUADSPI_QUIRK_SWAP_ENDIAN,
>+      .little_endian = true,
> };
>
> static const struct fsl_qspi_devtype_data imx6sx_data = {
>-      .devtype = FSL_QUADSPI_IMX6SX,
>-      .rxfifo = 128,
>-      .txfifo = 512,
>-      .ahb_buf_size = 1024,
>-      .driver_data = 0,
>+      .rxfifo = SZ_128,
>+      .txfifo = SZ_512,
>+      .ahb_buf_size = SZ_1K,
>+      .quirks = QUADSPI_QUIRK_4X_INT_CLK | QUADSPI_QUIRK_TKT245618,
>+      .little_endian = true,
>+};
>+
>+static const struct fsl_qspi_devtype_data imx7d_data = {
>+      .rxfifo = SZ_128,
>+      .txfifo = SZ_512,
>+      .ahb_buf_size = SZ_1K,
>+      .quirks = QUADSPI_QUIRK_TKT253890 | QUADSPI_QUIRK_4X_INT_CLK |
>+                QUADSPI_QUIRK_USE_TDH_SETTING,
>+      .little_endian = true,
>+};
>+
>+static const struct fsl_qspi_devtype_data imx6ul_data = {
>+      .rxfifo = SZ_128,
>+      .txfifo = SZ_512,
>+      .ahb_buf_size = SZ_1K,
>+      .quirks = QUADSPI_QUIRK_TKT253890 | QUADSPI_QUIRK_4X_INT_CLK |
>+                QUADSPI_QUIRK_USE_TDH_SETTING,
>+      .little_endian = true,
> };
>
>-static const struct fsl_qspi_devtype_data imx6ul_7d_data = {
>-      .devtype = FSL_QUADSPI_IMX6UL_7D,
>-      .rxfifo = 128,
>-      .txfifo = 512,
>-      .ahb_buf_size = 1024,
>-      .driver_data = 0,
>+static const struct fsl_qspi_devtype_data ls1021a_data = {
>+      .rxfifo = SZ_128,
>+      .txfifo = SZ_64,
>+      .ahb_buf_size = SZ_1K,
>+      .quirks = 0,
>+      .little_endian = false,
> };
>
>-static const struct fsl_qspi_devtype_data imx7ulp_data = {
>-      .devtype = FSL_QUADSPI_IMX7ULP,
>-      .rxfifo = 64,
>-      .txfifo = 64,
>-      .ahb_buf_size = 128,
>-      .driver_data = 0,
>+static const struct fsl_qspi_devtype_data ls1088a_data = {
>+      .rxfifo = SZ_128,
>+      .txfifo = SZ_128,
>+      .ahb_buf_size = SZ_1K,
>+      .quirks = QUADSPI_QUIRK_TKT253890,
>+      .little_endian = true,
> };
>
>-static u32 qspi_read32(u32 flags, u32 *addr)
>+static const struct fsl_qspi_devtype_data ls2080a_data = {
>+      .rxfifo = SZ_128,
>+      .txfifo = SZ_64,
>+      .ahb_buf_size = SZ_1K,
>+      .quirks = QUADSPI_QUIRK_TKT253890 |
>QUADSPI_QUIRK_BASE_INTERNAL,
>+      .little_endian = true,
>+};
>+
>+struct fsl_qspi {
>+      void __iomem *iobase;
>+      void __iomem *ahb_addr;
>+      u32 memmap_phy;
>+      const struct fsl_qspi_devtype_data *devtype_data;
>+      int selected;
>+};
>+
It would be better to move all declarations to header file. 
<snip>
-Priyanka

Reply via email to