Skip to content

Commit e4f77ac

Browse files
committed
drivers: flash: mcux-flexspi-nor: Support ocatl mode
Add support for JEDEC octal mode. Signed-off-by: Pieter De Gendt <[email protected]>
1 parent 0feb7ba commit e4f77ac

File tree

1 file changed

+119
-0
lines changed

1 file changed

+119
-0
lines changed

drivers/flash/flash_mcux_flexspi_nor.c

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,86 @@ static int flash_flexspi_nor_octal_enable(struct flash_flexspi_nor_data *data,
743743
/* Wait for QE bit to complete programming */
744744
return flash_flexspi_nor_wait_bus_busy(data);
745745
}
746+
747+
static int flash_flexspi_nor_octal_enable_s2b3(struct flash_flexspi_nor_data *data,
748+
uint32_t (*flexspi_lut)[MEMC_FLEXSPI_CMD_PER_SEQ])
749+
{
750+
int ret;
751+
uint32_t buffer = 0;
752+
flexspi_transfer_t transfer = {
753+
.deviceAddress = 0x02,
754+
.port = data->port,
755+
.SeqNumber = 1,
756+
.data = &buffer,
757+
};
758+
const flexspi_device_config_t config = {
759+
.flexspiRootClk = MHZ(50),
760+
.flashSize = FLEXSPI_FLSHCR0_FLSHSZ_MASK,
761+
.ARDSeqNumber = 1,
762+
.ARDSeqIndex = READ,
763+
};
764+
765+
flexspi_lut[SCRATCH_CMD][0] =
766+
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x65,
767+
kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x08);
768+
flexspi_lut[SCRATCH_CMD][1] =
769+
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DUMMY_SDR, kFLEXSPI_1PAD, 0x08,
770+
kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x01);
771+
flexspi_lut[SCRATCH_CMD2][0] =
772+
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, SPI_NOR_CMD_WRSR2,
773+
kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x01);
774+
775+
ret = memc_flexspi_set_device_config(&data->controller, &config, (uint32_t *)flexspi_lut,
776+
FLEXSPI_INSTR_END * MEMC_FLEXSPI_CMD_PER_SEQ,
777+
data->port);
778+
if (ret < 0) {
779+
return ret;
780+
}
781+
782+
transfer.dataSize = 1;
783+
transfer.seqIndex = SCRATCH_CMD;
784+
transfer.cmdType = kFLEXSPI_Read;
785+
ret = memc_flexspi_transfer(&data->controller, &transfer);
786+
if (ret < 0) {
787+
return ret;
788+
}
789+
790+
if ((buffer & BIT(3)) != 0U) {
791+
return 0;
792+
}
793+
794+
ret = flash_flexspi_nor_write_enable(data);
795+
if (ret < 0) {
796+
return ret;
797+
}
798+
799+
buffer |= BIT(3);
800+
transfer.deviceAddress = 0;
801+
transfer.seqIndex = SCRATCH_CMD2;
802+
transfer.cmdType = kFLEXSPI_Write;
803+
ret = memc_flexspi_transfer(&data->controller, &transfer);
804+
if (ret < 0) {
805+
return ret;
806+
}
807+
808+
return flash_flexspi_nor_wait_bus_busy(data);
809+
}
810+
811+
static int
812+
flash_flexspi_nor_handle_octal_requirements(struct flash_flexspi_nor_data *data,
813+
uint32_t (*flexspi_lut)[MEMC_FLEXSPI_CMD_PER_SEQ],
814+
uint8_t oer)
815+
{
816+
switch (oer) {
817+
case JESD216_DW19_OER_VAL_NONE:
818+
return 0;
819+
case JESD216_DW19_OER_VAL_S2B3:
820+
return flash_flexspi_nor_octal_enable_s2b3(data, flexspi_lut);
821+
default:
822+
return -ENOTSUP;
823+
}
824+
}
825+
746826
/*
747827
* This function enables 4 byte addressing, when supported. Otherwise it
748828
* returns an error.
@@ -865,8 +945,10 @@ static int flash_flexspi_nor_config_flash(struct flash_flexspi_nor_data *data,
865945
struct jesd216_bfp_dw16 dw16;
866946
struct jesd216_bfp_dw15 dw15;
867947
struct jesd216_bfp_dw14 dw14;
948+
struct jesd216_bfp_dw19 dw19;
868949
uint8_t addr_width;
869950
uint8_t mode_cmd;
951+
uint8_t octal_enable_req = JESD216_DW19_OER_VAL_NONE;
870952
int ret;
871953

872954
/* Read DW14 to determine the polling method we should use while programming */
@@ -892,6 +974,10 @@ static int flash_flexspi_nor_config_flash(struct flash_flexspi_nor_data *data,
892974
addr_width = jesd216_bfp_addrbytes(bfp) ==
893975
JESD216_SFDP_BFP_DW1_ADDRBYTES_VAL_4B ? 32 : 24;
894976

977+
if (jesd216_bfp_decode_dw19(&header->phdr[0], bfp, &dw19) == 0) {
978+
octal_enable_req = dw19.octal_enable_req;
979+
}
980+
895981
/* Check to see if we can enable 4 byte addressing */
896982
ret = jesd216_bfp_decode_dw16(&header->phdr[0], bfp, &dw16);
897983
if (ret == 0) {
@@ -915,6 +1001,39 @@ static int flash_flexspi_nor_config_flash(struct flash_flexspi_nor_data *data,
9151001
/* Extract the read command.
9161002
* Note- enhanced XIP not currently supported, nor is 4-4-4 mode.
9171003
*/
1004+
ret = jesd216_bfp_read_support(&header->phdr[0], bfp,
1005+
JESD216_MODE_188, &instr);
1006+
if (ret > 0) {
1007+
ret = flash_flexspi_nor_handle_octal_requirements(data, flexspi_lut,
1008+
octal_enable_req);
1009+
if (ret < 0) {
1010+
if (ret != -ENOTSUP) {
1011+
return ret;
1012+
}
1013+
} else {
1014+
LOG_DBG("Enable 188 mode");
1015+
if (instr.mode_clocks == 2) {
1016+
mode_cmd = kFLEXSPI_Command_MODE8_SDR;
1017+
} else if (instr.mode_clocks == 1) {
1018+
mode_cmd = kFLEXSPI_Command_MODE4_SDR;
1019+
} else if (instr.mode_clocks == 0) {
1020+
mode_cmd = kFLEXSPI_Command_DUMMY_SDR;
1021+
} else {
1022+
return -ENOTSUP;
1023+
}
1024+
flexspi_lut[READ][0] = FLEXSPI_LUT_SEQ(
1025+
kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, instr.instr,
1026+
kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_8PAD, addr_width);
1027+
flexspi_lut[READ][1] = FLEXSPI_LUT_SEQ(mode_cmd, kFLEXSPI_8PAD, 0x00,
1028+
kFLEXSPI_Command_DUMMY_SDR,
1029+
kFLEXSPI_8PAD, instr.wait_states);
1030+
flexspi_lut[READ][2] =
1031+
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_READ_SDR, kFLEXSPI_8PAD, 0x04,
1032+
kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x0);
1033+
return 0;
1034+
}
1035+
}
1036+
9181037
if (jesd216_bfp_read_support(&header->phdr[0], bfp,
9191038
JESD216_MODE_144, &instr) > 0) {
9201039
LOG_DBG("Enable 144 mode");

0 commit comments

Comments
 (0)