From mboxrd@z Thu Jan 1 00:00:00 1970 From: Peng Fan Date: Wed, 1 Apr 2015 15:19:01 +0800 Subject: [U-Boot] [PATCH v2] dm: spi: Convert Freescale QSPI driver to driver model In-Reply-To: <1427857840-48603-1-git-send-email-haikun.wang@freescale.com> References: <1427857840-48603-1-git-send-email-haikun.wang@freescale.com> Message-ID: <551B9BE5.4020505@freescale.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de Hi Haikun, On 4/1/2015 11:10 AM, Haikun Wang wrote: > Move the Freescale QSPI driver over to driver model. > > Signed-off-by: Haikun Wang > Signed-off-by: Peng Fan > --- > > Changes in v2: > - Fix build fail on mx6sxsabresd_spl issue > - Add configure regmap endian in NO-DM model > > Changes in v1: None. > > drivers/spi/fsl_qspi.c | 985 ++++++++++++++++++++++++++++++++----------------- > 1 file changed, 656 insertions(+), 329 deletions(-) > > diff --git a/drivers/spi/fsl_qspi.c b/drivers/spi/fsl_qspi.c > index 5e0b069..868df5f 100644 > --- a/drivers/spi/fsl_qspi.c > +++ b/drivers/spi/fsl_qspi.c > @@ -1,5 +1,5 @@ > /* > - * Copyright 2013-2014 Freescale Semiconductor, Inc. > + * Copyright 2013-2015 Freescale Semiconductor, Inc. > * > * Freescale Quad Serial Peripheral Interface (QSPI) driver > * > @@ -11,8 +11,12 @@ > #include > #include > #include > +#include > +#include > #include "fsl_qspi.h" > > +DECLARE_GLOBAL_DATA_PTR; > + > #define RX_BUFFER_SIZE 0x80 > #ifdef CONFIG_MX6SX > #define TX_BUFFER_SIZE 0x200 > @@ -63,35 +67,85 @@ > #define QSPI_CMD_PP_4B 0x12 /* Page program (up to 256 bytes) */ > #define QSPI_CMD_SE_4B 0xdc /* Sector erase (usually 64KiB) */ > > -#ifdef CONFIG_SYS_FSL_QSPI_LE > -#define qspi_read32 in_le32 > -#define qspi_write32 out_le32 > -#elif defined(CONFIG_SYS_FSL_QSPI_BE) > -#define qspi_read32 in_be32 > -#define qspi_write32 out_be32 > -#endif > +/* fsl_qspi_platdata flags */ > +#define QSPI_FLAG_REGMAP_ENDIAN_BIG (1 << 0) > > -static unsigned long spi_bases[] = { > - QSPI0_BASE_ADDR, > -#ifdef CONFIG_MX6SX > - QSPI1_BASE_ADDR, > -#endif > -}; > +/* default SCK frequency, unit: HZ */ > +#define FSL_QSPI_DEFAULT_SCK_FREQ 50000000 > > -static unsigned long amba_bases[] = { > - QSPI0_AMBA_BASE, > -#ifdef CONFIG_MX6SX > - QSPI1_AMBA_BASE, > +/* QSPI max chipselect signals number */ > +#define FSL_QSPI_MAX_CHIPSELECT_NUM 4 > + > +#ifdef CONFIG_DM_SPI > +/** > + * 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 > + */ > +struct fsl_qspi_platdata { > + u32 flags; > + u32 speed_hz; > + u32 reg_base; > + u32 amba_base; > + u32 amba_total_size; > + u32 flash_num; > + u32 num_chipselect; > +}; > #endif > + > +/** > + * 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 > + */ > +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; > }; > > +#ifndef CONFIG_DM_SPI > struct fsl_qspi { > struct spi_slave slave; > - unsigned long reg_base; > - unsigned long amba_base; > - u32 sf_addr; > - u8 cur_seqid; > + struct fsl_qspi_priv priv; > }; > +#endif > + > +static u32 qspi_read32(u32 flags, u32 *addr) > +{ > + return flags & QSPI_FLAG_REGMAP_ENDIAN_BIG ? > + in_be32(addr) : in_le32(addr); > +} > + > +static void qspi_write32(u32 flags, u32 *addr, u32 val) > +{ > + flags & QSPI_FLAG_REGMAP_ENDIAN_BIG ? > + out_be32(addr, val) : out_le32(addr, val); > +} > > /* QSPI support swapping the flash read/write data > * in hardware for LS102xA, but not for VF610 */ > @@ -104,131 +158,135 @@ static inline u32 qspi_endian_xchg(u32 data) > #endif > } > > -static inline struct fsl_qspi *to_qspi_spi(struct spi_slave *slave) > -{ > - return container_of(slave, struct fsl_qspi, slave); > -} > - > -static void qspi_set_lut(struct fsl_qspi *qspi) > +static void qspi_set_lut(struct fsl_qspi_priv *priv) > { > - struct fsl_qspi_regs *regs = (struct fsl_qspi_regs *)qspi->reg_base; > + struct fsl_qspi_regs *regs = priv->regs; > u32 lut_base; > > /* Unlock the LUT */ > - qspi_write32(®s->lutkey, LUT_KEY_VALUE); > - qspi_write32(®s->lckcr, QSPI_LCKCR_UNLOCK); > + qspi_write32(priv->flags, ®s->lutkey, LUT_KEY_VALUE); > + qspi_write32(priv->flags, ®s->lckcr, QSPI_LCKCR_UNLOCK); > > /* Write Enable */ > lut_base = SEQID_WREN * 4; > - qspi_write32(®s->lut[lut_base], OPRND0(QSPI_CMD_WREN) | > + qspi_write32(priv->flags, ®s->lut[lut_base], OPRND0(QSPI_CMD_WREN) | > PAD0(LUT_PAD1) | INSTR0(LUT_CMD)); > - qspi_write32(®s->lut[lut_base + 1], 0); > - qspi_write32(®s->lut[lut_base + 2], 0); > - qspi_write32(®s->lut[lut_base + 3], 0); > + qspi_write32(priv->flags, ®s->lut[lut_base + 1], 0); > + qspi_write32(priv->flags, ®s->lut[lut_base + 2], 0); > + qspi_write32(priv->flags, ®s->lut[lut_base + 3], 0); > > /* Fast Read */ > lut_base = SEQID_FAST_READ * 4; > #ifdef CONFIG_SPI_FLASH_BAR > - qspi_write32(®s->lut[lut_base], OPRND0(QSPI_CMD_FAST_READ) | > - PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) | > + qspi_write32(priv->flags, ®s->lut[lut_base], > + OPRND0(QSPI_CMD_FAST_READ) | PAD0(LUT_PAD1) | > + INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) | > PAD1(LUT_PAD1) | INSTR1(LUT_ADDR)); > #else > if (FSL_QSPI_FLASH_SIZE <= SZ_16M) > - qspi_write32(®s->lut[lut_base], OPRND0(QSPI_CMD_FAST_READ) | > - PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) | > - PAD1(LUT_PAD1) | INSTR1(LUT_ADDR)); > + qspi_write32(priv->flags, ®s->lut[lut_base], > + OPRND0(QSPI_CMD_FAST_READ) | PAD0(LUT_PAD1) | > + INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) | > + PAD1(LUT_PAD1) | INSTR1(LUT_ADDR)); > else > - qspi_write32(®s->lut[lut_base], > + qspi_write32(priv->flags, ®s->lut[lut_base], > OPRND0(QSPI_CMD_FAST_READ_4B) | > PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | > OPRND1(ADDR32BIT) | PAD1(LUT_PAD1) | > INSTR1(LUT_ADDR)); > #endif > - qspi_write32(®s->lut[lut_base + 1], OPRND0(8) | PAD0(LUT_PAD1) | > - INSTR0(LUT_DUMMY) | OPRND1(RX_BUFFER_SIZE) | PAD1(LUT_PAD1) | > - INSTR1(LUT_READ)); > - qspi_write32(®s->lut[lut_base + 2], 0); > - qspi_write32(®s->lut[lut_base + 3], 0); > + qspi_write32(priv->flags, ®s->lut[lut_base + 1], > + OPRND0(8) | PAD0(LUT_PAD1) | INSTR0(LUT_DUMMY) | > + OPRND1(RX_BUFFER_SIZE) | PAD1(LUT_PAD1) | > + INSTR1(LUT_READ)); > + qspi_write32(priv->flags, ®s->lut[lut_base + 2], 0); > + qspi_write32(priv->flags, ®s->lut[lut_base + 3], 0); > > /* Read Status */ > lut_base = SEQID_RDSR * 4; > - qspi_write32(®s->lut[lut_base], OPRND0(QSPI_CMD_RDSR) | > + qspi_write32(priv->flags, ®s->lut[lut_base], OPRND0(QSPI_CMD_RDSR) | > PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(1) | > PAD1(LUT_PAD1) | INSTR1(LUT_READ)); > - qspi_write32(®s->lut[lut_base + 1], 0); > - qspi_write32(®s->lut[lut_base + 2], 0); > - qspi_write32(®s->lut[lut_base + 3], 0); > + qspi_write32(priv->flags, ®s->lut[lut_base + 1], 0); > + qspi_write32(priv->flags, ®s->lut[lut_base + 2], 0); > + qspi_write32(priv->flags, ®s->lut[lut_base + 3], 0); > > /* Erase a sector */ > lut_base = SEQID_SE * 4; > #ifdef CONFIG_SPI_FLASH_BAR > - qspi_write32(®s->lut[lut_base], OPRND0(QSPI_CMD_SE) | > + qspi_write32(priv->flags, ®s->lut[lut_base], OPRND0(QSPI_CMD_SE) | > PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) | > PAD1(LUT_PAD1) | INSTR1(LUT_ADDR)); > #else > if (FSL_QSPI_FLASH_SIZE <= SZ_16M) > - qspi_write32(®s->lut[lut_base], OPRND0(QSPI_CMD_SE) | > - PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) | > - PAD1(LUT_PAD1) | INSTR1(LUT_ADDR)); > + qspi_write32(priv->flags, ®s->lut[lut_base], > + OPRND0(QSPI_CMD_SE) | PAD0(LUT_PAD1) | > + INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) | > + PAD1(LUT_PAD1) | INSTR1(LUT_ADDR)); > else > - qspi_write32(®s->lut[lut_base], OPRND0(QSPI_CMD_SE_4B) | > - PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR32BIT) | > - PAD1(LUT_PAD1) | INSTR1(LUT_ADDR)); > + qspi_write32(priv->flags, ®s->lut[lut_base], > + OPRND0(QSPI_CMD_SE_4B) | PAD0(LUT_PAD1) | > + INSTR0(LUT_CMD) | OPRND1(ADDR32BIT) | > + PAD1(LUT_PAD1) | INSTR1(LUT_ADDR)); > #endif > - qspi_write32(®s->lut[lut_base + 1], 0); > - qspi_write32(®s->lut[lut_base + 2], 0); > - qspi_write32(®s->lut[lut_base + 3], 0); > + qspi_write32(priv->flags, ®s->lut[lut_base + 1], 0); > + qspi_write32(priv->flags, ®s->lut[lut_base + 2], 0); > + qspi_write32(priv->flags, ®s->lut[lut_base + 3], 0); > > /* Erase the whole chip */ > lut_base = SEQID_CHIP_ERASE * 4; > - qspi_write32(®s->lut[lut_base], OPRND0(QSPI_CMD_CHIP_ERASE) | > - PAD0(LUT_PAD1) | INSTR0(LUT_CMD)); > - qspi_write32(®s->lut[lut_base + 1], 0); > - qspi_write32(®s->lut[lut_base + 2], 0); > - qspi_write32(®s->lut[lut_base + 3], 0); > + qspi_write32(priv->flags, ®s->lut[lut_base], > + OPRND0(QSPI_CMD_CHIP_ERASE) | > + PAD0(LUT_PAD1) | INSTR0(LUT_CMD)); > + qspi_write32(priv->flags, ®s->lut[lut_base + 1], 0); > + qspi_write32(priv->flags, ®s->lut[lut_base + 2], 0); > + qspi_write32(priv->flags, ®s->lut[lut_base + 3], 0); > > /* Page Program */ > lut_base = SEQID_PP * 4; > #ifdef CONFIG_SPI_FLASH_BAR > - qspi_write32(®s->lut[lut_base], OPRND0(QSPI_CMD_PP) | > + qspi_write32(priv->flags, ®s->lut[lut_base], OPRND0(QSPI_CMD_PP) | > PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) | > PAD1(LUT_PAD1) | INSTR1(LUT_ADDR)); > #else > if (FSL_QSPI_FLASH_SIZE <= SZ_16M) > - qspi_write32(®s->lut[lut_base], OPRND0(QSPI_CMD_PP) | > - PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) | > - PAD1(LUT_PAD1) | INSTR1(LUT_ADDR)); > + qspi_write32(priv->flags, ®s->lut[lut_base], > + OPRND0(QSPI_CMD_PP) | PAD0(LUT_PAD1) | > + INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) | > + PAD1(LUT_PAD1) | INSTR1(LUT_ADDR)); > else > - qspi_write32(®s->lut[lut_base], OPRND0(QSPI_CMD_PP_4B) | > - PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR32BIT) | > - PAD1(LUT_PAD1) | INSTR1(LUT_ADDR)); > + qspi_write32(priv->flags, ®s->lut[lut_base], > + OPRND0(QSPI_CMD_PP_4B) | PAD0(LUT_PAD1) | > + INSTR0(LUT_CMD) | OPRND1(ADDR32BIT) | > + PAD1(LUT_PAD1) | INSTR1(LUT_ADDR)); > #endif > #ifdef CONFIG_MX6SX > /* > * To MX6SX, OPRND0(TX_BUFFER_SIZE) can not work correctly. > * So, Use IDATSZ in IPCR to determine the size and here set 0. > */ > - qspi_write32(®s->lut[lut_base + 1], OPRND0(0) | > + qspi_write32(priv->flags, ®s->lut[lut_base + 1], OPRND0(0) | > PAD0(LUT_PAD1) | INSTR0(LUT_WRITE)); > #else > - qspi_write32(®s->lut[lut_base + 1], OPRND0(TX_BUFFER_SIZE) | > - PAD0(LUT_PAD1) | INSTR0(LUT_WRITE)); > + qspi_write32(priv->flags, ®s->lut[lut_base + 1], > + OPRND0(TX_BUFFER_SIZE) | > + PAD0(LUT_PAD1) | INSTR0(LUT_WRITE)); > #endif > - qspi_write32(®s->lut[lut_base + 2], 0); > - qspi_write32(®s->lut[lut_base + 3], 0); > + qspi_write32(priv->flags, ®s->lut[lut_base + 2], 0); > + qspi_write32(priv->flags, ®s->lut[lut_base + 3], 0); > > /* READ ID */ > lut_base = SEQID_RDID * 4; > - qspi_write32(®s->lut[lut_base], OPRND0(QSPI_CMD_RDID) | > + qspi_write32(priv->flags, ®s->lut[lut_base], OPRND0(QSPI_CMD_RDID) | > PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(8) | > PAD1(LUT_PAD1) | INSTR1(LUT_READ)); > - qspi_write32(®s->lut[lut_base + 1], 0); > - qspi_write32(®s->lut[lut_base + 2], 0); > - qspi_write32(®s->lut[lut_base + 3], 0); > + qspi_write32(priv->flags, ®s->lut[lut_base + 1], 0); > + qspi_write32(priv->flags, ®s->lut[lut_base + 2], 0); > + qspi_write32(priv->flags, ®s->lut[lut_base + 3], 0); > > /* SUB SECTOR 4K ERASE */ > lut_base = SEQID_BE_4K * 4; > - qspi_write32(®s->lut[lut_base], OPRND0(QSPI_CMD_BE_4K) | > + qspi_write32(priv->flags, ®s->lut[lut_base], OPRND0(QSPI_CMD_BE_4K) | > PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) | > PAD1(LUT_PAD1) | INSTR1(LUT_ADDR)); > > @@ -239,28 +297,28 @@ static void qspi_set_lut(struct fsl_qspi *qspi) > * initialization. > */ > lut_base = SEQID_BRRD * 4; > - qspi_write32(®s->lut[lut_base], OPRND0(QSPI_CMD_BRRD) | > + qspi_write32(priv->flags, ®s->lut[lut_base], OPRND0(QSPI_CMD_BRRD) | > PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(1) | > PAD1(LUT_PAD1) | INSTR1(LUT_READ)); > > lut_base = SEQID_BRWR * 4; > - qspi_write32(®s->lut[lut_base], OPRND0(QSPI_CMD_BRWR) | > + qspi_write32(priv->flags, ®s->lut[lut_base], OPRND0(QSPI_CMD_BRWR) | > PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(1) | > PAD1(LUT_PAD1) | INSTR1(LUT_WRITE)); > > lut_base = SEQID_RDEAR * 4; > - qspi_write32(®s->lut[lut_base], OPRND0(QSPI_CMD_RDEAR) | > + qspi_write32(priv->flags, ®s->lut[lut_base], OPRND0(QSPI_CMD_RDEAR) | > PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(1) | > PAD1(LUT_PAD1) | INSTR1(LUT_READ)); > > lut_base = SEQID_WREAR * 4; > - qspi_write32(®s->lut[lut_base], OPRND0(QSPI_CMD_WREAR) | > + qspi_write32(priv->flags, ®s->lut[lut_base], OPRND0(QSPI_CMD_WREAR) | > PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(1) | > PAD1(LUT_PAD1) | INSTR1(LUT_WRITE)); > #endif > /* Lock the LUT */ > - qspi_write32(®s->lutkey, LUT_KEY_VALUE); > - qspi_write32(®s->lckcr, QSPI_LCKCR_LOCK); > + qspi_write32(priv->flags, ®s->lutkey, LUT_KEY_VALUE); > + qspi_write32(priv->flags, ®s->lckcr, QSPI_LCKCR_LOCK); > } > > #if defined(CONFIG_SYS_FSL_QSPI_AHB) > @@ -270,14 +328,14 @@ static void qspi_set_lut(struct fsl_qspi *qspi) > * the wrong data. The spec tells us reset the AHB domain and Serial Flash > * domain at the same time. > */ > -static inline void qspi_ahb_invalid(struct fsl_qspi *q) > +static inline void qspi_ahb_invalid(struct fsl_qspi_priv *priv) > { > - struct fsl_qspi_regs *regs = (struct fsl_qspi_regs *)q->reg_base; > + struct fsl_qspi_regs *regs = priv->regs; > u32 reg; > > - reg = qspi_read32(®s->mcr); > + reg = qspi_read32(priv->flags, ®s->mcr); > reg |= QSPI_MCR_SWRSTHD_MASK | QSPI_MCR_SWRSTSD_MASK; > - qspi_write32(®s->mcr, reg); > + qspi_write32(priv->flags, ®s->mcr, reg); > > /* > * The minimum delay : 1 AHB + 2 SFCK clocks. > @@ -286,46 +344,48 @@ static inline void qspi_ahb_invalid(struct fsl_qspi *q) > udelay(1); > > reg &= ~(QSPI_MCR_SWRSTHD_MASK | QSPI_MCR_SWRSTSD_MASK); > - qspi_write32(®s->mcr, reg); > + qspi_write32(priv->flags, ®s->mcr, reg); > } > > /* Read out the data from the AHB buffer. */ > -static inline void qspi_ahb_read(struct fsl_qspi *q, u8 *rxbuf, int len) > +static inline void qspi_ahb_read(struct fsl_qspi_priv *priv, u8 *rxbuf, int len) > { > - struct fsl_qspi_regs *regs = (struct fsl_qspi_regs *)q->reg_base; > + struct fsl_qspi_regs *regs = priv->regs; > u32 mcr_reg; > > - mcr_reg = qspi_read32(®s->mcr); > + mcr_reg = qspi_read32(priv->flags, ®s->mcr); > > - qspi_write32(®s->mcr, QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK | > + qspi_write32(priv->flags, ®s->mcr, > + QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK | > QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE); > > /* Read out the data directly from the AHB buffer. */ > - memcpy(rxbuf, (u8 *)(q->amba_base + q->sf_addr), len); > + memcpy(rxbuf, (u8 *)(priv->cur_amba_base + priv->sf_addr), len); > > - qspi_write32(®s->mcr, mcr_reg); > + qspi_write32(priv->flags, ®s->mcr, mcr_reg); > } > > -static void qspi_enable_ddr_mode(struct fsl_qspi_regs *regs) > +static void qspi_enable_ddr_mode(struct fsl_qspi_priv *priv) > { > u32 reg, reg2; > + struct fsl_qspi_regs *regs = priv->regs; > > - reg = qspi_read32(®s->mcr); > + reg = qspi_read32(priv->flags, ®s->mcr); > /* Disable the module */ > - qspi_write32(®s->mcr, reg | QSPI_MCR_MDIS_MASK); > + qspi_write32(priv->flags, ®s->mcr, reg | QSPI_MCR_MDIS_MASK); > > /* Set the Sampling Register for DDR */ > - reg2 = qspi_read32(®s->smpr); > + reg2 = qspi_read32(priv->flags, ®s->smpr); > reg2 &= ~QSPI_SMPR_DDRSMP_MASK; > reg2 |= (2 << QSPI_SMPR_DDRSMP_SHIFT); > - qspi_write32(®s->smpr, reg2); > + qspi_write32(priv->flags, ®s->smpr, reg2); > > /* Enable the module again (enable the DDR too) */ > reg |= QSPI_MCR_DDR_EN_MASK; > /* Enable bit 29 for imx6sx */ > reg |= (1 << 29); > > - qspi_write32(®s->mcr, reg); > + qspi_write32(priv->flags, ®s->mcr, reg); > } > > /* > @@ -341,180 +401,103 @@ static void qspi_enable_ddr_mode(struct fsl_qspi_regs *regs) > * causes the controller to clear the buffer, and use the sequence pointed > * by the QUADSPI_BFGENCR[SEQID] to initiate a read from the flash. > */ > -static void qspi_init_ahb_read(struct fsl_qspi_regs *regs) > +static void qspi_init_ahb_read(struct fsl_qspi_priv *priv) > { > + struct fsl_qspi_regs *regs = priv->regs; > + > /* AHB configuration for access buffer 0/1/2 .*/ > - qspi_write32(®s->buf0cr, QSPI_BUFXCR_INVALID_MSTRID); > - qspi_write32(®s->buf1cr, QSPI_BUFXCR_INVALID_MSTRID); > - qspi_write32(®s->buf2cr, QSPI_BUFXCR_INVALID_MSTRID); > - qspi_write32(®s->buf3cr, QSPI_BUF3CR_ALLMST_MASK | > + qspi_write32(priv->flags, ®s->buf0cr, QSPI_BUFXCR_INVALID_MSTRID); > + qspi_write32(priv->flags, ®s->buf1cr, QSPI_BUFXCR_INVALID_MSTRID); > + qspi_write32(priv->flags, ®s->buf2cr, QSPI_BUFXCR_INVALID_MSTRID); > + qspi_write32(priv->flags, ®s->buf3cr, QSPI_BUF3CR_ALLMST_MASK | > (0x80 << QSPI_BUF3CR_ADATSZ_SHIFT)); > > /* We only use the buffer3 */ > - qspi_write32(®s->buf0ind, 0); > - qspi_write32(®s->buf1ind, 0); > - qspi_write32(®s->buf2ind, 0); > + qspi_write32(priv->flags, ®s->buf0ind, 0); > + qspi_write32(priv->flags, ®s->buf1ind, 0); > + qspi_write32(priv->flags, ®s->buf2ind, 0); > > /* > * Set the default lut sequence for AHB Read. > * Parallel mode is disabled. > */ > - qspi_write32(®s->bfgencr, > + qspi_write32(priv->flags, ®s->bfgencr, > SEQID_FAST_READ << QSPI_BFGENCR_SEQID_SHIFT); > > /*Enable DDR Mode*/ > - qspi_enable_ddr_mode(regs); > + qspi_enable_ddr_mode(priv); > } > #endif > > -void spi_init() > -{ > - /* do nothing */ > -} > - > -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, > - unsigned int max_hz, unsigned int mode) > -{ > - struct fsl_qspi *qspi; > - struct fsl_qspi_regs *regs; > - u32 smpr_val; > - u32 total_size; > - > - if (bus >= ARRAY_SIZE(spi_bases)) > - return NULL; > - > - if (cs >= FSL_QSPI_FLASH_NUM) > - return NULL; > - > - qspi = spi_alloc_slave(struct fsl_qspi, bus, cs); > - if (!qspi) > - return NULL; > - > - qspi->reg_base = spi_bases[bus]; > - /* > - * According cs, use different amba_base to choose the > - * corresponding flash devices. > - * > - * If not, only one flash device is used even if passing > - * different cs using `sf probe` > - */ > - qspi->amba_base = amba_bases[bus] + cs * FSL_QSPI_FLASH_SIZE; > - > - qspi->slave.max_write_size = TX_BUFFER_SIZE; > - > - regs = (struct fsl_qspi_regs *)qspi->reg_base; > - qspi_write32(®s->mcr, QSPI_MCR_RESERVED_MASK | QSPI_MCR_MDIS_MASK); > - > - smpr_val = qspi_read32(®s->smpr); > - qspi_write32(®s->smpr, smpr_val & ~(QSPI_SMPR_FSDLY_MASK | > - QSPI_SMPR_FSPHS_MASK | QSPI_SMPR_HSENA_MASK)); > - qspi_write32(®s->mcr, QSPI_MCR_RESERVED_MASK); > - > - total_size = FSL_QSPI_FLASH_SIZE * FSL_QSPI_FLASH_NUM; > - /* > - * Any read access to non-implemented addresses will provide > - * undefined results. > - * > - * In case single die flash devices, TOP_ADDR_MEMA2 and > - * TOP_ADDR_MEMB2 should be initialized/programmed to > - * TOP_ADDR_MEMA1 and TOP_ADDR_MEMB1 respectively - in effect, > - * setting the size of these devices to 0. This would ensure > - * that the complete memory map is assigned to only one flash device. > - */ > - qspi_write32(®s->sfa1ad, FSL_QSPI_FLASH_SIZE | amba_bases[bus]); > - qspi_write32(®s->sfa2ad, FSL_QSPI_FLASH_SIZE | amba_bases[bus]); > - qspi_write32(®s->sfb1ad, total_size | amba_bases[bus]); > - qspi_write32(®s->sfb2ad, total_size | amba_bases[bus]); > - > - qspi_set_lut(qspi); > - > - smpr_val = qspi_read32(®s->smpr); > - smpr_val &= ~QSPI_SMPR_DDRSMP_MASK; > - qspi_write32(®s->smpr, smpr_val); > - qspi_write32(®s->mcr, QSPI_MCR_RESERVED_MASK); > - > -#ifdef CONFIG_SYS_FSL_QSPI_AHB > - qspi_init_ahb_read(regs); > -#endif > - return &qspi->slave; > -} > - > -void spi_free_slave(struct spi_slave *slave) > -{ > - struct fsl_qspi *qspi = to_qspi_spi(slave); > - > - free(qspi); > -} > - > -int spi_claim_bus(struct spi_slave *slave) > -{ > - return 0; > -} > - > #ifdef CONFIG_SPI_FLASH_BAR > /* Bank register read/write, EAR register read/write */ > -static void qspi_op_rdbank(struct fsl_qspi *qspi, u8 *rxbuf, u32 len) > +static void qspi_op_rdbank(struct fsl_qspi_priv *priv, u8 *rxbuf, u32 len) > { > - struct fsl_qspi_regs *regs = (struct fsl_qspi_regs *)qspi->reg_base; > + struct fsl_qspi_regs *regs = priv->regs; > u32 reg, mcr_reg, data, seqid; > > - mcr_reg = qspi_read32(®s->mcr); > - qspi_write32(®s->mcr, QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK | > + mcr_reg = qspi_read32(priv->flags, ®s->mcr); > + qspi_write32(priv->flags, ®s->mcr, > + QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK | > QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE); > - qspi_write32(®s->rbct, QSPI_RBCT_RXBRD_USEIPS); > + qspi_write32(priv->flags, ®s->rbct, QSPI_RBCT_RXBRD_USEIPS); > > - qspi_write32(®s->sfar, qspi->amba_base); > + qspi_write32(priv->flags, ®s->sfar, priv->cur_amba_base); > > - if (qspi->cur_seqid == QSPI_CMD_BRRD) > + if (priv->cur_seqid == QSPI_CMD_BRRD) > seqid = SEQID_BRRD; > else > seqid = SEQID_RDEAR; > > - qspi_write32(®s->ipcr, (seqid << QSPI_IPCR_SEQID_SHIFT) | len); > + qspi_write32(priv->flags, ®s->ipcr, > + (seqid << QSPI_IPCR_SEQID_SHIFT) | len); > > /* Wait previous command complete */ > - while (qspi_read32(®s->sr) & QSPI_SR_BUSY_MASK) > + while (qspi_read32(priv->flags, ®s->sr) & QSPI_SR_BUSY_MASK) > ; > > while (1) { > - reg = qspi_read32(®s->rbsr); > + reg = qspi_read32(priv->flags, ®s->rbsr); > if (reg & QSPI_RBSR_RDBFL_MASK) { > - data = qspi_read32(®s->rbdr[0]); > + data = qspi_read32(priv->flags, ®s->rbdr[0]); > data = qspi_endian_xchg(data); > memcpy(rxbuf, &data, len); > - qspi_write32(®s->mcr, qspi_read32(®s->mcr) | > + qspi_write32(priv->flags, ®s->mcr, > + qspi_read32(priv->flags, ®s->mcr) | > QSPI_MCR_CLR_RXF_MASK); > break; > } > } > > - qspi_write32(®s->mcr, mcr_reg); > + qspi_write32(priv->flags, ®s->mcr, mcr_reg); > } > #endif > > -static void qspi_op_rdid(struct fsl_qspi *qspi, u32 *rxbuf, u32 len) > +static void qspi_op_rdid(struct fsl_qspi_priv *priv, u32 *rxbuf, u32 len) > { > - struct fsl_qspi_regs *regs = (struct fsl_qspi_regs *)qspi->reg_base; > + struct fsl_qspi_regs *regs = priv->regs; > u32 mcr_reg, rbsr_reg, data; > int i, size; > > - mcr_reg = qspi_read32(®s->mcr); > - qspi_write32(®s->mcr, QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK | > - QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE); > - qspi_write32(®s->rbct, QSPI_RBCT_RXBRD_USEIPS); > + mcr_reg = qspi_read32(priv->flags, ®s->mcr); > + qspi_write32(priv->flags, ®s->mcr, > + QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK | > + QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE); > + qspi_write32(priv->flags, ®s->rbct, QSPI_RBCT_RXBRD_USEIPS); > > - qspi_write32(®s->sfar, qspi->amba_base); > + qspi_write32(priv->flags, ®s->sfar, priv->cur_amba_base); > > - qspi_write32(®s->ipcr, (SEQID_RDID << QSPI_IPCR_SEQID_SHIFT) | 0); > - while (qspi_read32(®s->sr) & QSPI_SR_BUSY_MASK) > + qspi_write32(priv->flags, ®s->ipcr, > + (SEQID_RDID << QSPI_IPCR_SEQID_SHIFT) | 0); > + while (qspi_read32(priv->flags, ®s->sr) & QSPI_SR_BUSY_MASK) > ; > > i = 0; > size = len; > while ((RX_BUFFER_SIZE >= size) && (size > 0)) { > - rbsr_reg = qspi_read32(®s->rbsr); > + rbsr_reg = qspi_read32(priv->flags, ®s->rbsr); > if (rbsr_reg & QSPI_RBSR_RDBFL_MASK) { > - data = qspi_read32(®s->rbdr[i]); > + data = qspi_read32(priv->flags, ®s->rbdr[i]); > data = qspi_endian_xchg(data); > memcpy(rxbuf, &data, 4); > rxbuf++; > @@ -523,34 +506,36 @@ static void qspi_op_rdid(struct fsl_qspi *qspi, u32 *rxbuf, u32 len) > } > } > > - qspi_write32(®s->mcr, mcr_reg); > + qspi_write32(priv->flags, ®s->mcr, mcr_reg); > } > > #ifndef CONFIG_SYS_FSL_QSPI_AHB > /* If not use AHB read, read data from ip interface */ > -static void qspi_op_read(struct fsl_qspi *qspi, u32 *rxbuf, u32 len) > +static void qspi_op_read(struct fsl_qspi_priv *priv, u32 *rxbuf, u32 len) > { > - struct fsl_qspi_regs *regs = (struct fsl_qspi_regs *)qspi->reg_base; > + struct fsl_qspi_regs *regs = priv->regs; > u32 mcr_reg, data; > int i, size; > u32 to_or_from; > > - mcr_reg = qspi_read32(®s->mcr); > - qspi_write32(®s->mcr, QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK | > - QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE); > - qspi_write32(®s->rbct, QSPI_RBCT_RXBRD_USEIPS); > + mcr_reg = qspi_read32(priv->flags, ®s->mcr); > + qspi_write32(priv->flags, ®s->mcr, > + QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK | > + QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE); > + qspi_write32(priv->flags, ®s->rbct, QSPI_RBCT_RXBRD_USEIPS); > > - to_or_from = qspi->sf_addr + qspi->amba_base; > + to_or_from = priv->sf_addr + priv->cur_amba_base; > > while (len > 0) { > - qspi_write32(®s->sfar, to_or_from); > + qspi_write32(priv->flags, ®s->sfar, to_or_from); > > size = (len > RX_BUFFER_SIZE) ? > RX_BUFFER_SIZE : len; > > - qspi_write32(®s->ipcr, > - (SEQID_FAST_READ << QSPI_IPCR_SEQID_SHIFT) | size); > - while (qspi_read32(®s->sr) & QSPI_SR_BUSY_MASK) > + qspi_write32(priv->flags, ®s->ipcr, > + (SEQID_FAST_READ << QSPI_IPCR_SEQID_SHIFT) | > + size); > + while (qspi_read32(priv->flags, ®s->sr) & QSPI_SR_BUSY_MASK) > ; > > to_or_from += size; > @@ -558,66 +543,69 @@ static void qspi_op_read(struct fsl_qspi *qspi, u32 *rxbuf, u32 len) > > i = 0; > while ((RX_BUFFER_SIZE >= size) && (size > 0)) { > - data = qspi_read32(®s->rbdr[i]); > + data = qspi_read32(priv->flags, ®s->rbdr[i]); > data = qspi_endian_xchg(data); > memcpy(rxbuf, &data, 4); > rxbuf++; > size -= 4; > i++; > } > - qspi_write32(®s->mcr, qspi_read32(®s->mcr) | > - QSPI_MCR_CLR_RXF_MASK); > + qspi_write32(priv->flags, ®s->mcr, > + qspi_read32(priv->flags, ®s->mcr) | > + QSPI_MCR_CLR_RXF_MASK); > } > > - qspi_write32(®s->mcr, mcr_reg); > + qspi_write32(priv->flags, ®s->mcr, mcr_reg); > } > #endif > > -static void qspi_op_write(struct fsl_qspi *qspi, u8 *txbuf, u32 len) > +static void qspi_op_write(struct fsl_qspi_priv *priv, u8 *txbuf, u32 len) > { > - struct fsl_qspi_regs *regs = (struct fsl_qspi_regs *)qspi->reg_base; > + struct fsl_qspi_regs *regs = priv->regs; > u32 mcr_reg, data, reg, status_reg, seqid; > int i, size, tx_size; > u32 to_or_from = 0; > > - mcr_reg = qspi_read32(®s->mcr); > - qspi_write32(®s->mcr, QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK | > - QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE); > - qspi_write32(®s->rbct, QSPI_RBCT_RXBRD_USEIPS); > + mcr_reg = qspi_read32(priv->flags, ®s->mcr); > + qspi_write32(priv->flags, ®s->mcr, > + QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK | > + QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE); > + qspi_write32(priv->flags, ®s->rbct, QSPI_RBCT_RXBRD_USEIPS); > > status_reg = 0; > while ((status_reg & FLASH_STATUS_WEL) != FLASH_STATUS_WEL) { > - qspi_write32(®s->ipcr, > - (SEQID_WREN << QSPI_IPCR_SEQID_SHIFT) | 0); > - while (qspi_read32(®s->sr) & QSPI_SR_BUSY_MASK) > + qspi_write32(priv->flags, ®s->ipcr, > + (SEQID_WREN << QSPI_IPCR_SEQID_SHIFT) | 0); > + while (qspi_read32(priv->flags, ®s->sr) & QSPI_SR_BUSY_MASK) > ; > > - qspi_write32(®s->ipcr, > - (SEQID_RDSR << QSPI_IPCR_SEQID_SHIFT) | 1); > - while (qspi_read32(®s->sr) & QSPI_SR_BUSY_MASK) > + qspi_write32(priv->flags, ®s->ipcr, > + (SEQID_RDSR << QSPI_IPCR_SEQID_SHIFT) | 1); > + while (qspi_read32(priv->flags, ®s->sr) & QSPI_SR_BUSY_MASK) > ; > > - reg = qspi_read32(®s->rbsr); > + reg = qspi_read32(priv->flags, ®s->rbsr); > if (reg & QSPI_RBSR_RDBFL_MASK) { > - status_reg = qspi_read32(®s->rbdr[0]); > + status_reg = qspi_read32(priv->flags, ®s->rbdr[0]); > status_reg = qspi_endian_xchg(status_reg); > } > - qspi_write32(®s->mcr, > - qspi_read32(®s->mcr) | QSPI_MCR_CLR_RXF_MASK); > + qspi_write32(priv->flags, ®s->mcr, > + qspi_read32(priv->flags, ®s->mcr) | > + QSPI_MCR_CLR_RXF_MASK); > } > > /* Default is page programming */ > seqid = SEQID_PP; > #ifdef CONFIG_SPI_FLASH_BAR > - if (qspi->cur_seqid == QSPI_CMD_BRWR) > + if (priv->cur_seqid == QSPI_CMD_BRWR) > seqid = SEQID_BRWR; > - else if (qspi->cur_seqid == QSPI_CMD_WREAR) > + else if (priv->cur_seqid == QSPI_CMD_WREAR) > seqid = SEQID_WREAR; > #endif > > - to_or_from = qspi->sf_addr + qspi->amba_base; > + to_or_from = priv->sf_addr + priv->cur_amba_base; > > - qspi_write32(®s->sfar, to_or_from); > + qspi_write32(priv->flags, ®s->sfar, to_or_from); > > tx_size = (len > TX_BUFFER_SIZE) ? > TX_BUFFER_SIZE : len; > @@ -626,7 +614,7 @@ static void qspi_op_write(struct fsl_qspi *qspi, u8 *txbuf, u32 len) > for (i = 0; i < size; i++) { > memcpy(&data, txbuf, 4); > data = qspi_endian_xchg(data); > - qspi_write32(®s->tbdr, data); > + qspi_write32(priv->flags, ®s->tbdr, data); > txbuf += 4; > } > > @@ -635,146 +623,273 @@ static void qspi_op_write(struct fsl_qspi *qspi, u8 *txbuf, u32 len) > data = 0; > memcpy(&data, txbuf, size); > data = qspi_endian_xchg(data); > - qspi_write32(®s->tbdr, data); > + qspi_write32(priv->flags, ®s->tbdr, data); > } > > - qspi_write32(®s->ipcr, (seqid << QSPI_IPCR_SEQID_SHIFT) | tx_size); > - while (qspi_read32(®s->sr) & QSPI_SR_BUSY_MASK) > + qspi_write32(priv->flags, ®s->ipcr, > + (seqid << QSPI_IPCR_SEQID_SHIFT) | tx_size); > + while (qspi_read32(priv->flags, ®s->sr) & QSPI_SR_BUSY_MASK) > ; > > - qspi_write32(®s->mcr, mcr_reg); > + qspi_write32(priv->flags, ®s->mcr, mcr_reg); > } > > -static void qspi_op_rdsr(struct fsl_qspi *qspi, u32 *rxbuf) > +static void qspi_op_rdsr(struct fsl_qspi_priv *priv, u32 *rxbuf) > { > - struct fsl_qspi_regs *regs = (struct fsl_qspi_regs *)qspi->reg_base; > + struct fsl_qspi_regs *regs = priv->regs; > u32 mcr_reg, reg, data; > > - mcr_reg = qspi_read32(®s->mcr); > - qspi_write32(®s->mcr, QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK | > - QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE); > - qspi_write32(®s->rbct, QSPI_RBCT_RXBRD_USEIPS); > + mcr_reg = qspi_read32(priv->flags, ®s->mcr); > + qspi_write32(priv->flags, ®s->mcr, > + QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK | > + QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE); > + qspi_write32(priv->flags, ®s->rbct, QSPI_RBCT_RXBRD_USEIPS); > > - qspi_write32(®s->sfar, qspi->amba_base); > + qspi_write32(priv->flags, ®s->sfar, priv->cur_amba_base); > > - qspi_write32(®s->ipcr, > - (SEQID_RDSR << QSPI_IPCR_SEQID_SHIFT) | 0); > - while (qspi_read32(®s->sr) & QSPI_SR_BUSY_MASK) > + qspi_write32(priv->flags, ®s->ipcr, > + (SEQID_RDSR << QSPI_IPCR_SEQID_SHIFT) | 0); > + while (qspi_read32(priv->flags, ®s->sr) & QSPI_SR_BUSY_MASK) > ; > > while (1) { > - reg = qspi_read32(®s->rbsr); > + reg = qspi_read32(priv->flags, ®s->rbsr); > if (reg & QSPI_RBSR_RDBFL_MASK) { > - data = qspi_read32(®s->rbdr[0]); > + data = qspi_read32(priv->flags, ®s->rbdr[0]); > data = qspi_endian_xchg(data); > memcpy(rxbuf, &data, 4); > - qspi_write32(®s->mcr, qspi_read32(®s->mcr) | > - QSPI_MCR_CLR_RXF_MASK); > + qspi_write32(priv->flags, ®s->mcr, > + qspi_read32(priv->flags, ®s->mcr) | > + QSPI_MCR_CLR_RXF_MASK); > break; > } > } > > - qspi_write32(®s->mcr, mcr_reg); > + qspi_write32(priv->flags, ®s->mcr, mcr_reg); > } > > -static void qspi_op_erase(struct fsl_qspi *qspi) > +static void qspi_op_erase(struct fsl_qspi_priv *priv) > { > - struct fsl_qspi_regs *regs = (struct fsl_qspi_regs *)qspi->reg_base; > + struct fsl_qspi_regs *regs = priv->regs; > u32 mcr_reg; > u32 to_or_from = 0; > > - mcr_reg = qspi_read32(®s->mcr); > - qspi_write32(®s->mcr, QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK | > - QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE); > - qspi_write32(®s->rbct, QSPI_RBCT_RXBRD_USEIPS); > + mcr_reg = qspi_read32(priv->flags, ®s->mcr); > + qspi_write32(priv->flags, ®s->mcr, > + QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK | > + QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE); > + qspi_write32(priv->flags, ®s->rbct, QSPI_RBCT_RXBRD_USEIPS); > > - to_or_from = qspi->sf_addr + qspi->amba_base; > - qspi_write32(®s->sfar, to_or_from); > + to_or_from = priv->sf_addr + priv->cur_amba_base; > + qspi_write32(priv->flags, ®s->sfar, to_or_from); > > - qspi_write32(®s->ipcr, > - (SEQID_WREN << QSPI_IPCR_SEQID_SHIFT) | 0); > - while (qspi_read32(®s->sr) & QSPI_SR_BUSY_MASK) > + qspi_write32(priv->flags, ®s->ipcr, > + (SEQID_WREN << QSPI_IPCR_SEQID_SHIFT) | 0); > + while (qspi_read32(priv->flags, ®s->sr) & QSPI_SR_BUSY_MASK) > ; > > - if (qspi->cur_seqid == QSPI_CMD_SE) { > - qspi_write32(®s->ipcr, > + if (priv->cur_seqid == QSPI_CMD_SE) { > + qspi_write32(priv->flags, ®s->ipcr, > (SEQID_SE << QSPI_IPCR_SEQID_SHIFT) | 0); > - } else if (qspi->cur_seqid == QSPI_CMD_BE_4K) { > - qspi_write32(®s->ipcr, > + } else if (priv->cur_seqid == QSPI_CMD_BE_4K) { > + qspi_write32(priv->flags, ®s->ipcr, > (SEQID_BE_4K << QSPI_IPCR_SEQID_SHIFT) | 0); > } > - while (qspi_read32(®s->sr) & QSPI_SR_BUSY_MASK) > + while (qspi_read32(priv->flags, ®s->sr) & QSPI_SR_BUSY_MASK) > ; > > - qspi_write32(®s->mcr, mcr_reg); > + qspi_write32(priv->flags, ®s->mcr, mcr_reg); > } > > -int spi_xfer(struct spi_slave *slave, unsigned int bitlen, > +int qspi_xfer(struct fsl_qspi_priv *priv, unsigned int bitlen, > const void *dout, void *din, unsigned long flags) > { > - struct fsl_qspi *qspi = to_qspi_spi(slave); > u32 bytes = DIV_ROUND_UP(bitlen, 8); > static u32 wr_sfaddr; > u32 txbuf; > > if (dout) { > if (flags & SPI_XFER_BEGIN) { > - qspi->cur_seqid = *(u8 *)dout; > + priv->cur_seqid = *(u8 *)dout; > memcpy(&txbuf, dout, 4); > } > > if (flags == SPI_XFER_END) { > - qspi->sf_addr = wr_sfaddr; > - qspi_op_write(qspi, (u8 *)dout, bytes); > + priv->sf_addr = wr_sfaddr; > + qspi_op_write(priv, (u8 *)dout, bytes); > return 0; > } > > - if (qspi->cur_seqid == QSPI_CMD_FAST_READ) { > - qspi->sf_addr = swab32(txbuf) & OFFSET_BITS_MASK; > - } else if ((qspi->cur_seqid == QSPI_CMD_SE) || > - (qspi->cur_seqid == QSPI_CMD_BE_4K)) { > - qspi->sf_addr = swab32(txbuf) & OFFSET_BITS_MASK; > - qspi_op_erase(qspi); > - } else if (qspi->cur_seqid == QSPI_CMD_PP) > + if (priv->cur_seqid == QSPI_CMD_FAST_READ) { > + priv->sf_addr = swab32(txbuf) & OFFSET_BITS_MASK; > + } else if ((priv->cur_seqid == QSPI_CMD_SE) || > + (priv->cur_seqid == QSPI_CMD_BE_4K)) { > + priv->sf_addr = swab32(txbuf) & OFFSET_BITS_MASK; > + qspi_op_erase(priv); > + } else if (priv->cur_seqid == QSPI_CMD_PP) { > wr_sfaddr = swab32(txbuf) & OFFSET_BITS_MASK; > + } else if ((priv->cur_seqid == QSPI_CMD_BRWR) || > + (priv->cur_seqid == QSPI_CMD_WREAR)) { > #ifdef CONFIG_SPI_FLASH_BAR > - else if ((qspi->cur_seqid == QSPI_CMD_BRWR) || > - (qspi->cur_seqid == QSPI_CMD_WREAR)) { > wr_sfaddr = 0; > - } > #endif > + } > } > > if (din) { > - if (qspi->cur_seqid == QSPI_CMD_FAST_READ) { > + if (priv->cur_seqid == QSPI_CMD_FAST_READ) { > #ifdef CONFIG_SYS_FSL_QSPI_AHB > - qspi_ahb_read(qspi, din, bytes); > + qspi_ahb_read(priv, din, bytes); > #else > - qspi_op_read(qspi, din, bytes); > + qspi_op_read(priv, din, bytes); > #endif > - } > - else if (qspi->cur_seqid == QSPI_CMD_RDID) > - qspi_op_rdid(qspi, din, bytes); > - else if (qspi->cur_seqid == QSPI_CMD_RDSR) > - qspi_op_rdsr(qspi, din); > + } else if (priv->cur_seqid == QSPI_CMD_RDID) > + qspi_op_rdid(priv, din, bytes); > + else if (priv->cur_seqid == QSPI_CMD_RDSR) > + qspi_op_rdsr(priv, din); > #ifdef CONFIG_SPI_FLASH_BAR > - else if ((qspi->cur_seqid == QSPI_CMD_BRRD) || > - (qspi->cur_seqid == QSPI_CMD_RDEAR)) { > - qspi->sf_addr = 0; > - qspi_op_rdbank(qspi, din, bytes); > + else if ((priv->cur_seqid == QSPI_CMD_BRRD) || > + (priv->cur_seqid == QSPI_CMD_RDEAR)) { > + priv->sf_addr = 0; > + qspi_op_rdbank(priv, din, bytes); > } > #endif > } > > #ifdef CONFIG_SYS_FSL_QSPI_AHB > - if ((qspi->cur_seqid == QSPI_CMD_SE) || > - (qspi->cur_seqid == QSPI_CMD_PP) || > - (qspi->cur_seqid == QSPI_CMD_BE_4K) || > - (qspi->cur_seqid == QSPI_CMD_WREAR) || > - (qspi->cur_seqid == QSPI_CMD_BRWR)) > - qspi_ahb_invalid(qspi); > + if ((priv->cur_seqid == QSPI_CMD_SE) || > + (priv->cur_seqid == QSPI_CMD_PP) || > + (priv->cur_seqid == QSPI_CMD_BE_4K) || > + (priv->cur_seqid == QSPI_CMD_WREAR) || > + (priv->cur_seqid == QSPI_CMD_BRWR)) > + qspi_ahb_invalid(priv); > +#endif > + > + return 0; > +} > + > +void qspi_module_disable(struct fsl_qspi_priv *priv, u8 disable) > +{ > + u32 mcr_val; > + > + mcr_val = qspi_read32(priv->flags, &priv->regs->mcr); > + if (disable) > + mcr_val |= QSPI_MCR_MDIS_MASK; > + else > + mcr_val &= ~QSPI_MCR_MDIS_MASK; > + qspi_write32(priv->flags, &priv->regs->mcr, mcr_val); > +} > + > +void qspi_cfg_smpr(struct fsl_qspi_priv *priv, u32 clear_bits, u32 set_bits) > +{ > + u32 smpr_val; > + > + smpr_val = qspi_read32(priv->flags, &priv->regs->smpr); > + smpr_val &= ~clear_bits; > + smpr_val |= set_bits; > + qspi_write32(priv->flags, &priv->regs->smpr, smpr_val); > +} > +#ifndef CONFIG_DM_SPI > +static unsigned long spi_bases[] = { > + QSPI0_BASE_ADDR, > +#ifdef CONFIG_MX6SX > + QSPI1_BASE_ADDR, > +#endif > +}; > + > +static unsigned long amba_bases[] = { > + QSPI0_AMBA_BASE, > +#ifdef CONFIG_MX6SX > + QSPI1_AMBA_BASE, > +#endif > +}; > + > +static inline struct fsl_qspi *to_qspi_spi(struct spi_slave *slave) > +{ > + return container_of(slave, struct fsl_qspi, slave); > +} > + > +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, > + unsigned int max_hz, unsigned int mode) > +{ > + struct fsl_qspi *qspi; > + struct fsl_qspi_regs *regs; > + u32 total_size; > + > + if (bus >= ARRAY_SIZE(spi_bases)) > + return NULL; > + > + if (cs >= FSL_QSPI_FLASH_NUM) > + return NULL; > + > + qspi = spi_alloc_slave(struct fsl_qspi, bus, cs); > + if (!qspi) > + return NULL; > + > +#ifdef CONFIG_SYS_FSL_QSPI_BE > + qspi->priv.flags |= QSPI_FLAG_REGMAP_ENDIAN_BIG; > +#endif > + > + regs = (struct fsl_qspi_regs *)spi_bases[bus]; > + qspi->priv.regs = regs; > + /* > + * According cs, use different amba_base to choose the > + * corresponding flash devices. > + * > + * If not, only one flash device is used even if passing > + * different cs using `sf probe` > + */ > + qspi->priv.cur_amba_base = amba_bases[bus] + cs * FSL_QSPI_FLASH_SIZE; > + > + qspi->slave.max_write_size = TX_BUFFER_SIZE; > + > + qspi_write32(qspi->priv.flags, ®s->mcr, > + QSPI_MCR_RESERVED_MASK | QSPI_MCR_MDIS_MASK); > + > + qspi_cfg_smpr(&qspi->priv, > + ~(QSPI_SMPR_FSDLY_MASK | QSPI_SMPR_DDRSMP_MASK | > + QSPI_SMPR_FSPHS_MASK | QSPI_SMPR_HSENA_MASK), 0); > + > + total_size = FSL_QSPI_FLASH_SIZE * FSL_QSPI_FLASH_NUM; > + /* > + * Any read access to non-implemented addresses will provide > + * undefined results. > + * > + * In case single die flash devices, TOP_ADDR_MEMA2 and > + * TOP_ADDR_MEMB2 should be initialized/programmed to > + * TOP_ADDR_MEMA1 and TOP_ADDR_MEMB1 respectively - in effect, > + * setting the size of these devices to 0. This would ensure > + * that the complete memory map is assigned to only one flash device. > + */ > + qspi_write32(qspi->priv.flags, ®s->sfa1ad, > + FSL_QSPI_FLASH_SIZE | amba_bases[bus]); > + qspi_write32(qspi->priv.flags, ®s->sfa2ad, > + FSL_QSPI_FLASH_SIZE | amba_bases[bus]); > + qspi_write32(qspi->priv.flags, ®s->sfb1ad, > + total_size | amba_bases[bus]); > + qspi_write32(qspi->priv.flags, ®s->sfb2ad, > + total_size | amba_bases[bus]); > + > + qspi_set_lut(&qspi->priv); > + > +#ifdef CONFIG_SYS_FSL_QSPI_AHB > + qspi_init_ahb_read(&qspi->priv); > #endif > > + qspi_module_disable(&qspi->priv, 0); > + > + return &qspi->slave; > +} > + > +void spi_free_slave(struct spi_slave *slave) > +{ > + struct fsl_qspi *qspi = to_qspi_spi(slave); > + > + free(qspi); > +} > + > +int spi_claim_bus(struct spi_slave *slave) > +{ > return 0; > } > > @@ -782,3 +897,215 @@ void spi_release_bus(struct spi_slave *slave) > { > /* Nothing to do */ > } > + > +int spi_xfer(struct spi_slave *slave, unsigned int bitlen, > + const void *dout, void *din, unsigned long flags) > +{ > + struct fsl_qspi *qspi = to_qspi_spi(slave); > + > + return qspi_xfer(&qspi->priv, bitlen, dout, din, flags); > +} > + > +void spi_init(void) > +{ > + /* Nothing to do */ > +} > +#else > +static int fsl_qspi_child_pre_probe(struct udevice *dev) > +{ > + struct spi_slave *slave = dev_get_parentdata(dev); > + > + slave->max_write_size = TX_BUFFER_SIZE; > + > + return 0; > +} > + > +static int fsl_qspi_probe(struct udevice *bus) > +{ > + u32 total_size; > + struct fsl_qspi_platdata *plat = dev_get_platdata(bus); > + struct fsl_qspi_priv *priv = dev_get_priv(bus); > + struct dm_spi_bus *dm_spi_bus; > + > + dm_spi_bus = bus->uclass_priv; > + > + dm_spi_bus->max_hz = plat->speed_hz; > + > + priv->regs = (struct fsl_qspi_regs *)plat->reg_base; > + priv->flags = plat->flags; > + > + priv->speed_hz = plat->speed_hz; > + priv->amba_base[0] = plat->amba_base; > + priv->amba_total_size = plat->amba_total_size; > + priv->flash_num = plat->flash_num; > + priv->num_chipselect = plat->num_chipselect; > + > + qspi_write32(priv->flags, &priv->regs->mcr, > + QSPI_MCR_RESERVED_MASK | QSPI_MCR_MDIS_MASK); > + > + qspi_cfg_smpr(priv, ~(QSPI_SMPR_FSDLY_MASK | QSPI_SMPR_DDRSMP_MASK | > + QSPI_SMPR_FSPHS_MASK | QSPI_SMPR_HSENA_MASK), 0); > + > + total_size = FSL_QSPI_FLASH_SIZE * FSL_QSPI_FLASH_NUM; > + /* > + * Any read access to non-implemented addresses will provide > + * undefined results. > + * > + * In case single die flash devices, TOP_ADDR_MEMA2 and > + * TOP_ADDR_MEMB2 should be initialized/programmed to > + * TOP_ADDR_MEMA1 and TOP_ADDR_MEMB1 respectively - in effect, > + * setting the size of these devices to 0. This would ensure > + * that the complete memory map is assigned to only one flash device. > + */ > + qspi_write32(priv->flags, &priv->regs->sfa1ad, > + FSL_QSPI_FLASH_SIZE | priv->amba_base[0]); > + qspi_write32(priv->flags, &priv->regs->sfa2ad, > + FSL_QSPI_FLASH_SIZE | priv->amba_base[0]); > + qspi_write32(priv->flags, &priv->regs->sfb1ad, > + total_size | priv->amba_base[0]); > + qspi_write32(priv->flags, &priv->regs->sfb2ad, > + total_size | priv->amba_base[0]); > + > + qspi_set_lut(priv); > + > +#ifdef CONFIG_SYS_FSL_QSPI_AHB > + qspi_init_ahb_read(priv); > +#endif > + > + qspi_module_disable(priv, 0); > + > + return 0; > +} > + > +static int fsl_qspi_ofdata_to_platdata(struct udevice *bus) > +{ > + struct reg_data { > + u32 addr; > + u32 size; > + } regs_data[2]; > + struct fsl_qspi_platdata *plat = bus->platdata; > + const void *blob = gd->fdt_blob; > + int node = bus->of_offset; > + int ret, flash_num = 0, subnode; > + > + if (fdtdec_get_bool(blob, node, "big-endian")) > + plat->flags |= QSPI_FLAG_REGMAP_ENDIAN_BIG; > + > + ret = fdtdec_get_int_array(blob, node, "reg", (u32 *)regs_data, > + sizeof(regs_data)/sizeof(u32)); > + if (ret) { > + debug("Error: can't get base addresses (ret = %d)!\n", ret); > + return -ENOMEM; > + } > + > + /* Count flash numbers */ > + fdt_for_each_subnode(blob, subnode, node) > + ++flash_num; > + > + if (flash_num == 0) { > + debug("Error: Missing flashes!\n"); > + return -ENODEV; > + } > + > + plat->speed_hz = fdtdec_get_int(blob, node, "spi-max-frequency", > + FSL_QSPI_DEFAULT_SCK_FREQ); > + plat->num_chipselect = fdtdec_get_int(blob, node, "num-cs", > + FSL_QSPI_MAX_CHIPSELECT_NUM); > + > + plat->reg_base = regs_data[0].addr; > + plat->amba_base = regs_data[1].addr; > + plat->amba_total_size = regs_data[1].size; > + plat->flash_num = flash_num; > + > + debug("%s: regs=<0x%x> <0x%x, 0x%x>, max-frequency=%d, endianess=%s\n", > + __func__, > + plat->reg_base, > + plat->amba_base, > + plat->amba_total_size, > + plat->speed_hz, > + plat->flags & QSPI_FLAG_REGMAP_ENDIAN_BIG ? "be" : "le" > + ); > + > + return 0; > +} > + > +static int fsl_qspi_xfer(struct udevice *dev, unsigned int bitlen, > + const void *dout, void *din, unsigned long flags) > +{ > + struct fsl_qspi_priv *priv; > + struct udevice *bus; > + > + bus = dev->parent; > + priv = dev_get_priv(bus); > + > + return qspi_xfer(priv, bitlen, dout, din, flags); > +} > + > +static int fsl_qspi_claim_bus(struct udevice *dev) > +{ > + struct fsl_qspi_priv *priv; > + struct udevice *bus; > + struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); > + > + bus = dev->parent; > + priv = dev_get_priv(bus); > + > + priv->cur_amba_base = > + priv->amba_base[0] + FSL_QSPI_FLASH_SIZE * slave_plat->cs; > + > + qspi_module_disable(priv, 0); > + > + return 0; > +} > + > +static int fsl_qspi_release_bus(struct udevice *dev) > +{ > + struct fsl_qspi_priv *priv; > + struct udevice *bus; > + > + bus = dev->parent; > + priv = dev_get_priv(bus); > + > + qspi_module_disable(priv, 1); > + > + return 0; > +} > + > +static int fsl_qspi_set_speed(struct udevice *bus, uint speed) > +{ > + /* Nothing to do */ > + return 0; > +} > + > +static int fsl_qspi_set_mode(struct udevice *bus, uint mode) > +{ > + /* Nothing to do */ > + return 0; > +} > + > +static const struct dm_spi_ops fsl_qspi_ops = { > + .claim_bus = fsl_qspi_claim_bus, > + .release_bus = fsl_qspi_release_bus, > + .xfer = fsl_qspi_xfer, > + .set_speed = fsl_qspi_set_speed, > + .set_mode = fsl_qspi_set_mode, > +}; > + > +static const struct udevice_id fsl_qspi_ids[] = { > + { .compatible = "fsl,vf610-qspi" }, > + { .compatible = "fsl,imx6sx-qspi" }, > + { } > +}; > + > +U_BOOT_DRIVER(fsl_qspi) = { > + .name = "fsl_qspi", > + .id = UCLASS_SPI, > + .of_match = fsl_qspi_ids, > + .ops = &fsl_qspi_ops, > + .ofdata_to_platdata = fsl_qspi_ofdata_to_platdata, > + .platdata_auto_alloc_size = sizeof(struct fsl_qspi_platdata), > + .priv_auto_alloc_size = sizeof(struct fsl_qspi_priv), > + .probe = fsl_qspi_probe, > + .child_pre_probe = fsl_qspi_child_pre_probe, > +}; > +#endif Testey-by: Peng Fan Regards, Peng.