spi: spi-cadence-quadspi: mram: check if unlock succeeded
Signed-off-by: Heinrich Toews <ht@twx-software.de>
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user