mtd: spi-nor: sfdp: Add support for SCCR map for multi-chip device
SCCR map for multi-chip devices contains the number of additional dice in the device and register offset values for each additional dice. spi_nor_parse_sccr_mc() is added to determine the number of dice and volatile register offset for each die. The volatile register offset table may already be allocated and contains offset value for die-0 via SCCR map parse. So, we should use devm_krealloc() to expand the table with preserving die-0 offset. Signed-off-by: Takahiro Kuwano <Takahiro.Kuwano@infineon.com> Link: https://lore.kernel.org/r/89c892d52f8cbddbd14373f6a02db496885ae4f1.1680849425.git.Takahiro.Kuwano@infineon.com Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
This commit is contained in:
parent
706fd00da0
commit
7ab8b81075
@ -26,6 +26,11 @@
|
||||
* Status, Control and Configuration
|
||||
* Register Map.
|
||||
*/
|
||||
#define SFDP_SCCR_MAP_MC_ID 0xff88 /*
|
||||
* Status, Control and Configuration
|
||||
* Register Map Offsets for Multi-Chip
|
||||
* SPI Memory Devices.
|
||||
*/
|
||||
|
||||
#define SFDP_SIGNATURE 0x50444653U
|
||||
|
||||
@ -1264,6 +1269,63 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* spi_nor_parse_sccr_mc() - Parse the Status, Control and Configuration
|
||||
* Register Map Offsets for Multi-Chip SPI Memory
|
||||
* Devices.
|
||||
* @nor: pointer to a 'struct spi_nor'
|
||||
* @sccr_mc_header: pointer to the 'struct sfdp_parameter_header' describing
|
||||
* the SCCR Map offsets table length and version.
|
||||
*
|
||||
* Return: 0 on success, -errno otherwise.
|
||||
*/
|
||||
static int spi_nor_parse_sccr_mc(struct spi_nor *nor,
|
||||
const struct sfdp_parameter_header *sccr_mc_header)
|
||||
{
|
||||
struct spi_nor_flash_parameter *params = nor->params;
|
||||
u32 *dwords, addr;
|
||||
u8 i, n_dice;
|
||||
size_t len;
|
||||
int ret;
|
||||
|
||||
len = sccr_mc_header->length * sizeof(*dwords);
|
||||
dwords = kmalloc(len, GFP_KERNEL);
|
||||
if (!dwords)
|
||||
return -ENOMEM;
|
||||
|
||||
addr = SFDP_PARAM_HEADER_PTP(sccr_mc_header);
|
||||
ret = spi_nor_read_sfdp(nor, addr, len, dwords);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
le32_to_cpu_array(dwords, sccr_mc_header->length);
|
||||
|
||||
/*
|
||||
* Pair of DOWRDs (volatile and non-volatile register offsets) per
|
||||
* additional die. Hence, length = 2 * (number of additional dice).
|
||||
*/
|
||||
n_dice = 1 + sccr_mc_header->length / 2;
|
||||
|
||||
/* Address offset for volatile registers of additional dice */
|
||||
params->vreg_offset =
|
||||
devm_krealloc(nor->dev, params->vreg_offset,
|
||||
n_dice * sizeof(*dwords),
|
||||
GFP_KERNEL);
|
||||
if (!params->vreg_offset) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 1; i < n_dice; i++)
|
||||
params->vreg_offset[i] = dwords[SFDP_DWORD(i) * 2];
|
||||
|
||||
params->n_dice = n_dice;
|
||||
|
||||
out:
|
||||
kfree(dwords);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* spi_nor_post_sfdp_fixups() - Updates the flash's parameters and settings
|
||||
* after SFDP has been parsed. Called only for flashes that define JESD216 SFDP
|
||||
@ -1480,6 +1542,10 @@ int spi_nor_parse_sfdp(struct spi_nor *nor)
|
||||
err = spi_nor_parse_sccr(nor, param_header);
|
||||
break;
|
||||
|
||||
case SFDP_SCCR_MAP_MC_ID:
|
||||
err = spi_nor_parse_sccr_mc(nor, param_header);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user