in spi-nor/sfdp.c [432:637]
static int spi_nor_parse_bfpt(struct spi_nor *nor,
const struct sfdp_parameter_header *bfpt_header)
{
struct spi_nor_flash_parameter *params = nor->params;
struct spi_nor_erase_map *map = ¶ms->erase_map;
struct spi_nor_erase_type *erase_type = map->erase_type;
struct sfdp_bfpt bfpt;
size_t len;
int i, cmd, err;
u32 addr, val;
u16 half;
u8 erase_mask;
/* JESD216 Basic Flash Parameter Table length is at least 9 DWORDs. */
if (bfpt_header->length < BFPT_DWORD_MAX_JESD216)
return -EINVAL;
/* Read the Basic Flash Parameter Table. */
len = min_t(size_t, sizeof(bfpt),
bfpt_header->length * sizeof(u32));
addr = SFDP_PARAM_HEADER_PTP(bfpt_header);
memset(&bfpt, 0, sizeof(bfpt));
err = spi_nor_read_sfdp_dma_unsafe(nor, addr, len, &bfpt);
if (err < 0)
return err;
/* Fix endianness of the BFPT DWORDs. */
le32_to_cpu_array(bfpt.dwords, BFPT_DWORD_MAX);
/* Number of address bytes. */
switch (bfpt.dwords[BFPT_DWORD(1)] & BFPT_DWORD1_ADDRESS_BYTES_MASK) {
case BFPT_DWORD1_ADDRESS_BYTES_3_ONLY:
case BFPT_DWORD1_ADDRESS_BYTES_3_OR_4:
nor->addr_width = 3;
break;
case BFPT_DWORD1_ADDRESS_BYTES_4_ONLY:
nor->addr_width = 4;
break;
default:
break;
}
/* Flash Memory Density (in bits). */
val = bfpt.dwords[BFPT_DWORD(2)];
if (val & BIT(31)) {
val &= ~BIT(31);
/*
* Prevent overflows on params->size. Anyway, a NOR of 2^64
* bits is unlikely to exist so this error probably means
* the BFPT we are reading is corrupted/wrong.
*/
if (val > 63)
return -EINVAL;
params->size = 1ULL << val;
} else {
params->size = val + 1;
}
params->size >>= 3; /* Convert to bytes. */
/* Fast Read settings. */
for (i = 0; i < ARRAY_SIZE(sfdp_bfpt_reads); i++) {
const struct sfdp_bfpt_read *rd = &sfdp_bfpt_reads[i];
struct spi_nor_read_command *read;
if (!(bfpt.dwords[rd->supported_dword] & rd->supported_bit)) {
params->hwcaps.mask &= ~rd->hwcaps;
continue;
}
params->hwcaps.mask |= rd->hwcaps;
cmd = spi_nor_hwcaps_read2cmd(rd->hwcaps);
read = ¶ms->reads[cmd];
half = bfpt.dwords[rd->settings_dword] >> rd->settings_shift;
spi_nor_set_read_settings_from_bfpt(read, half, rd->proto);
}
/*
* Sector Erase settings. Reinitialize the uniform erase map using the
* Erase Types defined in the bfpt table.
*/
erase_mask = 0;
memset(¶ms->erase_map, 0, sizeof(params->erase_map));
for (i = 0; i < ARRAY_SIZE(sfdp_bfpt_erases); i++) {
const struct sfdp_bfpt_erase *er = &sfdp_bfpt_erases[i];
u32 erasesize;
u8 opcode;
half = bfpt.dwords[er->dword] >> er->shift;
erasesize = half & 0xff;
/* erasesize == 0 means this Erase Type is not supported. */
if (!erasesize)
continue;
erasesize = 1U << erasesize;
opcode = (half >> 8) & 0xff;
erase_mask |= BIT(i);
spi_nor_set_erase_settings_from_bfpt(&erase_type[i], erasesize,
opcode, i);
}
spi_nor_init_uniform_erase_map(map, erase_mask, params->size);
/*
* Sort all the map's Erase Types in ascending order with the smallest
* erase size being the first member in the erase_type array.
*/
sort(erase_type, SNOR_ERASE_TYPE_MAX, sizeof(erase_type[0]),
spi_nor_map_cmp_erase_type, NULL);
/*
* Sort the erase types in the uniform region in order to update the
* uniform_erase_type bitmask. The bitmask will be used later on when
* selecting the uniform erase.
*/
spi_nor_regions_sort_erase_types(map);
map->uniform_erase_type = map->uniform_region.offset &
SNOR_ERASE_TYPE_MASK;
/* Stop here if not JESD216 rev A or later. */
if (bfpt_header->length == BFPT_DWORD_MAX_JESD216)
return spi_nor_post_bfpt_fixups(nor, bfpt_header, &bfpt);
/* Page size: this field specifies 'N' so the page size = 2^N bytes. */
val = bfpt.dwords[BFPT_DWORD(11)];
val &= BFPT_DWORD11_PAGE_SIZE_MASK;
val >>= BFPT_DWORD11_PAGE_SIZE_SHIFT;
params->page_size = 1U << val;
/* Quad Enable Requirements. */
switch (bfpt.dwords[BFPT_DWORD(15)] & BFPT_DWORD15_QER_MASK) {
case BFPT_DWORD15_QER_NONE:
params->quad_enable = NULL;
break;
case BFPT_DWORD15_QER_SR2_BIT1_BUGGY:
/*
* Writing only one byte to the Status Register has the
* side-effect of clearing Status Register 2.
*/
case BFPT_DWORD15_QER_SR2_BIT1_NO_RD:
/*
* Read Configuration Register (35h) instruction is not
* supported.
*/
nor->flags |= SNOR_F_HAS_16BIT_SR | SNOR_F_NO_READ_CR;
params->quad_enable = spi_nor_sr2_bit1_quad_enable;
break;
case BFPT_DWORD15_QER_SR1_BIT6:
nor->flags &= ~SNOR_F_HAS_16BIT_SR;
params->quad_enable = spi_nor_sr1_bit6_quad_enable;
break;
case BFPT_DWORD15_QER_SR2_BIT7:
nor->flags &= ~SNOR_F_HAS_16BIT_SR;
params->quad_enable = spi_nor_sr2_bit7_quad_enable;
break;
case BFPT_DWORD15_QER_SR2_BIT1:
/*
* JESD216 rev B or later does not specify if writing only one
* byte to the Status Register clears or not the Status
* Register 2, so let's be cautious and keep the default
* assumption of a 16-bit Write Status (01h) command.
*/
nor->flags |= SNOR_F_HAS_16BIT_SR;
params->quad_enable = spi_nor_sr2_bit1_quad_enable;
break;
default:
dev_dbg(nor->dev, "BFPT QER reserved value used\n");
break;
}
/* Soft Reset support. */
if (bfpt.dwords[BFPT_DWORD(16)] & BFPT_DWORD16_SWRST_EN_RST)
nor->flags |= SNOR_F_SOFT_RESET;
/* Stop here if not JESD216 rev C or later. */
if (bfpt_header->length == BFPT_DWORD_MAX_JESD216B)
return spi_nor_post_bfpt_fixups(nor, bfpt_header, &bfpt);
/* 8D-8D-8D command extension. */
switch (bfpt.dwords[BFPT_DWORD(18)] & BFPT_DWORD18_CMD_EXT_MASK) {
case BFPT_DWORD18_CMD_EXT_REP:
nor->cmd_ext_type = SPI_NOR_EXT_REPEAT;
break;
case BFPT_DWORD18_CMD_EXT_INV:
nor->cmd_ext_type = SPI_NOR_EXT_INVERT;
break;
case BFPT_DWORD18_CMD_EXT_RES:
dev_dbg(nor->dev, "Reserved command extension used\n");
break;
case BFPT_DWORD18_CMD_EXT_16B:
dev_dbg(nor->dev, "16-bit opcodes not supported\n");
return -EOPNOTSUPP;
}
return spi_nor_post_bfpt_fixups(nor, bfpt_header, &bfpt);
}