Hi Priyanka,

> -----Original Message-----
> From: Priyanka Jain <priyanka.j...@nxp.com>
> Sent: Tuesday, December 17, 2019 10:38 AM
> To: Kuldeep Singh <kuldeep.si...@nxp.com>; u-boot@lists.denx.de
> Cc: ja...@amarulasolutions.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: RE: [Patch v2 1/7] spi: Transform the FSL QuadSPI driver to use the 
> SPI
> MEM API
> 
> 
> 
> >-----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

Ok. I will mention that information on top.

> >  *
> >- * 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.

Current Linux driver has declarations in the same file and that's why the same 
idea was applied to u-boot as well.

Thanks
Kuldeep

> <snip>
> -Priyanka

Reply via email to