@@ -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