@@ -2112,6 +2112,7 @@ struct sfdp_parameter_header {
21122112
21132113#define SFDP_BFPT_ID 0xff00 /* Basic Flash Parameter Table */
21142114#define SFDP_SECTOR_MAP_ID 0xff81 /* Sector Map Table */
2115+ #define SFDP_4BAIT_ID 0xff84u /* 4-byte Address Instruction Table */
21152116
21162117#define SFDP_SIGNATURE 0x50444653U
21172118#define SFDP_JESD216_MAJOR 1
@@ -2799,6 +2800,149 @@ static int spi_nor_parse_smpt(struct spi_nor *nor,
27992800 return ret ;
28002801}
28012802
2803+ struct sfdp_4bait {
2804+ /* The hardware capability. */
2805+ u32 hwcaps ;
2806+
2807+ /*
2808+ * The <supported_bit> bit in DWORD1 of the 4BAIT tells us whether
2809+ * the associated 4-byte address op code is supported.
2810+ */
2811+ u32 supported_bit ;
2812+ };
2813+
2814+ static int spi_nor_parse_4bait (struct spi_nor * nor ,
2815+ const struct sfdp_parameter_header * param_header ,
2816+ struct spi_nor_flash_parameter * params )
2817+ {
2818+ static const struct sfdp_4bait reads [] = {
2819+ { SNOR_HWCAPS_READ , BIT (0 ) },
2820+ { SNOR_HWCAPS_READ_FAST , BIT (1 ) },
2821+ { SNOR_HWCAPS_READ_1_1_2 , BIT (2 ) },
2822+ { SNOR_HWCAPS_READ_1_2_2 , BIT (3 ) },
2823+ { SNOR_HWCAPS_READ_1_1_4 , BIT (4 ) },
2824+ { SNOR_HWCAPS_READ_1_4_4 , BIT (5 ) },
2825+ { SNOR_HWCAPS_READ_1_1_1_DTR , BIT (13 ) },
2826+ { SNOR_HWCAPS_READ_1_2_2_DTR , BIT (14 ) },
2827+ { SNOR_HWCAPS_READ_1_4_4_DTR , BIT (15 ) },
2828+ };
2829+ static const struct sfdp_4bait programs [] = {
2830+ { SNOR_HWCAPS_PP , BIT (6 ) },
2831+ { SNOR_HWCAPS_PP_1_1_4 , BIT (7 ) },
2832+ { SNOR_HWCAPS_PP_1_4_4 , BIT (8 ) },
2833+ };
2834+ static const struct sfdp_4bait erases [SNOR_ERASE_TYPE_MAX ] = {
2835+ { 0u /* not used */ , BIT (9 ) },
2836+ { 0u /* not used */ , BIT (10 ) },
2837+ { 0u /* not used */ , BIT (11 ) },
2838+ { 0u /* not used */ , BIT (12 ) },
2839+ };
2840+ u32 dwords [2 ], addr , discard_hwcaps , read_hwcaps , pp_hwcaps , erase_mask ;
2841+ struct spi_nor_erase_map * map = & nor -> erase_map ;
2842+ int i , err ;
2843+
2844+ if (param_header -> major != SFDP_JESD216_MAJOR ||
2845+ param_header -> length < ARRAY_SIZE (dwords ))
2846+ return - EINVAL ;
2847+
2848+ /* Read the 4-byte Address Instruction Table. */
2849+ addr = SFDP_PARAM_HEADER_PTP (param_header );
2850+ err = spi_nor_read_sfdp (nor , addr , sizeof (dwords ), dwords );
2851+ if (err )
2852+ return err ;
2853+
2854+ /* Fix endianness of the 4BAIT DWORDs. */
2855+ for (i = 0 ; i < ARRAY_SIZE (dwords ); i ++ )
2856+ dwords [i ] = le32_to_cpu (dwords [i ]);
2857+
2858+ /*
2859+ * Compute the subset of (Fast) Read commands for which the 4-byte
2860+ * version is supported.
2861+ */
2862+ discard_hwcaps = 0 ;
2863+ read_hwcaps = 0 ;
2864+ for (i = 0 ; i < ARRAY_SIZE (reads ); i ++ ) {
2865+ const struct sfdp_4bait * read = & reads [i ];
2866+
2867+ discard_hwcaps |= read -> hwcaps ;
2868+ if ((params -> hwcaps .mask & read -> hwcaps ) &&
2869+ (dwords [0 ] & read -> supported_bit ))
2870+ read_hwcaps |= read -> hwcaps ;
2871+ }
2872+
2873+ /*
2874+ * Compute the subset of Page Program commands for which the 4-byte
2875+ * version is supported.
2876+ */
2877+ pp_hwcaps = 0 ;
2878+ for (i = 0 ; i < ARRAY_SIZE (programs ); i ++ ) {
2879+ const struct sfdp_4bait * program = & programs [i ];
2880+
2881+ discard_hwcaps |= program -> hwcaps ;
2882+ if ((params -> hwcaps .mask & program -> hwcaps ) &&
2883+ (dwords [0 ] & program -> supported_bit ))
2884+ pp_hwcaps |= program -> hwcaps ;
2885+ }
2886+
2887+ /*
2888+ * Compute the subet of Sector Erase commands for which the 4-byte
2889+ * version is supported.
2890+ */
2891+ erase_mask = 0 ;
2892+ for (i = 0 ; i < SNOR_ERASE_TYPE_MAX ; i ++ ) {
2893+ const struct sfdp_4bait * erase = & erases [i ];
2894+
2895+ if (map -> erase_type [i ].size > 0 &&
2896+ (dwords [0 ] & erase -> supported_bit ))
2897+ erase_mask |= BIT (i );
2898+ }
2899+
2900+ /*
2901+ * We need at least one 4-byte op code per read, program and erase
2902+ * operation; the .read(), .write() and .erase() hooks share the
2903+ * nor->addr_width value.
2904+ */
2905+ if (!read_hwcaps || !pp_hwcaps || !erase_mask )
2906+ return 0 ;
2907+
2908+ /*
2909+ * Discard all operations from the 4-byte instruction set which are
2910+ * not supported by this memory.
2911+ */
2912+ params -> hwcaps .mask &= ~discard_hwcaps ;
2913+ params -> hwcaps .mask |= (read_hwcaps | pp_hwcaps );
2914+
2915+ /* Use the 4-byte address instruction set. */
2916+ for (i = 0 ; i < SNOR_CMD_READ_MAX ; i ++ ) {
2917+ struct spi_nor_read_command * read_cmd = & params -> reads [i ];
2918+
2919+ read_cmd -> opcode = spi_nor_convert_3to4_read (read_cmd -> opcode );
2920+ }
2921+ for (i = 0 ; i < SNOR_CMD_PP_MAX ; i ++ ) {
2922+ struct spi_nor_pp_command * pp_cmd = & params -> page_programs [i ];
2923+
2924+ pp_cmd -> opcode = spi_nor_convert_3to4_program (pp_cmd -> opcode );
2925+ }
2926+ for (i = 0 ; i < SNOR_ERASE_TYPE_MAX ; i ++ ) {
2927+ struct spi_nor_erase_type * erase = & map -> erase_type [i ];
2928+
2929+ if (erase_mask & BIT (erase -> idx ))
2930+ erase -> opcode = (dwords [1 ] >> (erase -> idx * 8 )) & 0xFF ;
2931+ else
2932+ spi_nor_set_erase_type (erase , 0u , 0xFF );
2933+ }
2934+
2935+ /*
2936+ * We set nor->addr_width here to skip spi_nor_set_4byte_opcodes()
2937+ * later because this latest function implements a legacy quirk for
2938+ * the erase size of Spansion memory. However this quirk is no longer
2939+ * needed with new SFDP compliant memories.
2940+ */
2941+ nor -> addr_width = 4 ;
2942+ nor -> flags |= SPI_NOR_4B_OPCODES ;
2943+ return 0 ;
2944+ }
2945+
28022946/**
28032947 * spi_nor_parse_sfdp() - parse the Serial Flash Discoverable Parameters.
28042948 * @nor: pointer to a 'struct spi_nor'
@@ -2897,6 +3041,10 @@ static int spi_nor_parse_sfdp(struct spi_nor *nor,
28973041 err = spi_nor_parse_smpt (nor , param_header );
28983042 break ;
28993043
3044+ case SFDP_4BAIT_ID :
3045+ err = spi_nor_parse_4bait (nor , param_header , params );
3046+ break ;
3047+
29003048 default :
29013049 break ;
29023050 }
0 commit comments