spi: spi-cadence-quadspi: mram: check if unlock succeeded

Signed-off-by: Heinrich Toews <ht@twx-software.de>
This commit is contained in:
Heinrich Toews
2026-02-17 13:05:36 +01:00
parent 50d61d9673
commit 1a161c4be2
+54 -22
View File
@@ -28,14 +28,30 @@ static int everspin_mram_write_reg(struct spi_nor *nor, u32 addr, u8 val)
return spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto);
}
static void everspin_mram_default_init(struct spi_nor *nor)
/**
* everspin_mram_unlock - Clears Block Protection bits in Status Register 1
*/
static int everspin_mram_unlock(struct spi_nor *nor)
{
struct spi_mem_op op;
int ret;
dev_info(nor->dev, "Starting Everspin MRAM initialization (STR Octal)...\n");
/* Send Write Enable (WREN) */
spi_nor_write_enable(nor);
/* 1. Read Status Register 1 (SR1) to diagnose BP bits */
/* Write 0x00 to Status Register 1 (Opcode 01h) */
nor->bouncebuf[0] = 0x00;
op = (struct spi_mem_op)
SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WRSR, 1),
SPI_MEM_OP_NO_ADDR,
SPI_MEM_OP_NO_DUMMY,
SPI_MEM_OP_DATA_OUT(1, nor->bouncebuf, 1));
ret = spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto);
if (ret)
return ret;
/* Verify: Read back SR1 */
op = (struct spi_mem_op)
SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDSR, 1),
SPI_MEM_OP_NO_ADDR,
@@ -43,32 +59,48 @@ static void everspin_mram_default_init(struct spi_nor *nor)
SPI_MEM_OP_DATA_IN(1, nor->bouncebuf, 1));
ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
if (ret) {
dev_err(nor->dev, "Error reading SR1 register (%d)\n", ret);
} else {
if (ret)
return ret;
/* Check value at pointer address */
if (nor->bouncebuf[0] & GENMASK(5, 2)) {
dev_err(nor->dev, "Unlock failed! SR1 still 0x%02x\n", nor->bouncebuf[0]);
return -EACCES;
}
dev_info(nor->dev, "Unlock successful. SR1 is now 0x%02x\n", nor->bouncebuf[0]);
return 0;
}
static void everspin_mram_default_init(struct spi_nor *nor)
{
struct spi_mem_op op;
int ret;
dev_info(nor->dev, "Starting Everspin MRAM initialization (STR Octal)...\n");
/* 1. Read SR1 and unlock if necessary */
op = (struct spi_mem_op)
SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDSR, 1),
SPI_MEM_OP_NO_ADDR,
SPI_MEM_OP_NO_DUMMY,
SPI_MEM_OP_DATA_IN(1, nor->bouncebuf, 1));
ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
if (!ret) {
u8 sr1 = nor->bouncebuf[0];
u8 bp_bits = (sr1 & GENMASK(5, 2)) >> 2;
dev_info(nor->dev, "SR1: 0x%02x | BP bits: 0x%x (0 = no protection)\n", sr1, bp_bits);
if (bp_bits) {
dev_info(nor->dev, "Unlocking MRAM (clearing BP bits)...\n");
spi_nor_write_enable(nor);
nor->bouncebuf[0] = 0;
op = (struct spi_mem_op)
SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WRSR, 1),
SPI_MEM_OP_NO_ADDR,
SPI_MEM_OP_NO_DUMMY,
SPI_MEM_OP_DATA_OUT(1, nor->bouncebuf, 1));
spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto);
if (sr1 & GENMASK(5, 2)) {
dev_info(nor->dev, "SR1: 0x%02x | Protection detected, unlocking...\n", sr1);
everspin_mram_unlock(nor);
} else {
dev_info(nor->dev, "SR1: 0x%02x | No protection active.\n", sr1);
}
}
/* 2. Switch to Octal Mode via CFR1V */
dev_info(nor->dev, "Setting CFR1V to Octal STR (Addr 0x%x)...\n", SPINOR_REG_EVERSPIN_CFR1V);
ret = everspin_mram_write_reg(nor, SPINOR_REG_EVERSPIN_CFR1V, EVERSPIN_OCTAL_STR_ENABLE);
if (ret)
dev_err(nor->dev, "Error writing CFR1V mode register (%d)\n", ret);
else
dev_info(nor->dev, "CFR1V successfully set to Octal STR.\n");
dev_err(nor->dev, "Error writing CFR1V register (%d)\n", ret);
/* 3. Synchronize kernel parameters */
nor->cmd_ext_type = SPI_NOR_EXT_REPEAT;