qspi: qspi support for mx6sxsabresd
Subsystems (3)
v4 cover qspi: qspi support for mx6sxsabresd
This patch set is to support qspi for mx6sxsabresd board.
To mx6sxsabresd Revb board, 32M flash is used, but in header file, CONFIG_SPI_FLASH_BAR is not defined, and we still use SZ_16M. The LUT initialization qspi_set_lut function uses 32BIT addr, however CONFIG_SPI_FLASH_BAR and 24BIT addr should be used to access bigger than 16MB size flash, and BRRD/BRWR should also be supported. Future patches will fix this.
Since flash opcodes are not recommended to use in driver level, use QSPI_CMD_xx to replace OPCODE_xx. It is qspi controller's feature to program LUT with QSPI_CMD_xx which same value with OPCODE_xx.
Since Revb board's qspi flash support 4K erase, 4K erase is added in driver.
Peng Fan (5):
QuadSPI: use QSPI_CMD_xx instead of flash opcodes
QuadSPI: use correct amba_base
arm:mx6sx add QSPI support
imx:qspi add 4K erase support imx:mx6sxsabresd add qspi support
arch/arm/cpu/armv7/mx6/clock.c | 50 ++++++++++ arch/arm/include/asm/arch-mx6/clock.h | 1 + arch/arm/include/asm/arch-mx6/imx-regs.h | 12 +-- board/freescale/mx6sxsabresd/mx6sxsabresd.c | 40 ++++++++ drivers/spi/fsl_qspi.c | 137 +++++++++++++++++++--------- include/configs/mx6sxsabresd.h | 12 +++ 6 files changed, 205 insertions(+), 47 deletions(-)
Signature · 1 line
1.8.4
PATCH v4 1/5 QuadSPI: use QSPI_CMD_xx instead of flash opcodes
Use QSPI_CMD_xx instead of flash opcodes
---
Changes v4:
None
Changes v3:
Use QSPI_CMD_XX instead of flash opcodes. To fsl qspi controller, the LUT should be pre programmed with QSPI CMD.
Changes v2:
None
drivers/spi/fsl_qspi.c | 64 ++++++++++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 31 deletions(-)
drivers/spi/fsl_qspi.c +33 -31
@@ -29,19 +29,19 @@#define SEQID_PP 6#define SEQID_RDID 7 -/* Flash opcodes */ -#define OPCODE_PP 0x02/* Page program (up to 256 bytes) */ -#define OPCODE_RDSR 0x05/* Read status register */ -#define OPCODE_WREN 0x06/* Write enable */ -#define OPCODE_FAST_READ 0x0b/* Read data bytes (high frequency) */ -#define OPCODE_CHIP_ERASE 0xc7/* Erase whole flash chip */ -#define OPCODE_SE 0xd8/* Sector erase (usually 64KiB) */ -#define OPCODE_RDID 0x9f/* Read JEDEC ID */ - -/* 4-byte address opcodes - used on Spansion and some Macronix flashes */ -#define OPCODE_FAST_READ_4B 0x0c/* Read data bytes (high frequency) */ -#define OPCODE_PP_4B 0x12/* Page program (up to 256 bytes) */ -#define OPCODE_SE_4B 0xdc/* Sector erase (usually 64KiB) */ +/* 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_CHIP_ERASE 0xc7/* Erase whole flash chip */ +#define QSPI_CMD_SE 0xd8/* Sector erase (usually 64KiB) */ +#define QSPI_CMD_RDID 0x9f/* Read JEDEC ID */ + +/* 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) */ #ifdef CONFIG_SYS_FSL_QSPI_LE #define qspi_read32 in_le32
@@ -94,7 +94,7 @@ static void qspi_set_lut(struct fsl_qspi *qspi)/* Write Enable */ lut_base =SEQID_WREN *4 ; -qspi_write32 (®s->lut[lut_base],OPRND0 (OPCODE_WREN ) | +qspi_write32 (®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 );
@@ -103,13 +103,15 @@ static void qspi_set_lut(struct fsl_qspi *qspi)/* Fast Read */ lut_base =SEQID_FAST_READ *4 ;if (FSL_QSPI_FLASH_SIZE <=SZ_16M ) -qspi_write32 (®s->lut[lut_base],OPRND0 (OPCODE_FAST_READ ) | +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 ));else -qspi_write32 (®s->lut[lut_base],OPRND0 (OPCODE_FAST_READ_4B ) | -PAD0 (LUT_PAD1 ) |INSTR0 (LUT_CMD ) |OPRND1 (ADDR32BIT ) | -PAD1 (LUT_PAD1 ) |INSTR1 (LUT_ADDR )); +qspi_write32 (®s->lut[lut_base], +OPRND0 (QSPI_CMD_FAST_READ_4B ) | +PAD0 (LUT_PAD1 ) |INSTR0 (LUT_CMD ) | +OPRND1 (ADDR32BIT ) |PAD1 (LUT_PAD1 ) | +INSTR1 (LUT_ADDR ));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 ));
@@ -118,7 +120,7 @@ static void qspi_set_lut(struct fsl_qspi *qspi)/* Read Status */ lut_base =SEQID_RDSR *4 ; -qspi_write32 (®s->lut[lut_base],OPRND0 (OPCODE_RDSR ) | +qspi_write32 (®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 );
@@ -128,11 +130,11 @@ static void qspi_set_lut(struct fsl_qspi *qspi)/* Erase a sector */ lut_base =SEQID_SE *4 ;if (FSL_QSPI_FLASH_SIZE <=SZ_16M ) -qspi_write32 (®s->lut[lut_base],OPRND0 (OPCODE_SE ) | +qspi_write32 (®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 (OPCODE_SE_4B ) | +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 (®s->lut[lut_base +1 ],0 );
@@ -141,7 +143,7 @@ static void qspi_set_lut(struct fsl_qspi *qspi)/* Erase the whole chip */ lut_base =SEQID_CHIP_ERASE *4 ; -qspi_write32 (®s->lut[lut_base],OPRND0 (OPCODE_CHIP_ERASE ) | +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 );
@@ -150,11 +152,11 @@ static void qspi_set_lut(struct fsl_qspi *qspi)/* Page Program */ lut_base =SEQID_PP *4 ;if (FSL_QSPI_FLASH_SIZE <=SZ_16M ) -qspi_write32 (®s->lut[lut_base],OPRND0 (OPCODE_PP ) | +qspi_write32 (®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 (OPCODE_PP_4B ) | +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(®s->lut[lut_base + 1], OPRND0(TX_BUFFER_SIZE) |
@@ -164,7 +166,7 @@ static void qspi_set_lut(struct fsl_qspi *qspi)/* READ ID */ lut_base =SEQID_RDID *4 ; -qspi_write32 (®s->lut[lut_base],OPRND0 (OPCODE_RDID ) | +qspi_write32 (®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 );
@@ -454,22 +456,22 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen,return 0 ; } -if (qspi->cur_seqid ==OPCODE_FAST_READ ) { +if (qspi->cur_seqid ==QSPI_CMD_FAST_READ ) { qspi->sf_addr =swab32 (txbuf) &OFFSET_BITS_MASK ; - }else if (qspi->cur_seqid ==OPCODE_SE ) { + }else if (qspi->cur_seqid ==QSPI_CMD_SE ) { qspi->sf_addr =swab32 (txbuf) &OFFSET_BITS_MASK ;qspi_op_se (qspi); - }else if (qspi->cur_seqid ==OPCODE_PP ) { + }else if (qspi->cur_seqid ==QSPI_CMD_PP ) { pp_sfaddr =swab32 (txbuf) &OFFSET_BITS_MASK ; } }if (din) { -if (qspi->cur_seqid ==OPCODE_FAST_READ ) +if (qspi->cur_seqid ==QSPI_CMD_FAST_READ )qspi_op_read (qspi, din, bytes); -else if (qspi->cur_seqid ==OPCODE_RDID ) +else if (qspi->cur_seqid ==QSPI_CMD_RDID )qspi_op_rdid (qspi, din, bytes); -else if (qspi->cur_seqid ==OPCODE_RDSR ) +else if (qspi->cur_seqid ==QSPI_CMD_RDSR )qspi_op_rdsr (qspi, din); }
Signature · 1 line
1.8.4
PATCH v4 2/5 QuadSPI: use correct amba_base
In reply to Peng FanAccording cs, use different amba_base to choose the corresponding flash devices. If not, sf probe 1:0 and sf probe 1:1 will choose the same flash device, but not different flash devices.
---
Changes v4:
None
Changes v3:
None
Changes v2:
None
drivers/spi/fsl_qspi.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-)
drivers/spi/fsl_qspi.c +25 -5
@@ -194,12 +194,22 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,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]; - qspi->amba_base = amba_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 ;
@@ -212,10 +222,20 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,qspi_write32 (®s->mcr,QSPI_MCR_RESERVED_MASK ); total_size =FSL_QSPI_FLASH_SIZE *FSL_QSPI_FLASH_NUM ; -qspi_write32 (®s->sfa1ad,FSL_QSPI_FLASH_SIZE | qspi->amba_base); -qspi_write32 (®s->sfa2ad,FSL_QSPI_FLASH_SIZE | qspi->amba_base); -qspi_write32 (®s->sfb1ad, total_size | qspi->amba_base); -qspi_write32 (®s->sfb2ad, total_size | qspi->amba_base); +/* +* 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);
Signature · 1 line
1.8.4
PATCH v4 3/5 arm:mx6sx add QSPI support
In reply to Peng FanAdd QSPI support for mx6solox.
---
Changes v4:
None
Changes v3:
None
Changes v2:
Take Fabio's suggestion, split soc code and board code into two patches.
arch/arm/cpu/armv7/mx6/clock.c | 50 ++++++++++++++++++++++++++++++++ arch/arm/include/asm/arch-mx6/clock.h | 1 + arch/arm/include/asm/arch-mx6/imx-regs.h | 12 ++++---- drivers/spi/fsl_qspi.c | 19 ++++++++++++ 4 files changed, 76 insertions(+), 6 deletions(-)
arch/arm/cpu/armv7/mx6/clock.c +50 -0
@@ -434,6 +434,56 @@ static u32 get_mmdc_ch0_clk(void) }#endif +#ifdef CONFIG_MX6SX +/* qspi_num can be from 0 - 1 */ +void enable_qspi_clk (int qspi_num) +{ +u32 reg =0 ; +/* Enable QuadSPI clock */ +switch (qspi_num) { +case 0 : +/* disable the clock gate */ +clrbits_le32 (&imx_ccm->CCGR3,MXC_CCM_CCGR3_QSPI1_MASK ); + +/* set 50M : (50 = 396 / 2 / 4) */ + reg =readl (&imx_ccm->cscmr1); + reg &= ~(MXC_CCM_CSCMR1_QSPI1_PODF_MASK | +MXC_CCM_CSCMR1_QSPI1_CLK_SEL_MASK ); + reg |= ((1 <<MXC_CCM_CSCMR1_QSPI1_PODF_OFFSET ) | + (2 <<MXC_CCM_CSCMR1_QSPI1_CLK_SEL_OFFSET )); +writel (reg, &imx_ccm->cscmr1); + +/* enable the clock gate */ +setbits_le32 (&imx_ccm->CCGR3,MXC_CCM_CCGR3_QSPI1_MASK ); +break ; +case 1 : +/* +* disable the clock gate +* QSPI2 and GPMI_BCH_INPUT_GPMI_IO share the same clock gate, +* disable both of them. +*/ +clrbits_le32 (&imx_ccm->CCGR4,MXC_CCM_CCGR4_QSPI2_ENFC_MASK | +MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK ); + +/* set 50M : (50 = 396 / 2 / 4) */ + reg =readl (&imx_ccm->cs2cdr); + reg &= ~(MXC_CCM_CS2CDR_QSPI2_CLK_PODF_MASK | +MXC_CCM_CS2CDR_QSPI2_CLK_PRED_MASK | +MXC_CCM_CS2CDR_QSPI2_CLK_SEL_MASK ); + reg |= (MXC_CCM_CS2CDR_QSPI2_CLK_PRED (0x1 ) | +MXC_CCM_CS2CDR_QSPI2_CLK_SEL (0x3 )); +writel (reg, &imx_ccm->cs2cdr); + +/*enable the clock gate*/ +setbits_le32 (&imx_ccm->CCGR4,MXC_CCM_CCGR4_QSPI2_ENFC_MASK | +MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK ); +break ; +default : +break ; + } +} +#endif +#ifdef CONFIG_FEC_MXC int enable_fec_anatop_clock (enum enet_freq freq) {
arch/arm/include/asm/arch-mx6/clock.h +1 -0
@@ -67,5 +67,6 @@ int enable_spi_clk(unsigned char enable, unsigned spi_num);void enable_ipu_clock (void );int enable_fec_anatop_clock (enum enet_freq freq);void enable_enet_clk (unsigned char enable); +void enable_qspi_clk (int qspi_num);void enable_thermal_clk (void );#endif /* __ASM_ARCH_CLOCK_H */
arch/arm/include/asm/arch-mx6/imx-regs.h +6 -6
@@ -92,10 +92,10 @@#define AIPS3_END_ADDR 0x022FFFFF#define WEIM_ARB_BASE_ADDR 0x50000000#define WEIM_ARB_END_ADDR 0x57FFFFFF -#define QSPI1_ARB_BASE_ADDR 0x60000000 -#define QSPI1_ARB_END_ADDR 0x6FFFFFFF -#define QSPI2_ARB_BASE_ADDR 0x70000000 -#define QSPI2_ARB_END_ADDR 0x7FFFFFFF +#define QSPI0_AMBA_BASE 0x60000000 +#define QSPI0_AMBA_END 0x6FFFFFFF +#define QSPI1_AMBA_BASE 0x70000000 +#define QSPI1_AMBA_END 0x7FFFFFFF#else #define SATA_ARB_BASE_ADDR 0x02200000#define SATA_ARB_END_ADDR 0x02203FFF
@@ -262,8 +262,8 @@#define AUDMUX_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x58000)#ifdef CONFIG_MX6SX #define SAI2_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x5C000) -#define QSPI1_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x60000) -#define QSPI2_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x64000) +#define QSPI0_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x60000) +#define QSPI1_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x64000)#else #define MIPI_CSI2_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x5C000)#define MIPI_DSI_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x60000)
drivers/spi/fsl_qspi.c +19 -0
@@ -14,7 +14,11 @@#include "fsl_qspi.h" #define RX_BUFFER_SIZE 0x80 +#ifdef CONFIG_MX6SX +#define TX_BUFFER_SIZE 0x200 +#else #define TX_BUFFER_SIZE 0x40 +#endif #define OFFSET_BITS_MASK 0x00ffffff
@@ -53,10 +57,16 @@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 };struct fsl_qspi {
@@ -159,8 +169,17 @@ static void qspi_set_lut(struct fsl_qspi *qspi)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 )); +#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 ) | +PAD0 (LUT_PAD1 ) |INSTR0 (LUT_WRITE )); +#else qspi_write32 (®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 );
Signature · 1 line
1.8.4
PATCH v4 4/5 imx:qspi add 4K erase support
In reply to Peng FanAdd 4k erase command support for qspi driver. reuse the 64k erase function, but change the function name from qspi_op_se to qspi_op_erase, since it supports 64k and 4k erase.
---
Changes v4:
New patch in v4. This patch is to support 4k erase.
drivers/spi/fsl_qspi.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-)
drivers/spi/fsl_qspi.c +19 -5
@@ -32,12 +32,14 @@#define SEQID_CHIP_ERASE 5#define SEQID_PP 6#define SEQID_RDID 7 +#define SEQID_BE_4K 8/* 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 */
@@ -192,6 +194,12 @@ static void qspi_set_lut(struct fsl_qspi *qspi)qspi_write32 (®s->lut[lut_base +2 ],0 );qspi_write32 (®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 ) | +PAD0 (LUT_PAD1 ) |INSTR0 (LUT_CMD ) |OPRND1 (ADDR24BIT ) | +PAD1 (LUT_PAD1 ) |INSTR1 (LUT_ADDR )); +/* Lock the LUT */ qspi_write32 (®s->lutkey,LUT_KEY_VALUE );qspi_write32 (®s->lckcr,QSPI_LCKCR_LOCK );
@@ -450,7 +458,7 @@ static void qspi_op_rdsr(struct fsl_qspi *qspi, u32 *rxbuf)qspi_write32 (®s->mcr, mcr_reg); } -static void qspi_op_se (struct fsl_qspi *qspi) +static void qspi_op_erase (struct fsl_qspi *qspi) {struct fsl_qspi_regs *regs = (struct fsl_qspi_regs *)qspi->reg_base;u32 mcr_reg;
@@ -469,8 +477,13 @@ static void qspi_op_se(struct fsl_qspi *qspi)while (qspi_read32 (®s->sr) &QSPI_SR_BUSY_MASK ) ; -qspi_write32 (®s->ipcr, - (SEQID_SE <<QSPI_IPCR_SEQID_SHIFT ) |0 ); +if (qspi->cur_seqid ==QSPI_CMD_SE ) { +qspi_write32 (®s->ipcr, + (SEQID_SE <<QSPI_IPCR_SEQID_SHIFT ) |0 ); + }else if (qspi->cur_seqid ==QSPI_CMD_BE_4K ) { +qspi_write32 (®s->ipcr, + (SEQID_BE_4K <<QSPI_IPCR_SEQID_SHIFT ) |0 ); + }while (qspi_read32 (®s->sr) &QSPI_SR_BUSY_MASK ) ;
@@ -497,9 +510,10 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen,if (qspi->cur_seqid ==QSPI_CMD_FAST_READ ) { qspi->sf_addr =swab32 (txbuf) &OFFSET_BITS_MASK ; - }else if (qspi->cur_seqid ==QSPI_CMD_SE ) { + }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_se (qspi); +qspi_op_erase (qspi); }else if (qspi->cur_seqid ==QSPI_CMD_PP ) { pp_sfaddr =swab32 (txbuf) &OFFSET_BITS_MASK ; }
Signature · 1 line
1.8.4
PATCH v4 5/5 imx:mx6sxsabresd add qspi support
In reply to Peng FanConfigure the pad setting and enable qspi clock to support qspi flashes access.
Add QSPI related macro in configuration header file.
---
Changes v4:
None
Changes v3:
None
Changes v2:
Take Fabio's suggestion, split soc code and board code into two patches.
board/freescale/mx6sxsabresd/mx6sxsabresd.c | 40 +++++++++++++++++++++++++++++ include/configs/mx6sxsabresd.h | 12 +++++++++ 2 files changed, 52 insertions(+)
board/freescale/mx6sxsabresd/mx6sxsabresd.c +40 -0
@@ -371,6 +371,42 @@ int board_mmc_init(bd_t *bis)return 0 ; } +#ifdef CONFIG_FSL_QSPI + +#define QSPI_PAD_CTRL1 \ + (PAD_CTL_SRE_FAST | PAD_CTL_SPEED_HIGH | \ + PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_47K_UP | PAD_CTL_DSE_40ohm) + +static iomux_v3_cfg_t const quadspi_pads[] = { +MX6_PAD_NAND_WP_B__QSPI2_A_DATA_0 |MUX_PAD_CTRL (QSPI_PAD_CTRL1 ), +MX6_PAD_NAND_READY_B__QSPI2_A_DATA_1 |MUX_PAD_CTRL (QSPI_PAD_CTRL1 ), +MX6_PAD_NAND_CE0_B__QSPI2_A_DATA_2 |MUX_PAD_CTRL (QSPI_PAD_CTRL1 ), +MX6_PAD_NAND_CE1_B__QSPI2_A_DATA_3 |MUX_PAD_CTRL (QSPI_PAD_CTRL1 ), +MX6_PAD_NAND_ALE__QSPI2_A_SS0_B |MUX_PAD_CTRL (QSPI_PAD_CTRL1 ), +MX6_PAD_NAND_CLE__QSPI2_A_SCLK |MUX_PAD_CTRL (QSPI_PAD_CTRL1 ), +MX6_PAD_NAND_DATA07__QSPI2_A_DQS |MUX_PAD_CTRL (QSPI_PAD_CTRL1 ), +MX6_PAD_NAND_DATA01__QSPI2_B_DATA_0 |MUX_PAD_CTRL (QSPI_PAD_CTRL1 ), +MX6_PAD_NAND_DATA00__QSPI2_B_DATA_1 |MUX_PAD_CTRL (QSPI_PAD_CTRL1 ), +MX6_PAD_NAND_WE_B__QSPI2_B_DATA_2 |MUX_PAD_CTRL (QSPI_PAD_CTRL1 ), +MX6_PAD_NAND_RE_B__QSPI2_B_DATA_3 |MUX_PAD_CTRL (QSPI_PAD_CTRL1 ), +MX6_PAD_NAND_DATA03__QSPI2_B_SS0_B |MUX_PAD_CTRL (QSPI_PAD_CTRL1 ), +MX6_PAD_NAND_DATA02__QSPI2_B_SCLK |MUX_PAD_CTRL (QSPI_PAD_CTRL1 ), +MX6_PAD_NAND_DATA05__QSPI2_B_DQS |MUX_PAD_CTRL (QSPI_PAD_CTRL1 ), +}; + +int board_qspi_init (void ) +{ +/* Set the iomux */ +imx_iomux_v3_setup_multiple_pads (quadspi_pads, +ARRAY_SIZE (quadspi_pads)); + +/* Set the clock */ +enable_qspi_clk (1 ); + +return 0 ; +} +#endif +int board_init (void ) {/* Address of boot parameters */
@@ -380,6 +416,10 @@ int board_init(void)setup_i2c (0 ,CONFIG_SYS_I2C_SPEED ,0x7f , &i2c_pad_info1);#endif +#ifdef CONFIG_FSL_QSPI +board_qspi_init (); +#endif +return 0 ; }
include/configs/mx6sxsabresd.h +12 -0
@@ -235,6 +235,18 @@/* FLASH and environment organization */ #define CONFIG_SYS_NO_FLASH +#define CONFIG_FSL_QSPI + +#ifdef CONFIG_FSL_QSPI +#define CONFIG_CMD_SF +#define CONFIG_SPI_FLASH +#define CONFIG_SPI_FLASH_SPANSION +#define CONFIG_SPI_FLASH_STMICRO +#define CONFIG_SYS_FSL_QSPI_LE +#define FSL_QSPI_FLASH_SIZE SZ_16M +#define FSL_QSPI_FLASH_NUM 2 +#endif +#define CONFIG_ENV_OFFSET (6 * SZ_64K)#define CONFIG_ENV_SIZE SZ_8K#define CONFIG_ENV_IS_IN_MMC
Signature · 1 line
1.8.4
v4 cover qspi: qspi support for mx6sxsabresd
In reply to Peng FanQuoted 8 lines · Peng Fan
This patch set is to support qspi for mx6sxsabresd board.
To mx6sxsabresd Revb board, 32M flash is used, but in header file,
CONFIG_SPI_FLASH_BARis not defined, and we still useSZ_16M. The LUT initializationqspi_set_lutfunction uses 32BIT addr, howeverCONFIG_SPI_FLASH_BARand 24BIT addr should be used to access bigger than 16MB size flash, and BRRD/BRWR should also be supported. Future patches will fix this.
Please do remember your self, for next patches. of-course I have added this note on "[U-Boot,v4,5/5] imx:mx6sxsabresd add qspi support" commit body.
Quoted 22 lines
Since flash opcodes are not recommended to use in driver level, use
QSPI_CMD_xxto replaceOPCODE_xx. It is qspi controller's feature to program LUT withQSPI_CMD_xxwhich same value withOPCODE_xx.Since Revb board's qspi flash support 4K erase, 4K erase is added in driver.
Peng Fan (5):
QuadSPI: useQSPI_CMD_xxinstead of flash opcodes
QuadSPI: use correctamba_base
arm:mx6sx add QSPI support
imx:qspi add 4K erase support imx:mx6sxsabresd add qspi supportarch/arm/cpu/armv7/mx6/clock.c | 50 ++++++++++ arch/arm/include/asm/arch-mx6/clock.h | 1 + arch/arm/include/asm/arch-mx6/imx-regs.h | 12 +-- board/freescale/mx6sxsabresd/mx6sxsabresd.c | 40 ++++++++ drivers/spi/fsl_qspi.c | 137 +++++++++++++++++++--------- include/configs/mx6sxsabresd.h | 12 +++ 6 files changed, 205 insertions(+), 47 deletions(-)
Quoted 4 lines
--
1.8.4
Applied to u-boot-spi/master
thanks!
Signature · 1 line
Jagan.
v4 cover qspi: qspi support for mx6sxsabresd
Quoted 10 lines · Jagan Teki
Quoted 8 lines · Peng Fan
This patch set is to support qspi for mx6sxsabresd board.
To mx6sxsabresd Revb board, 32M flash is used, but in header file,
CONFIG_SPI_FLASH_BARis not defined, and we still useSZ_16M. The LUT initializationqspi_set_lutfunction uses 32BIT addr, howeverCONFIG_SPI_FLASH_BARand 24BIT addr should be used to access bigger than 16MB size flash, and BRRD/BRWR should also be supported. Future patches will fix this.
Quoted 3 lines
Please do remember your self, for next patches. of-course I have added this note on "[U-Boot,v4,5/5] imx:mx6sxsabresd add qspi support" commit body.
Thanks. Actually I am doing the work.
Quoted 22 lines
Quoted 22 lines
Since flash opcodes are not recommended to use in driver level, use
QSPI_CMD_xxto replaceOPCODE_xx. It is qspi controller's feature to program LUT withQSPI_CMD_xxwhich same value withOPCODE_xx.Since Revb board's qspi flash support 4K erase, 4K erase is added in driver.
Peng Fan (5):
QuadSPI: useQSPI_CMD_xxinstead of flash opcodes
QuadSPI: use correctamba_base
arm:mx6sx add QSPI support
imx:qspi add 4K erase support imx:mx6sxsabresd add qspi supportarch/arm/cpu/armv7/mx6/clock.c | 50 ++++++++++ arch/arm/include/asm/arch-mx6/clock.h | 1 + arch/arm/include/asm/arch-mx6/imx-regs.h | 12 +-- board/freescale/mx6sxsabresd/mx6sxsabresd.c | 40 ++++++++ drivers/spi/fsl_qspi.c | 137 +++++++++++++++++++--------- include/configs/mx6sxsabresd.h | 12 +++ 6 files changed, 205 insertions(+), 47 deletions(-)
Quoted 9 lines
Quoted 4 lines
--
1.8.4Applied to u-boot-spi/master
thanks!
Regards,
Peng.