Skip to content

Commit 920caeb

Browse files
committed
mtd/spi: add OTP access command for XTX flash memory
XTX flash memory uses different commands for Read/Write/Erase in order to access OTP memory area with the same protocol for normal memory access, therefore by replacing the command is enough to access OTP memory area. Change-Id: Ifdadfe39d440fccdc0b91b05669138568821b738 Signed-off-by: Dongjin Kim <[email protected]>
1 parent 5a0beb1 commit 920caeb

File tree

1 file changed

+37
-0
lines changed

1 file changed

+37
-0
lines changed

drivers/mtd/spi/spi-nor-core.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,22 @@ static int spi_nor_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
7070
return spi_nor_read_write_reg(nor, &op, buf);
7171
}
7272

73+
/*
74+
* Since security registers in XTX flash memory uses different address
75+
* format than normal memory, the address needs to be calculated.
76+
*
77+
* Security Register #1 : 0x001000 ~ 0x0013ff (from 0x000000 ~ 0x0003ff)
78+
* Security Register #2 : 0x002000 ~ 0x0023ff (from 0x000400 ~ 0x0007ff)
79+
* Security Register #3 : 0x003000 ~ 0x0033ff (from 0x000800 ~ 0x000bff)
80+
*
81+
* This scheme must work with only certain command that access the
82+
* security registers, Read (0x48) / Write (0x42) / Erase (0x44), only.
83+
*/
84+
static u32 xtx_security_address(u32 addr)
85+
{
86+
return (((addr + 0x400) & 0xc00) << 2) | (addr & 0x3ff);
87+
}
88+
7389
static ssize_t spi_nor_read_data(struct spi_nor *nor, loff_t from, size_t len,
7490
u_char *buf)
7591
{
@@ -81,6 +97,13 @@ static ssize_t spi_nor_read_data(struct spi_nor *nor, loff_t from, size_t len,
8197
size_t remaining = len;
8298
int ret;
8399

100+
if (nor->secure_on) {
101+
if (nor->info->id[0] == 0x0b) { // XTX flash memory
102+
op.cmd.opcode = 0x48;
103+
op.addr.val = xtx_security_address(from);
104+
}
105+
}
106+
84107
/* get transfer protocols. */
85108
op.cmd.buswidth = spi_nor_get_protocol_inst_nbits(nor->read_proto);
86109
op.addr.buswidth = spi_nor_get_protocol_addr_nbits(nor->read_proto);
@@ -118,6 +141,13 @@ static ssize_t spi_nor_write_data(struct spi_nor *nor, loff_t to, size_t len,
118141
SPI_MEM_OP_DATA_OUT(len, buf, 1));
119142
int ret;
120143

144+
if (nor->secure_on) {
145+
if (nor->info->id[0] == 0x0b) { // XTX flash memory
146+
op.cmd.opcode = 0x42;
147+
op.addr.val = xtx_security_address(to);
148+
}
149+
}
150+
121151
/* get transfer protocols. */
122152
op.cmd.buswidth = spi_nor_get_protocol_inst_nbits(nor->write_proto);
123153
op.addr.buswidth = spi_nor_get_protocol_addr_nbits(nor->write_proto);
@@ -539,6 +569,13 @@ static int spi_nor_erase_sector(struct spi_nor *nor, u32 addr)
539569
SPI_MEM_OP_NO_DUMMY,
540570
SPI_MEM_OP_NO_DATA);
541571

572+
if (nor->secure_on) {
573+
if (nor->info->id[0] == 0x0b) {// XTX flash memory
574+
op.cmd.opcode = 0x44;
575+
addr = xtx_security_address(addr);
576+
}
577+
}
578+
542579
if (nor->erase)
543580
return nor->erase(nor, addr);
544581

0 commit comments

Comments
 (0)