Lines Matching +full:dma +full:- +full:safe +full:- +full:map
1 // SPDX-License-Identifier: GPL-2.0
9 #include <linux/mtd/spi-nor.h>
13 #define SFDP_PARAM_HEADER_ID(p) (((p)->id_msb << 8) | (p)->id_lsb)
15 (((p)->parameter_table_pointer[2] << 16) | \
16 ((p)->parameter_table_pointer[1] << 8) | \
17 ((p)->parameter_table_pointer[0] << 0))
20 #define SFDP_SECTOR_MAP_ID 0xff81 /* Sector Map Table */
21 #define SFDP_4BAIT_ID 0xff84 /* 4-byte Address Instruction Table */
29 u8 nph; /* 0-base number of parameter headers */
38 /* The Fast Read x-y-z hardware capability in params->hwcaps.mask. */
43 * whether the Fast Read x-y-z command is supported.
49 * The half-word at offset <setting_shift> in <setting_dword> BFPT DWORD
51 * states to be used by Fast Read x-y-z command.
56 /* The SPI protocol for this Fast Read x-y-z command. */
62 * The half-word at offset <shift> in DWORD <dwoard> encodes the
123 * the associated 4-byte address op code is supported.
129 * spi_nor_read_raw() - raw read of serial flash memory. read_opcode,
136 * @buf: buffer where the data is copied into (dma-safe memory)
138 * Return: 0 on success, -errno otherwise.
149 return -EIO; in spi_nor_read_raw()
153 len -= ret; in spi_nor_read_raw()
159 * spi_nor_read_sfdp() - read Serial Flash Discoverable Parameters.
163 * @buf: buffer where the SFDP data are copied into (dma-safe memory)
167 * followed by a 3-byte address and 8 dummy clock cycles.
169 * Return: 0 on success, -errno otherwise.
177 read_opcode = nor->read_opcode; in spi_nor_read_sfdp()
178 addr_width = nor->addr_width; in spi_nor_read_sfdp()
179 read_dummy = nor->read_dummy; in spi_nor_read_sfdp()
181 nor->read_opcode = SPINOR_OP_RDSFDP; in spi_nor_read_sfdp()
182 nor->addr_width = 3; in spi_nor_read_sfdp()
183 nor->read_dummy = 8; in spi_nor_read_sfdp()
187 nor->read_opcode = read_opcode; in spi_nor_read_sfdp()
188 nor->addr_width = addr_width; in spi_nor_read_sfdp()
189 nor->read_dummy = read_dummy; in spi_nor_read_sfdp()
195 * spi_nor_read_sfdp_dma_unsafe() - read Serial Flash Discoverable Parameters.
202 * guaranteed to be dma-safe.
204 * Return: -ENOMEM if kmalloc() fails, the return code of spi_nor_read_sfdp()
215 return -ENOMEM; in spi_nor_read_sfdp_dma_unsafe()
229 read->num_mode_clocks = (half >> 5) & 0x07; in spi_nor_set_read_settings_from_bfpt()
230 read->num_wait_states = (half >> 0) & 0x1f; in spi_nor_set_read_settings_from_bfpt()
231 read->opcode = (half >> 8) & 0xff; in spi_nor_set_read_settings_from_bfpt()
232 read->proto = proto; in spi_nor_set_read_settings_from_bfpt()
236 /* Fast Read 1-1-2 */
244 /* Fast Read 1-2-2 */
252 /* Fast Read 2-2-2 */
260 /* Fast Read 1-1-4 */
268 /* Fast Read 1-4-4 */
276 /* Fast Read 4-4-4 */
300 * spi_nor_set_erase_settings_from_bfpt() - set erase type settings from BFPT
316 erase->idx = i; in spi_nor_set_erase_settings_from_bfpt()
321 * spi_nor_map_cmp_erase_type() - compare the map's erase types by size
322 * @l: member in the left half of the map's erase_type array
323 * @r: member in the right half of the map's erase_type array
326 * map's erase types, the smallest erase type size being the first member in the
329 * Return: the result of @l->size - @r->size
335 return left->size - right->size; in spi_nor_map_cmp_erase_type()
339 * spi_nor_sort_erase_mask() - sort erase mask
340 * @map: the erase map of the SPI NOR
343 * Replicate the sort done for the map's erase types in BFPT: sort the erase
349 static u8 spi_nor_sort_erase_mask(struct spi_nor_erase_map *map, u8 erase_mask) in spi_nor_sort_erase_mask() argument
351 struct spi_nor_erase_type *erase_type = map->erase_type; in spi_nor_sort_erase_mask()
358 /* Replicate the sort done for the map's erase types. */ in spi_nor_sort_erase_mask()
367 * spi_nor_regions_sort_erase_types() - sort erase types in each region
368 * @map: the erase map of the SPI NOR
370 * Function assumes that the erase types defined in the erase map are already
372 * member in the erase_type array. It replicates the sort done for the map's
374 * supported from the sorted erase types defined in the erase map.
378 static void spi_nor_regions_sort_erase_types(struct spi_nor_erase_map *map) in spi_nor_regions_sort_erase_types() argument
380 struct spi_nor_erase_region *region = map->regions; in spi_nor_regions_sort_erase_types()
384 region_erase_mask = region->offset & SNOR_ERASE_TYPE_MASK; in spi_nor_regions_sort_erase_types()
386 sorted_erase_mask = spi_nor_sort_erase_mask(map, in spi_nor_regions_sort_erase_types()
390 region->offset = (region->offset & ~SNOR_ERASE_TYPE_MASK) | in spi_nor_regions_sort_erase_types()
398 * spi_nor_parse_bfpt() - read and parse the Basic Flash Parameter Table.
425 * Return: 0 on success, -errno otherwise.
431 struct spi_nor_erase_map *map = ¶ms->erase_map; in spi_nor_parse_bfpt() local
432 struct spi_nor_erase_type *erase_type = map->erase_type; in spi_nor_parse_bfpt()
441 if (bfpt_header->length < BFPT_DWORD_MAX_JESD216) in spi_nor_parse_bfpt()
442 return -EINVAL; in spi_nor_parse_bfpt()
446 bfpt_header->length * sizeof(u32)); in spi_nor_parse_bfpt()
460 nor->addr_width = 3; in spi_nor_parse_bfpt()
464 nor->addr_width = 4; in spi_nor_parse_bfpt()
477 * Prevent overflows on params->size. Anyway, a NOR of 2^64 in spi_nor_parse_bfpt()
482 return -EINVAL; in spi_nor_parse_bfpt()
484 params->size = 1ULL << val; in spi_nor_parse_bfpt()
486 params->size = val + 1; in spi_nor_parse_bfpt()
488 params->size >>= 3; /* Convert to bytes. */ in spi_nor_parse_bfpt()
495 if (!(bfpt.dwords[rd->supported_dword] & rd->supported_bit)) { in spi_nor_parse_bfpt()
496 params->hwcaps.mask &= ~rd->hwcaps; in spi_nor_parse_bfpt()
500 params->hwcaps.mask |= rd->hwcaps; in spi_nor_parse_bfpt()
501 cmd = spi_nor_hwcaps_read2cmd(rd->hwcaps); in spi_nor_parse_bfpt()
502 read = ¶ms->reads[cmd]; in spi_nor_parse_bfpt()
503 half = bfpt.dwords[rd->settings_dword] >> rd->settings_shift; in spi_nor_parse_bfpt()
504 spi_nor_set_read_settings_from_bfpt(read, half, rd->proto); in spi_nor_parse_bfpt()
508 * Sector Erase settings. Reinitialize the uniform erase map using the in spi_nor_parse_bfpt()
512 memset(¶ms->erase_map, 0, sizeof(params->erase_map)); in spi_nor_parse_bfpt()
518 half = bfpt.dwords[er->dword] >> er->shift; in spi_nor_parse_bfpt()
531 spi_nor_init_uniform_erase_map(map, erase_mask, params->size); in spi_nor_parse_bfpt()
533 * Sort all the map's Erase Types in ascending order with the smallest in spi_nor_parse_bfpt()
543 spi_nor_regions_sort_erase_types(map); in spi_nor_parse_bfpt()
544 map->uniform_erase_type = map->uniform_region.offset & in spi_nor_parse_bfpt()
548 if (bfpt_header->length == BFPT_DWORD_MAX_JESD216) in spi_nor_parse_bfpt()
556 params->page_size = 1U << val; in spi_nor_parse_bfpt()
561 params->quad_enable = NULL; in spi_nor_parse_bfpt()
567 * side-effect of clearing Status Register 2. in spi_nor_parse_bfpt()
574 nor->flags |= SNOR_F_HAS_16BIT_SR | SNOR_F_NO_READ_CR; in spi_nor_parse_bfpt()
575 params->quad_enable = spi_nor_sr2_bit1_quad_enable; in spi_nor_parse_bfpt()
579 nor->flags &= ~SNOR_F_HAS_16BIT_SR; in spi_nor_parse_bfpt()
580 params->quad_enable = spi_nor_sr1_bit6_quad_enable; in spi_nor_parse_bfpt()
584 nor->flags &= ~SNOR_F_HAS_16BIT_SR; in spi_nor_parse_bfpt()
585 params->quad_enable = spi_nor_sr2_bit7_quad_enable; in spi_nor_parse_bfpt()
593 * assumption of a 16-bit Write Status (01h) command. in spi_nor_parse_bfpt()
595 nor->flags |= SNOR_F_HAS_16BIT_SR; in spi_nor_parse_bfpt()
597 params->quad_enable = spi_nor_sr2_bit1_quad_enable; in spi_nor_parse_bfpt()
601 dev_dbg(nor->dev, "BFPT QER reserved value used\n"); in spi_nor_parse_bfpt()
606 if (bfpt_header->length == BFPT_DWORD_MAX_JESD216B) in spi_nor_parse_bfpt()
614 * spi_nor_smpt_addr_width() - return the address width used in the
630 return nor->addr_width; in spi_nor_smpt_addr_width()
635 * spi_nor_smpt_read_dummy() - return the configuration detection command read
647 return nor->read_dummy; in spi_nor_smpt_read_dummy()
652 * spi_nor_get_map_in_use() - get the configuration map in use
654 * @smpt: pointer to the sector map parameter table
655 * @smpt_len: sector map parameter table length
657 * Return: pointer to the map in use, ERR_PTR(-errno) otherwise.
670 /* Use a kmalloc'ed bounce buffer to guarantee it is DMA-able. */ in spi_nor_get_map_in_use()
673 return ERR_PTR(-ENOMEM); in spi_nor_get_map_in_use()
675 addr_width = nor->addr_width; in spi_nor_get_map_in_use()
676 read_dummy = nor->read_dummy; in spi_nor_get_map_in_use()
677 read_opcode = nor->read_opcode; in spi_nor_get_map_in_use()
686 nor->addr_width = spi_nor_smpt_addr_width(nor, smpt[i]); in spi_nor_get_map_in_use()
687 nor->read_dummy = spi_nor_smpt_read_dummy(nor, smpt[i]); in spi_nor_get_map_in_use()
688 nor->read_opcode = SMPT_CMD_OPCODE(smpt[i]); in spi_nor_get_map_in_use()
698 * Build an index value that is used to select the Sector Map in spi_nor_get_map_in_use()
705 * If command descriptors are provided, they always precede map in spi_nor_get_map_in_use()
709 * Find the matching configuration map. in spi_nor_get_map_in_use()
711 ret = ERR_PTR(-EINVAL); in spi_nor_get_map_in_use()
719 * If there are no more configuration map descriptors and no in spi_nor_get_map_in_use()
721 * sector address map is unknown. in spi_nor_get_map_in_use()
726 /* increment the table index to the next map */ in spi_nor_get_map_in_use()
733 nor->addr_width = addr_width; in spi_nor_get_map_in_use()
734 nor->read_dummy = read_dummy; in spi_nor_get_map_in_use()
735 nor->read_opcode = read_opcode; in spi_nor_get_map_in_use()
741 region->offset |= SNOR_LAST_REGION; in spi_nor_region_mark_end()
746 region->offset |= SNOR_OVERLAID_REGION; in spi_nor_region_mark_overlay()
750 * spi_nor_region_check_overlay() - set overlay bit when the region is overlaid
765 if (region->size & erase[i].size_mask) { in spi_nor_region_check_overlay()
773 * spi_nor_init_non_uniform_erase_map() - initialize the non-uniform erase map
777 * @smpt: pointer to the sector map parameter table
779 * Return: 0 on success, -errno otherwise.
786 struct spi_nor_erase_map *map = ¶ms->erase_map; in spi_nor_init_non_uniform_erase_map() local
787 struct spi_nor_erase_type *erase = map->erase_type; in spi_nor_init_non_uniform_erase_map()
800 region = devm_kcalloc(nor->dev, region_count, sizeof(*region), in spi_nor_init_non_uniform_erase_map()
803 return -ENOMEM; in spi_nor_init_non_uniform_erase_map()
804 map->regions = region; in spi_nor_init_non_uniform_erase_map()
826 * supported in this configuration map. in spi_nor_init_non_uniform_erase_map()
834 save_uniform_erase_type = map->uniform_erase_type; in spi_nor_init_non_uniform_erase_map()
835 map->uniform_erase_type = spi_nor_sort_erase_mask(map, in spi_nor_init_non_uniform_erase_map()
843 map->uniform_erase_type = save_uniform_erase_type; in spi_nor_init_non_uniform_erase_map()
844 return -EINVAL; in spi_nor_init_non_uniform_erase_map()
849 * map configurations. Mask out the erase types that are not supported in spi_nor_init_non_uniform_erase_map()
850 * by the current map configuration. in spi_nor_init_non_uniform_erase_map()
856 spi_nor_region_mark_end(®ion[i - 1]); in spi_nor_init_non_uniform_erase_map()
862 * spi_nor_parse_smpt() - parse Sector Map Parameter Table
864 * @smpt_header: sector map parameter table header
872 * Return: 0 on success, -errno otherwise.
884 /* Read the Sector Map Parameter Table. */ in spi_nor_parse_smpt()
885 len = smpt_header->length * sizeof(*smpt); in spi_nor_parse_smpt()
888 return -ENOMEM; in spi_nor_parse_smpt()
896 le32_to_cpu_array(smpt, smpt_header->length); in spi_nor_parse_smpt()
898 sector_map = spi_nor_get_map_in_use(nor, smpt, smpt_header->length); in spi_nor_parse_smpt()
908 spi_nor_regions_sort_erase_types(¶ms->erase_map); in spi_nor_parse_smpt()
916 * spi_nor_parse_4bait() - parse the 4-Byte Address Instruction Table
919 * the 4-Byte Address Instruction Table length and version.
922 * Return: 0 on success, -errno otherwise.
950 struct spi_nor_pp_command *params_pp = params->page_programs; in spi_nor_parse_4bait()
951 struct spi_nor_erase_map *map = ¶ms->erase_map; in spi_nor_parse_4bait() local
952 struct spi_nor_erase_type *erase_type = map->erase_type; in spi_nor_parse_4bait()
958 if (param_header->major != SFDP_JESD216_MAJOR || in spi_nor_parse_4bait()
959 param_header->length < SFDP_4BAIT_DWORD_MAX) in spi_nor_parse_4bait()
960 return -EINVAL; in spi_nor_parse_4bait()
962 /* Read the 4-byte Address Instruction Table. */ in spi_nor_parse_4bait()
965 /* Use a kmalloc'ed bounce buffer to guarantee it is DMA-able. */ in spi_nor_parse_4bait()
968 return -ENOMEM; in spi_nor_parse_4bait()
979 * Compute the subset of (Fast) Read commands for which the 4-byte in spi_nor_parse_4bait()
987 discard_hwcaps |= read->hwcaps; in spi_nor_parse_4bait()
988 if ((params->hwcaps.mask & read->hwcaps) && in spi_nor_parse_4bait()
989 (dwords[0] & read->supported_bit)) in spi_nor_parse_4bait()
990 read_hwcaps |= read->hwcaps; in spi_nor_parse_4bait()
994 * Compute the subset of Page Program commands for which the 4-byte in spi_nor_parse_4bait()
1004 * Bypass the params->hwcaps.mask and consider 4BAIT the biggest in spi_nor_parse_4bait()
1007 discard_hwcaps |= program->hwcaps; in spi_nor_parse_4bait()
1008 if (dwords[0] & program->supported_bit) in spi_nor_parse_4bait()
1009 pp_hwcaps |= program->hwcaps; in spi_nor_parse_4bait()
1013 * Compute the subset of Sector Erase commands for which the 4-byte in spi_nor_parse_4bait()
1020 if (dwords[0] & erase->supported_bit) in spi_nor_parse_4bait()
1024 /* Replicate the sort done for the map's erase types in BFPT. */ in spi_nor_parse_4bait()
1025 erase_mask = spi_nor_sort_erase_mask(map, erase_mask); in spi_nor_parse_4bait()
1028 * We need at least one 4-byte op code per read, program and erase in spi_nor_parse_4bait()
1030 * nor->addr_width value. in spi_nor_parse_4bait()
1036 * Discard all operations from the 4-byte instruction set which are in spi_nor_parse_4bait()
1039 params->hwcaps.mask &= ~discard_hwcaps; in spi_nor_parse_4bait()
1040 params->hwcaps.mask |= (read_hwcaps | pp_hwcaps); in spi_nor_parse_4bait()
1042 /* Use the 4-byte address instruction set. */ in spi_nor_parse_4bait()
1044 struct spi_nor_read_command *read_cmd = ¶ms->reads[i]; in spi_nor_parse_4bait()
1046 read_cmd->opcode = spi_nor_convert_3to4_read(read_cmd->opcode); in spi_nor_parse_4bait()
1077 nor->addr_width = 4; in spi_nor_parse_4bait()
1078 nor->flags |= SNOR_F_4B_OPCODES | SNOR_F_HAS_4BAIT; in spi_nor_parse_4bait()
1087 * spi_nor_parse_sfdp() - parse the Serial Flash Discoverable Parameters.
1094 * (Q)SPI memory manufacturers. Those hard-coded tables allow us to learn at
1098 * Return: 0 on success, -errno otherwise.
1106 struct device *dev = nor->dev; in spi_nor_parse_sfdp()
1118 return -EINVAL; in spi_nor_parse_sfdp()
1126 bfpt_header->major != SFDP_JESD216_MAJOR) in spi_nor_parse_sfdp()
1127 return -EINVAL; in spi_nor_parse_sfdp()
1145 return -ENOMEM; in spi_nor_parse_sfdp()
1163 param_header->major == SFDP_JESD216_MAJOR && in spi_nor_parse_sfdp()
1164 (param_header->minor > bfpt_header->minor || in spi_nor_parse_sfdp()
1165 (param_header->minor == bfpt_header->minor && in spi_nor_parse_sfdp()
1166 param_header->length > bfpt_header->length))) in spi_nor_parse_sfdp()