Skip to content

Commit 64fe934

Browse files
JBarberUkartben
authored andcommitted
driver: flash: mcux_flexspi_nor: Fix for is25lpxxxd chips
IS25LPXXXD uses the same jedec-id as IS25LPXXX, but the latter has an extended read register, similar to IS25WPXXX. This change will attempt to read the extended read register to determine what the appropriate initialization value for read register should be. Signed-off-by: John Barbero Unenge <git@lsrkttn.com>
1 parent d457a6a commit 64fe934

File tree

1 file changed

+60
-40
lines changed

1 file changed

+60
-40
lines changed

drivers/flash/flash_mcux_flexspi_nor.c

Lines changed: 60 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -943,37 +943,72 @@ static int flash_flexspi_nor_sfdp_read(const struct device *dev,
943943

944944
#endif
945945

946-
/* Helper to configure IS25 flash, by clearing read param bits */
947-
static int flash_flexspi_nor_is25_clear_read_param(struct flash_flexspi_nor_data *data,
948-
uint32_t (*flexspi_lut)[MEMC_FLEXSPI_CMD_PER_SEQ],
949-
uint32_t *read_params)
946+
/* Helper to configure IS25 flash */
947+
static int
948+
flash_flexspi_nor_is25_clear_dummy_cycles(struct flash_flexspi_nor_data *data,
949+
uint32_t (*flexspi_lut)[MEMC_FLEXSPI_CMD_PER_SEQ])
950950
{
951951
int ret;
952-
/* Install Set Read Parameters (Volatile) command */
952+
953+
const flexspi_device_config_t config = {
954+
.flexspiRootClk = MHZ(50),
955+
.flashSize = FLEXSPI_FLSHCR0_FLSHSZ_MASK, /* Max flash size */
956+
.ARDSeqNumber = 1,
957+
.ARDSeqIndex = READ,
958+
};
959+
953960
flexspi_transfer_t transfer = {
954961
.deviceAddress = 0,
955962
.port = data->port,
956963
.seqIndex = SCRATCH_CMD,
957964
.SeqNumber = 1,
958-
.data = read_params,
959965
.dataSize = 1,
960-
.cmdType = kFLEXSPI_Write,
961-
};
962-
flexspi_device_config_t config = {
963-
.flexspiRootClk = MHZ(50),
964-
.flashSize = FLEXSPI_FLSHCR0_FLSHSZ_MASK, /* Max flash size */
965-
.ARDSeqNumber = 1,
966-
.ARDSeqIndex = READ,
967966
};
968967

969-
flexspi_lut[SCRATCH_CMD][0] = FLEXSPI_LUT_SEQ(
970-
kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0xC0,
971-
kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x1);
972-
ret = memc_flexspi_set_device_config(&data->controller,
973-
&config,
974-
(uint32_t *)flexspi_lut,
975-
FLEXSPI_INSTR_END * MEMC_FLEXSPI_CMD_PER_SEQ,
976-
data->port);
968+
/*
969+
* Get Extended Read Parameters (Non-Volatile) command (RDERP, 81h)
970+
*
971+
* This is done to distinguish between an IS25LPXXX and IS25LPXXXD since
972+
* the former uses the read parameters (SRPV) to set drive strength and
973+
* dummy cycles, while IS25LPXXXD uses extended read parameters (SERPV)
974+
* for drive strength and read parameters (SRPV) for dummy cycles.
975+
*/
976+
uint32_t resp_data;
977+
978+
transfer.data = &resp_data;
979+
transfer.cmdType = kFLEXSPI_Read;
980+
981+
flexspi_lut[SCRATCH_CMD][0] =
982+
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x81,
983+
kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x1);
984+
ret = memc_flexspi_set_device_config(&data->controller, &config, (uint32_t *)flexspi_lut,
985+
FLEXSPI_INSTR_END * MEMC_FLEXSPI_CMD_PER_SEQ,
986+
data->port);
987+
988+
if (ret < 0) {
989+
return ret;
990+
}
991+
992+
ret = memc_flexspi_transfer(&data->controller, &transfer);
993+
994+
/*
995+
* Check that EB[7:4] is not all zero and that EB[0] (WIP)
996+
* is not 1, which should catch a chip responding to an
997+
* unsupported 81h command with either 0x00 or 0xFF
998+
*/
999+
const int has_extended_read_reg = resp_data & 0xF0 && !(resp_data & 0x01);
1000+
uint32_t read_params = has_extended_read_reg ? 0 : 0xE0U;
1001+
1002+
/* Switch over to writing read_params (SRPV, C0h) */
1003+
transfer.cmdType = kFLEXSPI_Write;
1004+
transfer.data = &read_params;
1005+
1006+
flexspi_lut[SCRATCH_CMD][0] =
1007+
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0xC0,
1008+
kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x1);
1009+
ret = memc_flexspi_set_device_config(&data->controller, &config, (uint32_t *)flexspi_lut,
1010+
FLEXSPI_INSTR_END * MEMC_FLEXSPI_CMD_PER_SEQ,
1011+
data->port);
9771012
if (ret < 0) {
9781013
return ret;
9791014
}
@@ -986,7 +1021,6 @@ static int flash_flexspi_nor_check_jedec(struct flash_flexspi_nor_data *data,
9861021
{
9871022
int ret;
9881023
uint32_t vendor_id;
989-
uint32_t read_params;
9901024

9911025
ret = flash_flexspi_nor_read_id_helper(data, (uint8_t *)&vendor_id);
9921026
if (ret < 0) {
@@ -995,31 +1029,17 @@ static int flash_flexspi_nor_check_jedec(struct flash_flexspi_nor_data *data,
9951029

9961030
/* Switch on manufacturer and vendor ID */
9971031
switch (vendor_id & 0xFFFFFF) {
998-
case 0x16609d: /* IS25LP032 flash, needs P[4:3] cleared with same method as IS25WP */
1032+
case 0x16609d: /* IS25LP032 */
9991033
case 0x17609d: /* IS25LP064 */
10001034
case 0x18609d: /* IS25LP128 */
1001-
read_params = 0xE0U;
1002-
ret = flash_flexspi_nor_is25_clear_read_param(data, flexspi_lut, &read_params);
1003-
if (ret < 0) {
1004-
while (1) {
1005-
/*
1006-
* Spin here, this flash won't configure correctly.
1007-
* We can't print a warning, as we are unlikely to
1008-
* be able to XIP at this point.
1009-
*/
1010-
}
1011-
}
1012-
/* Still return an error- we want the JEDEC configuration to run */
1013-
return -ENOTSUP;
10141035
case 0x16709d: /* IS25WP032 */
10151036
case 0x17709d: /* IS25WP064 */
10161037
case 0x18709d: /* IS25WP128 */
10171038
/*
1018-
* IS25WP flash. We can support this flash with the JEDEC probe,
1019-
* but we need to insure P[6:3] are at the default value
1039+
* We can support this flash with the JEDEC probe, but we need to
1040+
* ensure Dummy Cycles are at the default value
10201041
*/
1021-
read_params = 0;
1022-
ret = flash_flexspi_nor_is25_clear_read_param(data, flexspi_lut, &read_params);
1042+
ret = flash_flexspi_nor_is25_clear_dummy_cycles(data, flexspi_lut);
10231043
if (ret < 0) {
10241044
while (1) {
10251045
/*

0 commit comments

Comments
 (0)