Browse Source

drivers: flash: flexspi: Add octal mode support for MT35 family

MT35 flashes could run in octal mode, Now the driver doesn't support
octal mode, add octal mode support for MT35 flashes.

Signed-off-by: Qiang Zhao <qiang.zhao@nxp.com>
pull/92275/head
Qiang Zhao 4 weeks ago committed by Daniel DeGrasse
parent
commit
0337527e74
  1. 110
      drivers/flash/flash_mcux_flexspi_nor.c
  2. 2
      drivers/flash/spi_nor.h

110
drivers/flash/flash_mcux_flexspi_nor.c

@ -50,6 +50,7 @@ enum { @@ -50,6 +50,7 @@ enum {
ERASE_BLOCK,
READ_ID,
READ_STATUS_REG,
WRITE_REG,
ERASE_CHIP,
READ_JESD216,
/* Entries after this should be for scratch commands */
@ -667,6 +668,60 @@ static int flash_flexspi_nor_quad_enable(struct flash_flexspi_nor_data *data, @@ -667,6 +668,60 @@ static int flash_flexspi_nor_quad_enable(struct flash_flexspi_nor_data *data,
return flash_flexspi_nor_wait_bus_busy(data);
}
/*
* This function enables octal mode, when supported. Otherwise it
* returns an error.
* @param dev: Flexspi device
* @param flexspi_lut: flexspi lut table, useful if instruction writes are needed
* @return 0 if octal mode was entered, or -ENOTSUP if octal mode is not supported
*/
static int flash_flexspi_nor_octal_enable(struct flash_flexspi_nor_data *data,
uint32_t (*flexspi_lut)[MEMC_FLEXSPI_CMD_PER_SEQ])
{
int ret;
uint32_t buffer = 0;
flexspi_transfer_t transfer = {
.deviceAddress = 0,
.port = data->port,
.SeqNumber = 1,
.data = &buffer,
};
flexspi_device_config_t config = {
.flexspiRootClk = MHZ(50),
.flashSize = FLEXSPI_FLSHCR0_FLSHSZ_MASK, /* Max flash size */
.ARDSeqNumber = 1,
.ARDSeqIndex = READ,
};
ret = memc_flexspi_set_device_config(&data->controller,
&config,
(uint32_t *)flexspi_lut,
FLEXSPI_INSTR_END * MEMC_FLEXSPI_CMD_PER_SEQ,
data->port);
if (ret < 0) {
return ret;
}
/* Enable write */
ret = flash_flexspi_nor_write_enable(data);
if (ret < 0) {
return ret;
}
/* Enable octal DDR mode */
buffer = 0xE7;
transfer.dataSize = 1;
transfer.seqIndex = WRITE_REG;
transfer.cmdType = kFLEXSPI_Write;
ret = memc_flexspi_transfer(&data->controller, &transfer);
if (ret < 0) {
return ret;
}
/* Wait for QE bit to complete programming */
return flash_flexspi_nor_wait_bus_busy(data);
}
/*
* This function enables 4 byte addressing, when supported. Otherwise it
* returns an error.
@ -1184,6 +1239,61 @@ static int flash_flexspi_nor_check_jedec(struct flash_flexspi_nor_data *data, @@ -1184,6 +1239,61 @@ static int flash_flexspi_nor_check_jedec(struct flash_flexspi_nor_data *data,
kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x01);
/* Device has no QE bit, 1-4-4 and 1-1-4 is always enabled */
return 0;
case 0x195b2c: /* MT35XU256 */
case 0x1a5b2c: /* MT35XU512 */
case 0x1b5b2c: /* MT35XU01G */
case 0x1c5b2c: /* MT35XU02G */
case 0x195a2c: /* MT35XL256 */
case 0x1a5a2c: /* MT35XL512 */
case 0x1b5a2c: /* MT35XL01G */
case 0x1c5a2c: /* MT35XL02G */
/* MT35X flash with more than 32MB, use 8 byte read/write */
flexspi_lut[READ][0] = FLEXSPI_LUT_SEQ(
kFLEXSPI_Command_SDR, kFLEXSPI_8PAD, SPI_NOR_OCMD_READ,
kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x20);
/* Flash needs 16 dummy cycles */
flexspi_lut[READ][1] = FLEXSPI_LUT_SEQ(
kFLEXSPI_Command_DUMMY_DDR, kFLEXSPI_8PAD, 0x20,
kFLEXSPI_Command_READ_DDR, kFLEXSPI_8PAD, 0x04);
/* Update PROGRAM commands for 8 byte mode */
flexspi_lut[PAGE_PROGRAM][0] = FLEXSPI_LUT_SEQ(
kFLEXSPI_Command_SDR, kFLEXSPI_8PAD, SPI_NOR_CMD_PP_4B,
kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x20);
flexspi_lut[PAGE_PROGRAM][1] = FLEXSPI_LUT_SEQ(
kFLEXSPI_Command_WRITE_DDR, kFLEXSPI_8PAD, 0x4,
kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x0);
/* Update ERASE commands for 4 byte mode */
flexspi_lut[ERASE_SECTOR][0] = FLEXSPI_LUT_SEQ(
kFLEXSPI_Command_SDR, kFLEXSPI_8PAD, SPI_NOR_CMD_SE_4B,
kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x20);
flexspi_lut[ERASE_BLOCK][0] = FLEXSPI_LUT_SEQ(
kFLEXSPI_Command_SDR, kFLEXSPI_8PAD, SPI_NOR_CMD_BE_4B,
kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x20),
/* Read instruction used for polling is 0x05 */
data->legacy_poll = true;
flexspi_lut[READ_STATUS_REG][0] = FLEXSPI_LUT_SEQ(
kFLEXSPI_Command_SDR, kFLEXSPI_8PAD, SPI_NOR_CMD_RDSR,
kFLEXSPI_Command_DUMMY_DDR, kFLEXSPI_8PAD, 0x10);
flexspi_lut[READ_STATUS_REG][1] = FLEXSPI_LUT_SEQ(
kFLEXSPI_Command_READ_DDR, kFLEXSPI_8PAD, 0x01,
kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x00);
/* Write volatile register for 1 byte mode, used to enter OPI mode */
flexspi_lut[WRITE_REG][0] = FLEXSPI_LUT_SEQ(
kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, SPI_NOR_CMD_WR_VCFGREG,
kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x00);
flexspi_lut[WRITE_REG][1] = FLEXSPI_LUT_SEQ(
kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x00,
kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x00);
flexspi_lut[WRITE_REG][2] = FLEXSPI_LUT_SEQ(
kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x01,
kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x00);
/* enable octal mode */
flash_flexspi_nor_octal_enable(data, flexspi_lut);
flexspi_lut[WRITE_ENABLE][0] = FLEXSPI_LUT_SEQ(
kFLEXSPI_Command_SDR, kFLEXSPI_8PAD, SPI_NOR_CMD_WREN,
kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0);
return 0;
default:
return -ENOTSUP;
}

2
drivers/flash/spi_nor.h

@ -71,6 +71,8 @@ @@ -71,6 +71,8 @@
#define SPI_NOR_CMD_PP_1_4_4_4B 0x3e /* Quad Page program (1-4-4) 4 Byte Address */
#define SPI_NOR_CMD_RDFLSR 0x70 /* Read Flag Status Register */
#define SPI_NOR_CMD_CLRFLSR 0x50 /* Clear Flag Status Register */
#define SPI_NOR_CMD_WR_VCFGREG 0x81 /* Octal Write volatile configuration Register */
#define SPI_NOR_OCMD_READ 0xFD /* Octal IO read command */
/* Flash octal opcodes */
#define SPI_NOR_OCMD_SE 0x21DE /* Octal Sector erase */

Loading…
Cancel
Save