Skip to content

Commit 7ab8b81

Browse files
Kuwano-sanambarus
authored andcommitted
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>
1 parent 706fd00 commit 7ab8b81

1 file changed

Lines changed: 66 additions & 0 deletions

File tree

drivers/mtd/spi-nor/sfdp.c

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@
2626
* Status, Control and Configuration
2727
* Register Map.
2828
*/
29+
#define SFDP_SCCR_MAP_MC_ID 0xff88 /*
30+
* Status, Control and Configuration
31+
* Register Map Offsets for Multi-Chip
32+
* SPI Memory Devices.
33+
*/
2934

3035
#define SFDP_SIGNATURE 0x50444653U
3136

@@ -1264,6 +1269,63 @@ static int spi_nor_parse_sccr(struct spi_nor *nor,
12641269
return ret;
12651270
}
12661271

1272+
/**
1273+
* spi_nor_parse_sccr_mc() - Parse the Status, Control and Configuration
1274+
* Register Map Offsets for Multi-Chip SPI Memory
1275+
* Devices.
1276+
* @nor: pointer to a 'struct spi_nor'
1277+
* @sccr_mc_header: pointer to the 'struct sfdp_parameter_header' describing
1278+
* the SCCR Map offsets table length and version.
1279+
*
1280+
* Return: 0 on success, -errno otherwise.
1281+
*/
1282+
static int spi_nor_parse_sccr_mc(struct spi_nor *nor,
1283+
const struct sfdp_parameter_header *sccr_mc_header)
1284+
{
1285+
struct spi_nor_flash_parameter *params = nor->params;
1286+
u32 *dwords, addr;
1287+
u8 i, n_dice;
1288+
size_t len;
1289+
int ret;
1290+
1291+
len = sccr_mc_header->length * sizeof(*dwords);
1292+
dwords = kmalloc(len, GFP_KERNEL);
1293+
if (!dwords)
1294+
return -ENOMEM;
1295+
1296+
addr = SFDP_PARAM_HEADER_PTP(sccr_mc_header);
1297+
ret = spi_nor_read_sfdp(nor, addr, len, dwords);
1298+
if (ret)
1299+
goto out;
1300+
1301+
le32_to_cpu_array(dwords, sccr_mc_header->length);
1302+
1303+
/*
1304+
* Pair of DOWRDs (volatile and non-volatile register offsets) per
1305+
* additional die. Hence, length = 2 * (number of additional dice).
1306+
*/
1307+
n_dice = 1 + sccr_mc_header->length / 2;
1308+
1309+
/* Address offset for volatile registers of additional dice */
1310+
params->vreg_offset =
1311+
devm_krealloc(nor->dev, params->vreg_offset,
1312+
n_dice * sizeof(*dwords),
1313+
GFP_KERNEL);
1314+
if (!params->vreg_offset) {
1315+
ret = -ENOMEM;
1316+
goto out;
1317+
}
1318+
1319+
for (i = 1; i < n_dice; i++)
1320+
params->vreg_offset[i] = dwords[SFDP_DWORD(i) * 2];
1321+
1322+
params->n_dice = n_dice;
1323+
1324+
out:
1325+
kfree(dwords);
1326+
return ret;
1327+
}
1328+
12671329
/**
12681330
* spi_nor_post_sfdp_fixups() - Updates the flash's parameters and settings
12691331
* 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)
14801542
err = spi_nor_parse_sccr(nor, param_header);
14811543
break;
14821544

1545+
case SFDP_SCCR_MAP_MC_ID:
1546+
err = spi_nor_parse_sccr_mc(nor, param_header);
1547+
break;
1548+
14831549
default:
14841550
break;
14851551
}

0 commit comments

Comments
 (0)