aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mtd/devices/st_spi_fsm.c113
1 files changed, 112 insertions, 1 deletions
diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index 99e08b01a32d..34aac3f49ba9 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -567,6 +567,27 @@ static struct stfsm_seq stfsm_seq_erase_sector = {
567 SEQ_CFG_STARTSEQ), 567 SEQ_CFG_STARTSEQ),
568}; 568};
569 569
570static struct stfsm_seq stfsm_seq_erase_chip = {
571 .seq_opc = {
572 (SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) |
573 SEQ_OPC_OPCODE(FLASH_CMD_WREN) | SEQ_OPC_CSDEASSERT),
574
575 (SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) |
576 SEQ_OPC_OPCODE(FLASH_CMD_CHIPERASE) | SEQ_OPC_CSDEASSERT),
577 },
578 .seq = {
579 STFSM_INST_CMD1,
580 STFSM_INST_CMD2,
581 STFSM_INST_WAIT,
582 STFSM_INST_STOP,
583 },
584 .seq_cfg = (SEQ_CFG_PADS_1 |
585 SEQ_CFG_ERASE |
586 SEQ_CFG_READNOTWRITE |
587 SEQ_CFG_CSDEASSERT |
588 SEQ_CFG_STARTSEQ),
589};
590
570static struct stfsm_seq stfsm_seq_wrvcr = { 591static struct stfsm_seq stfsm_seq_wrvcr = {
571 .seq_opc[0] = (SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) | 592 .seq_opc[0] = (SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) |
572 SEQ_OPC_OPCODE(FLASH_CMD_WREN) | SEQ_OPC_CSDEASSERT), 593 SEQ_OPC_OPCODE(FLASH_CMD_WREN) | SEQ_OPC_CSDEASSERT),
@@ -1217,6 +1238,47 @@ static int stfsm_mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
1217 return 0; 1238 return 0;
1218} 1239}
1219 1240
1241static int stfsm_erase_sector(struct stfsm *fsm, const uint32_t offset)
1242{
1243 struct stfsm_seq *seq = &stfsm_seq_erase_sector;
1244 int ret;
1245
1246 dev_dbg(fsm->dev, "erasing sector at 0x%08x\n", offset);
1247
1248 /* Enter 32-bit address mode, if required */
1249 if (fsm->configuration & CFG_ERASESEC_TOGGLE_32BIT_ADDR)
1250 stfsm_enter_32bit_addr(fsm, 1);
1251
1252 seq->addr1 = (offset >> 16) & 0xffff;
1253 seq->addr2 = offset & 0xffff;
1254
1255 stfsm_load_seq(fsm, seq);
1256
1257 stfsm_wait_seq(fsm);
1258
1259 /* Wait for completion */
1260 ret = stfsm_wait_busy(fsm);
1261
1262 /* Exit 32-bit address mode, if required */
1263 if (fsm->configuration & CFG_ERASESEC_TOGGLE_32BIT_ADDR)
1264 stfsm_enter_32bit_addr(fsm, 0);
1265
1266 return ret;
1267}
1268
1269static int stfsm_erase_chip(struct stfsm *fsm)
1270{
1271 const struct stfsm_seq *seq = &stfsm_seq_erase_chip;
1272
1273 dev_dbg(fsm->dev, "erasing chip\n");
1274
1275 stfsm_load_seq(fsm, seq);
1276
1277 stfsm_wait_seq(fsm);
1278
1279 return stfsm_wait_busy(fsm);
1280}
1281
1220/* 1282/*
1221 * Write an address range to the flash chip. Data must be written in 1283 * Write an address range to the flash chip. Data must be written in
1222 * FLASH_PAGESIZE chunks. The address range may be any size provided 1284 * FLASH_PAGESIZE chunks. The address range may be any size provided
@@ -1272,6 +1334,54 @@ out1:
1272 return ret; 1334 return ret;
1273} 1335}
1274 1336
1337/*
1338 * Erase an address range on the flash chip. The address range may extend
1339 * one or more erase sectors. Return an error is there is a problem erasing.
1340 */
1341static int stfsm_mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
1342{
1343 struct stfsm *fsm = dev_get_drvdata(mtd->dev.parent);
1344 u32 addr, len;
1345 int ret;
1346
1347 dev_dbg(fsm->dev, "%s at 0x%llx, len %lld\n", __func__,
1348 (long long)instr->addr, (long long)instr->len);
1349
1350 addr = instr->addr;
1351 len = instr->len;
1352
1353 mutex_lock(&fsm->lock);
1354
1355 /* Whole-chip erase? */
1356 if (len == mtd->size) {
1357 ret = stfsm_erase_chip(fsm);
1358 if (ret)
1359 goto out1;
1360 } else {
1361 while (len) {
1362 ret = stfsm_erase_sector(fsm, addr);
1363 if (ret)
1364 goto out1;
1365
1366 addr += mtd->erasesize;
1367 len -= mtd->erasesize;
1368 }
1369 }
1370
1371 mutex_unlock(&fsm->lock);
1372
1373 instr->state = MTD_ERASE_DONE;
1374 mtd_erase_callback(instr);
1375
1376 return 0;
1377
1378out1:
1379 instr->state = MTD_ERASE_FAILED;
1380 mutex_unlock(&fsm->lock);
1381
1382 return ret;
1383}
1384
1275static void stfsm_read_jedec(struct stfsm *fsm, uint8_t *const jedec) 1385static void stfsm_read_jedec(struct stfsm *fsm, uint8_t *const jedec)
1276{ 1386{
1277 const struct stfsm_seq *seq = &stfsm_seq_read_jedec; 1387 const struct stfsm_seq *seq = &stfsm_seq_read_jedec;
@@ -1529,8 +1639,9 @@ static int stfsm_probe(struct platform_device *pdev)
1529 1639
1530 fsm->mtd._read = stfsm_mtd_read; 1640 fsm->mtd._read = stfsm_mtd_read;
1531 fsm->mtd._write = stfsm_mtd_write; 1641 fsm->mtd._write = stfsm_mtd_write;
1642 fsm->mtd._erase = stfsm_mtd_erase;
1532 1643
1533 dev_err(&pdev->dev, 1644 dev_info(&pdev->dev,
1534 "Found serial flash device: %s\n" 1645 "Found serial flash device: %s\n"
1535 " size = %llx (%lldMiB) erasesize = 0x%08x (%uKiB)\n", 1646 " size = %llx (%lldMiB) erasesize = 0x%08x (%uKiB)\n",
1536 info->name, 1647 info->name,