summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorMikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>2025-09-30 03:21:02 +0300
committerMichael Trimarchi <michael@amarulasolutions.com>2025-10-05 20:26:19 +0200
commit37f0fc45f51d2c21dd117331ffdd72c94bd53d7f (patch)
tree2c9b890100593df1a7cbcc7bdfcdf3044362c452 /include
parent49b855662f7076d2eea3cd3e12a434f7be9a8449 (diff)
mtd: spinand: add OTP support
The code was ported from linux-6.15 based on a linux commit c06b1f753bea (mtd: spinand: add OTP support) created by Martin Kurbanov <mmkurbanov@salutedevices.com> Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu> Reviewed-by: Frieder Schrempf <frieder.schrempf@kontron.de> Signed-off-by: Michael Trimarchi <michael@amarulasolutions.com>
Diffstat (limited to 'include')
-rw-r--r--include/linux/mtd/spinand.h112
1 files changed, 112 insertions, 0 deletions
diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h
index 44c616a4acf..adfb5f3ffbc 100644
--- a/include/linux/mtd/spinand.h
+++ b/include/linux/mtd/spinand.h
@@ -323,6 +323,68 @@ struct spinand_ecc_info {
#define SPINAND_NO_RAW_ACCESS BIT(4)
/**
+ * struct spinand_otp_layout - structure to describe the SPI NAND OTP area
+ * @npages: number of pages in the OTP
+ * @start_page: start page of the user/factory OTP area.
+ */
+struct spinand_otp_layout {
+ unsigned int npages;
+ unsigned int start_page;
+};
+
+/**
+ * struct spinand_fact_otp_ops - SPI NAND OTP methods for factory area
+ * @info: get the OTP area information
+ * @read: read from the SPI NAND OTP area
+ */
+struct spinand_fact_otp_ops {
+ int (*info)(struct spinand_device *spinand, size_t len,
+ struct otp_info *buf, size_t *retlen);
+ int (*read)(struct spinand_device *spinand, loff_t from, size_t len,
+ size_t *retlen, u8 *buf);
+};
+
+/**
+ * struct spinand_user_otp_ops - SPI NAND OTP methods for user area
+ * @info: get the OTP area information
+ * @lock: lock an OTP region
+ * @erase: erase an OTP region
+ * @read: read from the SPI NAND OTP area
+ * @write: write to the SPI NAND OTP area
+ */
+struct spinand_user_otp_ops {
+ int (*info)(struct spinand_device *spinand, size_t len,
+ struct otp_info *buf, size_t *retlen);
+ int (*lock)(struct spinand_device *spinand, loff_t from, size_t len);
+ int (*erase)(struct spinand_device *spinand, loff_t from, size_t len);
+ int (*read)(struct spinand_device *spinand, loff_t from, size_t len,
+ size_t *retlen, u8 *buf);
+ int (*write)(struct spinand_device *spinand, loff_t from, size_t len,
+ size_t *retlen, const u8 *buf);
+};
+
+/**
+ * struct spinand_fact_otp - SPI NAND OTP grouping structure for factory area
+ * @layout: OTP region layout
+ * @ops: OTP access ops
+ */
+struct spinand_fact_otp {
+ const struct spinand_otp_layout layout;
+ const struct spinand_fact_otp_ops *ops;
+};
+
+/**
+ * struct spinand_user_otp - SPI NAND OTP grouping structure for user area
+ * @layout: OTP region layout
+ * @ops: OTP access ops
+ */
+struct spinand_user_otp {
+ const struct spinand_otp_layout layout;
+ const struct spinand_user_otp_ops *ops;
+};
+
+
+/**
* struct spinand_info - Structure used to describe SPI NAND chips
* @model: model name
* @devid: device ID
@@ -337,6 +399,8 @@ struct spinand_ecc_info {
* @select_target: function used to select a target/die. Required only for
* multi-die chips
* @set_cont_read: enable/disable continuous cached reads
+ * @fact_otp: SPI NAND factory OTP info.
+ * @user_otp: SPI NAND user OTP info.
* @read_retries: the number of read retry modes supported
* @set_read_retry: enable/disable read retry for data recovery
*
@@ -359,6 +423,8 @@ struct spinand_info {
unsigned int target);
int (*set_cont_read)(struct spinand_device *spinand,
bool enable);
+ struct spinand_fact_otp fact_otp;
+ struct spinand_user_otp user_otp;
unsigned int read_retries;
int (*set_read_retry)(struct spinand_device *spinand,
unsigned int read_retry);
@@ -390,6 +456,24 @@ struct spinand_info {
#define SPINAND_CONT_READ(__set_cont_read) \
.set_cont_read = __set_cont_read,
+#define SPINAND_FACT_OTP_INFO(__npages, __start_page, __ops) \
+ .fact_otp = { \
+ .layout = { \
+ .npages = __npages, \
+ .start_page = __start_page, \
+ }, \
+ .ops = __ops, \
+ }
+
+#define SPINAND_USER_OTP_INFO(__npages, __start_page, __ops) \
+ .user_otp = { \
+ .layout = { \
+ .npages = __npages, \
+ .start_page = __start_page, \
+ }, \
+ .ops = __ops, \
+ }
+
#define SPINAND_READ_RETRY(__read_retries, __set_read_retry) \
.read_retries = __read_retries, \
.set_read_retry = __set_read_retry
@@ -444,6 +528,8 @@ struct spinand_dirmap {
* actually relevant to enable this feature.
* @set_cont_read: Enable/disable the continuous read feature
* @priv: manufacturer private data
+ * @fact_otp: SPI NAND factory OTP info.
+ * @user_otp: SPI NAND user OTP info.
* @read_retries: the number of read retry modes supported
* @set_read_retry: Enable/disable the read retry feature
* @last_wait_status: status of the last wait operation that will be used in case
@@ -487,6 +573,9 @@ struct spinand_device {
int (*set_cont_read)(struct spinand_device *spinand,
bool enable);
+ const struct spinand_fact_otp *fact_otp;
+ const struct spinand_user_otp *user_otp;
+
unsigned int read_retries;
int (*set_read_retry)(struct spinand_device *spinand,
unsigned int retry_mode);
@@ -571,6 +660,29 @@ int spinand_match_and_init(struct spinand_device *spinand,
enum spinand_readid_method rdid_method);
int spinand_upd_cfg(struct spinand_device *spinand, u8 mask, u8 val);
+int spinand_write_reg_op(struct spinand_device *spinand, u8 reg, u8 val);
int spinand_select_target(struct spinand_device *spinand, unsigned int target);
+int spinand_wait(struct spinand_device *spinand, unsigned long initial_delay_us,
+ unsigned long poll_delay_us, u8 *s);
+
+int spinand_read_page(struct spinand_device *spinand,
+ const struct nand_page_io_req *req);
+
+int spinand_write_page(struct spinand_device *spinand,
+ const struct nand_page_io_req *req);
+
+size_t spinand_otp_page_size(struct spinand_device *spinand);
+size_t spinand_fact_otp_size(struct spinand_device *spinand);
+size_t spinand_user_otp_size(struct spinand_device *spinand);
+
+int spinand_fact_otp_read(struct spinand_device *spinand, loff_t ofs,
+ size_t len, size_t *retlen, u8 *buf);
+int spinand_user_otp_read(struct spinand_device *spinand, loff_t ofs,
+ size_t len, size_t *retlen, u8 *buf);
+int spinand_user_otp_write(struct spinand_device *spinand, loff_t ofs,
+ size_t len, size_t *retlen, const u8 *buf);
+
+int spinand_set_mtd_otp_ops(struct spinand_device *spinand);
+
#endif /* __LINUX_MTD_SPINAND_H */