Sergii Dmytruk has uploaded this change for review.

View Change

[RFC] flashchips: add support for OTP to several chip models

Added configurations matches new chips in dummyflasher.

Change-Id: I98491ed00d1e5fa6682bcdc4d5e132ec76447f21
Signed-off-by: Hatim Kanchwala <hatim at hatimak.me>
Signed-off-by: Sergii Dmytruk <sergii.dmytruk@3mdeb.com>
---
M Makefile
M flashchips.c
M meson.build
M otp.h
A otp_layouts.c
5 files changed, 227 insertions(+), 27 deletions(-)

git pull ssh://review.coreboot.org:29418/flashrom refs/changes/05/59405/1
diff --git a/Makefile b/Makefile
index 74acbfc..7e8d0b0 100644
--- a/Makefile
+++ b/Makefile
@@ -314,7 +314,7 @@
sst28sf040.o 82802ab.o \
sst49lfxxxc.o sst_fwhub.o edi.o flashchips.o spi.o spi25.o spi25_statusreg.o \
spi95.o opaque.o sfdp.o en29lv640b.o at45db.o s25f.o \
- otp.o writeprotect.o writeprotect_ranges.o
+ otp.o otp_layouts.o writeprotect.o writeprotect_ranges.o

###############################################################################
# Library code.
diff --git a/flashchips.c b/flashchips.c
index b26681d..6bad720 100644
--- a/flashchips.c
+++ b/flashchips.c
@@ -21,6 +21,7 @@
#include "flash.h"
#include "flashchips.h"
#include "chipdrivers.h"
+#include "otp.h"

/**
* List of supported flash chips.
@@ -4955,8 +4956,8 @@
.model_id = EON_EN25Q16,
.total_size = 2048,
.page_size = 256,
- /* OTP: D16 512B/Q16 128B total; enter 0x3A */
- .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ /* OTP: D16 512B/Q16 128B total */
+ .feature_bits = FEATURE_WRSR_WREN,
.tested = TEST_UNTESTED,
.probe = probe_spi_rdid,
.probe_timing = TIMING_ZERO,
@@ -4985,6 +4986,7 @@
.write = spi_chip_write_256,
.read = spi_chip_read,
.voltage = {2700, 3600},
+ .otp = &en128_2048otp,
},

{
@@ -4995,8 +4997,7 @@
.model_id = EON_EN25Q32,
.total_size = 4096,
.page_size = 256,
- /* OTP: 512B total; enter 0x3A */
- .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .feature_bits = FEATURE_WRSR_WREN,
.tested = TEST_OK_PREW,
.probe = probe_spi_rdid,
.probe_timing = TIMING_ZERO,
@@ -5021,6 +5022,7 @@
.write = spi_chip_write_256,
.read = spi_chip_read,
.voltage = {2700, 3600},
+ .otp = &en512_4096otp,
},

{
@@ -5031,8 +5033,7 @@
.model_id = EON_EN25Q40,
.total_size = 512,
.page_size = 256,
- /* OTP: 256B total; enter 0x3A */
- .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .feature_bits = FEATURE_WRSR_WREN,
.tested = TEST_UNTESTED,
.probe = probe_spi_rdid,
.probe_timing = TIMING_ZERO,
@@ -5057,6 +5058,7 @@
.write = spi_chip_write_256,
.read = spi_chip_read,
.voltage = {2700, 3600},
+ .otp = &en256_512otp,
},

{
@@ -5067,8 +5069,7 @@
.model_id = EON_EN25Q64,
.total_size = 8192,
.page_size = 256,
- /* OTP: 512B total; enter 0x3A */
- .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .feature_bits = FEATURE_WRSR_WREN,
.tested = TEST_OK_PREW,
.probe = probe_spi_rdid,
.probe_timing = TIMING_ZERO,
@@ -5093,6 +5094,7 @@
.write = spi_chip_write_256,
.read = spi_chip_read,
.voltage = {2700, 3600},
+ .otp = &en512_8192otp,
},

{
@@ -5103,8 +5105,7 @@
.model_id = EON_EN25Q80,
.total_size = 1024,
.page_size = 256,
- /* OTP: 256B total; enter 0x3A */
- .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .feature_bits = FEATURE_WRSR_WREN,
.tested = TEST_UNTESTED,
.probe = probe_spi_rdid,
.probe_timing = TIMING_ZERO,
@@ -5129,6 +5130,7 @@
.write = spi_chip_write_256,
.read = spi_chip_read,
.voltage = {2700, 3600},
+ .otp = &en256_1024otp,
},

{
@@ -5140,9 +5142,8 @@
.total_size = 16384,
.page_size = 256,
/* supports SFDP */
- /* OTP: 512B total; enter 0x3A */
/* QPI enable 0x38, disable 0xFF */
- .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_QPI,
.tested = TEST_OK_PREW,
.probe = probe_spi_rdid,
.probe_timing = TIMING_ZERO,
@@ -5167,6 +5168,7 @@
.write = spi_chip_write_256,
.read = spi_chip_read,
.voltage = {2700, 3600},
+ .otp = &en512_16384otp,
},

{
@@ -5178,9 +5180,8 @@
.total_size = 2048,
.page_size = 256,
/* supports SFDP */
- /* OTP: 512B total; enter 0x3A */
/* QPI enable 0x38, disable 0xFF */
- .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_QPI,
.tested = TEST_OK_PREW,
.probe = probe_spi_rdid,
.probe_timing = TIMING_ZERO,
@@ -5205,6 +5206,7 @@
.write = spi_chip_write_256,
.read = spi_chip_read,
.voltage = {2700, 3600},
+ .otp = &en512_2048otp,
},

{
@@ -5216,9 +5218,8 @@
.total_size = 4096,
.page_size = 256,
/* supports SFDP */
- /* OTP: 512B total; enter 0x3A */
/* QPI enable 0x38, disable 0xFF */
- .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_QPI,
.tested = TEST_OK_PREW,
.probe = probe_spi_rdid,
.probe_timing = TIMING_ZERO,
@@ -5243,6 +5244,7 @@
.write = spi_chip_write_256,
.read = spi_chip_read,
.voltage = {2700, 3600},
+ .otp = &en512_4096otp,
},

{
@@ -5254,9 +5256,8 @@
.total_size = 8192,
.page_size = 256,
/* supports SFDP */
- /* OTP: 512B total; enter 0x3A */
/* QPI enable 0x38, disable 0xFF */
- .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_QPI,
.tested = TEST_OK_PREW,
.probe = probe_spi_rdid,
.probe_timing = TIMING_ZERO,
@@ -5281,6 +5282,7 @@
.write = spi_chip_write_256,
.read = spi_chip_read,
.voltage = {2700, 3600},
+ .otp = &en512_8192otp,
},

{
@@ -6588,9 +6590,9 @@
.model_id = GIGADEVICE_GD25Q128,
.total_size = 16384,
.page_size = 256,
- /* OTP: 1536B total; read 0x48; write 0x42, erase 0x44 */
/* QPI: enable 0x38, disable 0xFF */
- .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_QPI |
+ FEATURE_RDSR2 | FEATURE_WRSR2,
.tested = TEST_OK_PREW,
.probe = probe_spi_rdid,
.probe_timing = TIMING_ZERO,
@@ -6619,6 +6621,7 @@
.write = spi_chip_write_256,
.read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
.voltage = {2700, 3600},
+ .otp = &gd512_3_otp,
},

{
@@ -7022,8 +7025,7 @@
.model_id = GIGADEVICE_GD25VQ21B,
.total_size = 256,
.page_size = 256,
- /* OTP: 1536B total; read 0x48, write 0x42, erase 0x44 */
- .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_QPI,
.tested = TEST_UNTESTED,
.probe = probe_spi_rdid,
.probe_timing = TIMING_ZERO,
@@ -7051,6 +7053,7 @@
.write = spi_chip_write_256,
.read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
.voltage = {2300, 3600},
+ .otp = &gd512_3_otp,
},

{
@@ -7101,8 +7104,8 @@
.model_id = GIGADEVICE_GD25VQ41B,
.total_size = 512,
.page_size = 256,
- /* OTP: 1536B total; read 0x48, write 0x42, erase 0x44 */
- .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_QPI |
+ FEATURE_RDSR2 | FEATURE_WRSR2,
.tested = TEST_OK_PREW,
.probe = probe_spi_rdid,
.probe_timing = TIMING_ZERO,
@@ -7130,6 +7133,7 @@
.write = spi_chip_write_256,
.read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
.voltage = {2300, 3600},
+ .otp = &gd512_3_otp,
},

{
@@ -17684,8 +17688,9 @@
.total_size = 512,
.page_size = 256,
/* supports SFDP */
- /* OTP: 756B total; read 0x48; write 0x42, erase 0x44, read ID 0x4B */
- .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ /* OTP: read ID 0x4B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_RDSR2 |
+ FEATURE_WRSR_EXT,
.tested = TEST_OK_PREW,
.probe = probe_spi_rdid,
.probe_timing = TIMING_ZERO,
@@ -17713,6 +17718,7 @@
.write = spi_chip_write_256, /* Multi I/O supported */
.read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
.voltage = {2700, 3600},
+ .otp = &gd_w256_3_otp,
},

{
diff --git a/meson.build b/meson.build
index 7520943..31c12e8 100644
--- a/meson.build
+++ b/meson.build
@@ -386,6 +386,7 @@
srcs += 'libflashrom.c'
srcs += 'opaque.c'
srcs += 'otp.c'
+srcs += 'otp_layouts.c'
srcs += 'print.c'
srcs += 'programmer.c'
srcs += 'programmer_table.c'
diff --git a/otp.h b/otp.h
index cd8f7bd..5782f70 100644
--- a/otp.h
+++ b/otp.h
@@ -60,4 +60,14 @@
} regions[FLASHROM_OTP_MAX_REGIONS + 1]; /* We need one more than maximum */
};

+extern struct otp en128_2048otp;
+extern struct otp en256_512otp;
+extern struct otp en512_4096otp;
+extern struct otp en256_1024otp;
+extern struct otp en512_2048otp;
+extern struct otp en512_16384otp;
+extern struct otp en512_8192otp;
+extern struct otp gd_w256_3_otp;
+extern struct otp gd512_3_otp;
+
#endif /* !__OTP_H__ */
diff --git a/otp_layouts.c b/otp_layouts.c
new file mode 100644
index 0000000..114ac2d
--- /dev/null
+++ b/otp_layouts.c
@@ -0,0 +1,183 @@
+/*
+ * This file is part of the flashrom project.
+ *
+ * Copyright (C) 2016 Hatim Kanchwala <hatim@hatimak.me>
+ * Copyright (C) 2021 3mdeb Embedded Systems Consulting
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "otp.h"
+#include "spi.h"
+
+/*
+ * Eon (OTP mode)
+ *
+ * Because OTP region is mapped at the end of address space, structures differ
+ * based on region and flash sizes.
+ */
+
+/* EN25Q16 */
+struct otp en128_2048otp = {
+ .feature_bits = OTP_KIND_MODE | OTP_MODE_CLEAR_BP | OTP_MODE_LOCK_WHILE_IN,
+ .otp_enter_opcode = JEDEC_ENTER_OTP,
+ .otp_exit_opcode = JEDEC_WRDI,
+ .regions =
+ {
+ {
+ .addr = 0x1FF000,
+ .size = 128,
+ .status_bit = {STATUS1, 7, OTP},
+ },
+ },
+};
+
+/* EN25Q40 */
+struct otp en256_512otp = {
+ .feature_bits = OTP_KIND_MODE | OTP_MODE_CLEAR_BP | OTP_MODE_LOCK_WHILE_IN,
+ .otp_enter_opcode = JEDEC_ENTER_OTP,
+ .otp_exit_opcode = JEDEC_WRDI,
+ .regions =
+ {
+ {
+ .addr = 0x07F000,
+ .size = 256,
+ .status_bit = {STATUS1, 7, OTP},
+ },
+ },
+};
+
+/* EN25Q80(A) */
+struct otp en256_1024otp = {
+ .feature_bits = OTP_KIND_MODE | OTP_MODE_CLEAR_BP | OTP_MODE_LOCK_WHILE_IN,
+ .otp_enter_opcode = JEDEC_ENTER_OTP,
+ .otp_exit_opcode = JEDEC_WRDI,
+ .regions =
+ {
+ {
+ .addr = 0x0FF000,
+ .size = 256,
+ .status_bit = {STATUS1, 7, OTP},
+ },
+ },
+};
+
+/* EN25QH16 */
+struct otp en512_2048otp = {
+ .feature_bits = OTP_KIND_MODE | OTP_MODE_CLEAR_BP | OTP_MODE_LOCK_WHILE_IN,
+ .otp_enter_opcode = JEDEC_ENTER_OTP,
+ .otp_exit_opcode = JEDEC_WRDI,
+ .regions =
+ {
+ {
+ .addr = 0x1FF000,
+ .size = 512,
+ .status_bit = {STATUS1, 7, OTP},
+ },
+ },
+};
+
+/* EN25Q32(A/B), EN25QH32 */
+struct otp en512_4096otp = {
+ .feature_bits = OTP_KIND_MODE | OTP_MODE_CLEAR_BP | OTP_MODE_LOCK_WHILE_IN,
+ .otp_enter_opcode = JEDEC_ENTER_OTP,
+ .otp_exit_opcode = JEDEC_WRDI,
+ .regions =
+ {
+ {
+ .addr = 0x3FF000,
+ .size = 512,
+ .status_bit = {STATUS1, 7, OTP},
+ },
+ },
+};
+
+/* EN25Q64, EN25QH64 */
+struct otp en512_8192otp = {
+ .feature_bits = OTP_KIND_MODE | OTP_MODE_CLEAR_BP | OTP_MODE_LOCK_WHILE_IN,
+ .otp_enter_opcode = JEDEC_ENTER_OTP,
+ .otp_exit_opcode = JEDEC_WRDI,
+ .regions =
+ {
+ {
+ .addr = 0x7FF000,
+ .size = 512,
+ .status_bit = {STATUS1, 7, OTP},
+ },
+ },
+};
+
+/* EN25Q128, EN25QH128 */
+struct otp en512_16384otp = {
+ .feature_bits = OTP_KIND_MODE | OTP_MODE_CLEAR_BP | OTP_MODE_LOCK_WHILE_IN,
+ .otp_enter_opcode = JEDEC_ENTER_OTP,
+ .otp_exit_opcode = JEDEC_WRDI,
+ .regions =
+ {
+ {
+ .addr = 0xFFF000,
+ .size = 512,
+ .status_bit = {STATUS1, 7, OTP},
+ },
+ },
+};
+
+/*
+ * GigaDevice and Winbond (secure registers)
+ *
+ * Sizes and addresses differ, although all regions tend to be of the same size.
+ */
+
+/* W25Q40.V */
+struct otp gd_w256_3_otp = {
+ .feature_bits = OTP_KIND_REGS,
+ .regions =
+ {
+ {
+ .addr = 0x001000,
+ .size = 256,
+ .status_bit = {STATUS2, 3, OTP},
+ }, {
+ .addr = 0x002000,
+ .size = 256,
+ .status_bit = {STATUS2, 4, OTP},
+ }, {
+ .addr = 0x003000,
+ .size = 256,
+ .status_bit = {STATUS2, 5, OTP},
+ },
+ },
+};
+
+/* GD25VQ21B, GD25VQ41B, GD25Q128C */
+struct otp gd512_3_otp = {
+ .feature_bits = OTP_KIND_REGS,
+ .regions =
+ {
+ {
+ .addr = 0x001000,
+ .size = 512,
+ .status_bit = {STATUS2, 3, OTP},
+ }, {
+ .addr = 0x002000,
+ .size = 512,
+ .status_bit = {STATUS2, 4, OTP},
+ }, {
+ .addr = 0x003000,
+ .size = 512,
+ .status_bit = {STATUS2, 5, OTP},
+ },
+ },
+};

To view, visit change 59405. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: flashrom
Gerrit-Branch: master
Gerrit-Change-Id: I98491ed00d1e5fa6682bcdc4d5e132ec76447f21
Gerrit-Change-Number: 59405
Gerrit-PatchSet: 1
Gerrit-Owner: Sergii Dmytruk <sergii.dmytruk@3mdeb.com>
Gerrit-MessageType: newchange