From nobody Tue Feb 10 00:06:40 2026 Received: from mx1.sberdevices.ru (mx2.sberdevices.ru [45.89.224.132]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0CC641D4342 for ; Thu, 26 Dec 2024 13:56:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.89.224.132 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1735221406; cv=none; b=RIzV2nDlVt6ID4LKQP2IBZT7Or73fIg3v1tiPo0v6/0JBhQE/WKH4trU7XNntGfAxKJs9ApKheq0NVd+nqTZPksNOMPWJhy6hcDNLWGlc6eubYz6/nMuOCPTjhLrDRajK/JwUD0G+8KqftyjGqKMyp5GmwQL936sbXEZTMrrbFI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1735221406; c=relaxed/simple; bh=93D6Cwdp0F9nLXijL6xphfwHJ2MA7OM1Rk2ORe33gO8=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=fbaNb0oBSF2SSkrYkv3QM+iqyL6lnuxmwspKoJMzxcoqSTV+wmIAXvvS3n9MjJr6FIo28csWrfDq3kHa9GytrsT6N3ocCe/mH8NTt5oQ+oTYdN9VcgpIJNV91/YsPHNqXaJfHnVwzst6M94xduDn/Jg/9+jvCdYSot3Vrg3kuQo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=salutedevices.com; spf=pass smtp.mailfrom=salutedevices.com; dkim=pass (2048-bit key) header.d=salutedevices.com header.i=@salutedevices.com header.b=XkBz0dy0; arc=none smtp.client-ip=45.89.224.132 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=salutedevices.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=salutedevices.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=salutedevices.com header.i=@salutedevices.com header.b="XkBz0dy0" Received: from p-infra-ksmg-sc-msk02.sberdevices.ru (localhost [127.0.0.1]) by mx1.sberdevices.ru (Postfix) with ESMTP id 4BD1A120006; Thu, 26 Dec 2024 16:56:36 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.sberdevices.ru 4BD1A120006 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=salutedevices.com; s=mail; t=1735221396; bh=tGrh4z/YYA5o4qVgoCNj8+PFLw1yEb7QctfkwdM0E+I=; h=From:To:Subject:Date:Message-ID:MIME-Version:Content-Type:From; b=XkBz0dy0+5aFrOSSRLjGiIcc0o7KT+zl9ZoJ2fjjTdLfcyaaiSyUk2LaQWE5QaZIR X2tkScvS+YuIjyx7flyxcwxdJQSEwinx6L+TuMD9sn5KencyjnO3C0cEB9oCXwODOD fWhgmHApVnQpxLHBOZWPrmFYaUF42itx17GWwmVbfRTdrNiwkOVX8w4rcVThnTRPYm QohEuP/FCynUHzchQQJarN/L1vA358gZ+W+Cuia7ZewrSFMkwdMcvy3OdxbfQdnaUw S9p/dv4HtHExH/80O6Z4dtxPlzNDNgL0vW1fwobar922PIPc+hbcrm/+o1dWtDxWnW G/Q6OB0OKZobQ== Received: from smtp.sberdevices.ru (p-i-exch-sc-m01.sberdevices.ru [172.16.192.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.sberdevices.ru (Postfix) with ESMTPS; Thu, 26 Dec 2024 16:56:36 +0300 (MSK) From: Martin Kurbanov To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Ezra Buehler , Alexey Romanov , Frieder Schrempf CC: , , , Martin Kurbanov Subject: [PATCH v3 1/7] mtd: spinand: make spinand_{read,write}_page global Date: Thu, 26 Dec 2024 16:55:46 +0300 Message-ID: <20241226135623.43098-2-mmkurbanov@salutedevices.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241226135623.43098-1-mmkurbanov@salutedevices.com> References: <20241226135623.43098-1-mmkurbanov@salutedevices.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: p-i-exch-a-m2.sberdevices.ru (172.24.196.120) To p-i-exch-sc-m01.sberdevices.ru (172.16.192.107) X-KSMG-Rule-ID: 10 X-KSMG-Message-Action: clean X-KSMG-AntiSpam-Lua-Profiles: 190075 [Dec 26 2024] X-KSMG-AntiSpam-Version: 6.1.1.7 X-KSMG-AntiSpam-Envelope-From: mmkurbanov@salutedevices.com X-KSMG-AntiSpam-Rate: 0 X-KSMG-AntiSpam-Status: not_detected X-KSMG-AntiSpam-Method: none X-KSMG-AntiSpam-Auth: dkim=none X-KSMG-AntiSpam-Info: LuaCore: 49 0.3.49 28b3b64a43732373258a371bd1554adb2caa23cb, {Tracking_from_domain_doesnt_match_to}, 127.0.0.199:7.1.2;smtp.sberdevices.ru:7.1.1,5.0.1;salutedevices.com:7.1.1;d41d8cd98f00b204e9800998ecf8427e.com:7.1.1, FromAlignment: s X-MS-Exchange-Organization-SCL: -1 X-KSMG-AntiSpam-Interceptor-Info: scan successful X-KSMG-AntiPhishing: Clean X-KSMG-LinksScanning: Clean X-KSMG-AntiVirus: Kaspersky Secure Mail Gateway, version 2.0.1.6960, bases: 2024/12/26 12:50:00 #26919000 X-KSMG-AntiVirus-Status: Clean, skipped Content-Type: text/plain; charset="utf-8" Change these functions from static to global so that to use them later in OTP operations. Since reading OTP pages is no different from reading pages from the main area. Signed-off-by: Martin Kurbanov --- drivers/mtd/nand/spi/core.c | 24 ++++++++++++++++++++---- include/linux/mtd/spinand.h | 6 ++++++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c index e0b6715e5dfed..4b394eace2d09 100644 --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c @@ -566,8 +566,16 @@ static int spinand_lock_block(struct spinand_device *s= pinand, u8 lock) return spinand_write_reg_op(spinand, REG_BLOCK_LOCK, lock); } =20 -static int spinand_read_page(struct spinand_device *spinand, - const struct nand_page_io_req *req) +/** + * spinand_read_page() - Read a page + * @spinand: the spinand device + * @req: the I/O request + * + * Return: 0 or a positive number of bitflips corrected on success. + * A negative error code otherwise. + */ +int spinand_read_page(struct spinand_device *spinand, + const struct nand_page_io_req *req) { struct nand_device *nand =3D spinand_to_nand(spinand); u8 status; @@ -597,8 +605,16 @@ static int spinand_read_page(struct spinand_device *sp= inand, return nand_ecc_finish_io_req(nand, (struct nand_page_io_req *)req); } =20 -static int spinand_write_page(struct spinand_device *spinand, - const struct nand_page_io_req *req) +/** + * spinand_write_page() - Write a page + * @spinand: the spinand device + * @req: the I/O request + * + * Return: 0 or a positive number of bitflips corrected on success. + * A negative error code otherwise. + */ +int spinand_write_page(struct spinand_device *spinand, + const struct nand_page_io_req *req) { struct nand_device *nand =3D spinand_to_nand(spinand); u8 status; diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h index 5c19ead604996..555846517faf6 100644 --- a/include/linux/mtd/spinand.h +++ b/include/linux/mtd/spinand.h @@ -519,4 +519,10 @@ int spinand_match_and_init(struct spinand_device *spin= and, int spinand_upd_cfg(struct spinand_device *spinand, u8 mask, u8 val); int spinand_select_target(struct spinand_device *spinand, unsigned int tar= get); =20 +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); + #endif /* __LINUX_MTD_SPINAND_H */ --=20 2.43.0 From nobody Tue Feb 10 00:06:40 2026 Received: from mx1.sberdevices.ru (mx1.sberdevices.ru [37.18.73.165]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 32FD218E1F for ; Thu, 26 Dec 2024 13:56:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=37.18.73.165 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1735221402; cv=none; b=Rs/2R+1PyGOD4vaIqNessi6ESrLW99xhQGR0eIjatAkKuF3cS0b6SzMQ02tVpFsYToIAC+pMNgOPAQEGpkzuUxHuOSiSRMX+qncfDCngKQy1v83KHXxUcZbCg7ofl3AwPplB7Ywqt0AHwt2Ed0kU7Akr+cEqwSybcmOEN/XFgQs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1735221402; c=relaxed/simple; bh=f/tWfd9CXRWui+Y1AWJ2r5iPNuDui46eWwN/UbpxGjI=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=TtVro0deFOvX4DjsUEJZXWfMZPRMLEaHmM7Uz2gpVxKjApSrgAVj/sxbfLrYlXoodsBKA2bW7Fs7VsutTsOGNvddB4cSd6y48w/wddSVCGIctsRWsZpzGUtTnYKJBXEaicrt6UkU+UHqKqW4BaGIcYXAoAftHe1l61GUqrRQxvI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=salutedevices.com; spf=pass smtp.mailfrom=salutedevices.com; dkim=pass (2048-bit key) header.d=salutedevices.com header.i=@salutedevices.com header.b=nnltGPHa; arc=none smtp.client-ip=37.18.73.165 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=salutedevices.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=salutedevices.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=salutedevices.com header.i=@salutedevices.com header.b="nnltGPHa" Received: from p-infra-ksmg-sc-msk01.sberdevices.ru (localhost [127.0.0.1]) by mx1.sberdevices.ru (Postfix) with ESMTP id 8CEDD100008; Thu, 26 Dec 2024 16:56:36 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.sberdevices.ru 8CEDD100008 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=salutedevices.com; s=mail; t=1735221396; bh=XTST6i6yTc9vLtzNPts6dg52V/B9tBq1q3P3PLwGUxU=; h=From:To:Subject:Date:Message-ID:MIME-Version:Content-Type:From; b=nnltGPHa9D8raZL8j65dUOeS04QyGw9PZvfRIGIc/eCmRlx3r+58MQfFF5s5v0+RY ikL8iQhfgA9gqsPkc9WOQ9Ede5+7sOp0+LkcdTRn2tJJ2bagPCW784ie11qc6pEZ4v YWiCIr04djYV1jg1La4THwe0zXRNev+I46k3UqhMHDlW0WUAehzPHD8Q4SWzqWbLd6 MHgz1PTwo0a+LqqPTe7cYb51IwEiZ3Vik9+n81rL0NDGYW9X/3RC670vyxSFzJedJQ tFuNXV7r1m7LZB869a+KP+C6934/J8C3pLEeBGyivKUBpn7hYMiKOkFbeMouPaAIWD 9G8oPxRzh12Cw== Received: from smtp.sberdevices.ru (p-i-exch-sc-m01.sberdevices.ru [172.16.192.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.sberdevices.ru (Postfix) with ESMTPS; Thu, 26 Dec 2024 16:56:36 +0300 (MSK) From: Martin Kurbanov To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Ezra Buehler , Alexey Romanov , Frieder Schrempf CC: , , , Martin Kurbanov Subject: [PATCH v3 2/7] mtd: spinand: add OTP support Date: Thu, 26 Dec 2024 16:55:47 +0300 Message-ID: <20241226135623.43098-3-mmkurbanov@salutedevices.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241226135623.43098-1-mmkurbanov@salutedevices.com> References: <20241226135623.43098-1-mmkurbanov@salutedevices.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: p-i-exch-a-m2.sberdevices.ru (172.24.196.120) To p-i-exch-sc-m01.sberdevices.ru (172.16.192.107) X-KSMG-Rule-ID: 10 X-KSMG-Message-Action: clean X-KSMG-AntiSpam-Lua-Profiles: 190075 [Dec 26 2024] X-KSMG-AntiSpam-Version: 6.1.1.7 X-KSMG-AntiSpam-Envelope-From: mmkurbanov@salutedevices.com X-KSMG-AntiSpam-Rate: 0 X-KSMG-AntiSpam-Status: not_detected X-KSMG-AntiSpam-Method: none X-KSMG-AntiSpam-Auth: dkim=none X-KSMG-AntiSpam-Info: LuaCore: 49 0.3.49 28b3b64a43732373258a371bd1554adb2caa23cb, {Tracking_from_domain_doesnt_match_to}, smtp.sberdevices.ru:5.0.1,7.1.1;127.0.0.199:7.1.2;salutedevices.com:7.1.1;d41d8cd98f00b204e9800998ecf8427e.com:7.1.1, FromAlignment: s X-MS-Exchange-Organization-SCL: -1 X-KSMG-AntiSpam-Interceptor-Info: scan successful X-KSMG-AntiPhishing: Clean X-KSMG-LinksScanning: Clean X-KSMG-AntiVirus: Kaspersky Secure Mail Gateway, version 2.0.1.6960, bases: 2024/12/26 12:50:00 #26919000 X-KSMG-AntiVirus-Status: Clean, skipped Content-Type: text/plain; charset="utf-8" The MTD subsystem already supports accessing two OTP areas: user and factory. User areas can be written by the user. This patch only adds support for the user areas. In this patch the OTP_INFO macro is provided to add parameters to spinand_info. To implement OTP operations, the client (flash driver) is provided with 5 callbacks: .read(), .write(), .info(), .lock(), .erase(). Signed-off-by: Martin Kurbanov --- drivers/mtd/nand/spi/Makefile | 3 +- drivers/mtd/nand/spi/core.c | 7 ++ drivers/mtd/nand/spi/otp.c | 169 ++++++++++++++++++++++++++++++++++ include/linux/mtd/spinand.h | 52 +++++++++++ 4 files changed, 230 insertions(+), 1 deletion(-) create mode 100644 drivers/mtd/nand/spi/otp.c diff --git a/drivers/mtd/nand/spi/Makefile b/drivers/mtd/nand/spi/Makefile index 19cc77288ebbc..60d2e830ffc6b 100644 --- a/drivers/mtd/nand/spi/Makefile +++ b/drivers/mtd/nand/spi/Makefile @@ -1,4 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 -spinand-objs :=3D core.o alliancememory.o ato.o esmt.o foresee.o gigadevic= e.o macronix.o +spinand-objs :=3D core.o otp.o +spinand-objs +=3D alliancememory.o ato.o esmt.o foresee.o gigadevice.o mac= ronix.o spinand-objs +=3D micron.o paragon.o toshiba.o winbond.o xtx.o obj-$(CONFIG_MTD_SPI_NAND) +=3D spinand.o diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c index 4b394eace2d09..d12f09b28e371 100644 --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c @@ -1111,6 +1111,7 @@ int spinand_match_and_init(struct spinand_device *spi= nand, spinand->flags =3D table[i].flags; spinand->id.len =3D 1 + table[i].devid.len; spinand->select_target =3D table[i].select_target; + spinand->otp =3D &table[i].otp; =20 op =3D spinand_select_op_variant(spinand, info->op_variants.read_cache); @@ -1292,6 +1293,12 @@ static int spinand_init(struct spinand_device *spina= nd) mtd->_max_bad_blocks =3D nanddev_mtd_max_bad_blocks; mtd->_resume =3D spinand_mtd_resume; =20 + if (spinand_otp_size(spinand)) { + ret =3D spinand_set_mtd_otp_ops(spinand); + if (ret) + goto err_cleanup_ecc_engine; + } + if (nand->ecc.engine) { ret =3D mtd_ooblayout_count_freebytes(mtd); if (ret < 0) diff --git a/drivers/mtd/nand/spi/otp.c b/drivers/mtd/nand/spi/otp.c new file mode 100644 index 0000000000000..3650ff336db14 --- /dev/null +++ b/drivers/mtd/nand/spi/otp.c @@ -0,0 +1,169 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2024, SaluteDevices. All Rights Reserved. + * + * Author: Martin Kurbanov + */ + +#include +#include + +/** + * spinand_otp_size() - Get SPI-NAND OTP area size + * @spinand: the spinand device + * + * Return: the OTP size. + */ +size_t spinand_otp_size(struct spinand_device *spinand) +{ + struct nand_device *nand =3D spinand_to_nand(spinand); + size_t otp_pagesize =3D nanddev_page_size(nand) + + nanddev_per_page_oobsize(nand); + + return spinand->otp->layout.npages * otp_pagesize; +} + +static int spinand_otp_check_bounds(struct spinand_device *spinand, loff_t= ofs, + size_t len) +{ + if (ofs < 0 || ofs + len > spinand_otp_size(spinand)) + return -EINVAL; + + return 0; +} + +static int spinand_mtd_otp_info(struct mtd_info *mtd, size_t len, + size_t *retlen, struct otp_info *buf) +{ + struct spinand_device *spinand =3D mtd_to_spinand(mtd); + const struct spinand_otp_ops *ops =3D spinand->otp->ops; + int ret; + + *retlen =3D 0; + + mutex_lock(&spinand->lock); + ret =3D ops->info(spinand, len, buf, retlen); + mutex_unlock(&spinand->lock); + + return ret; +} + +static int spinand_mtd_otp_read(struct mtd_info *mtd, loff_t ofs, size_t l= en, + size_t *retlen, u8 *buf) +{ + struct spinand_device *spinand =3D mtd_to_spinand(mtd); + const struct spinand_otp_ops *ops =3D spinand->otp->ops; + int ret; + + *retlen =3D 0; + + if (!len) + return 0; + + ret =3D spinand_otp_check_bounds(spinand, ofs, len); + if (ret) + return ret; + + mutex_lock(&spinand->lock); + ret =3D ops->read(spinand, ofs, len, retlen, buf); + mutex_unlock(&spinand->lock); + + return ret; +} + +static int spinand_mtd_otp_write(struct mtd_info *mtd, loff_t ofs, size_t = len, + size_t *retlen, const u8 *buf) +{ + struct spinand_device *spinand =3D mtd_to_spinand(mtd); + const struct spinand_otp_ops *ops =3D spinand->otp->ops; + int ret; + + *retlen =3D 0; + + if (!len) + return 0; + + ret =3D spinand_otp_check_bounds(spinand, ofs, len); + if (ret) + return ret; + + mutex_lock(&spinand->lock); + ret =3D ops->write(spinand, ofs, len, retlen, buf); + mutex_unlock(&spinand->lock); + + return ret; +} + +static int spinand_mtd_otp_erase(struct mtd_info *mtd, loff_t ofs, size_t = len) +{ + struct spinand_device *spinand =3D mtd_to_spinand(mtd); + const struct spinand_otp_ops *ops =3D spinand->otp->ops; + int ret; + + if (!len) + return 0; + + ret =3D spinand_otp_check_bounds(spinand, ofs, len); + if (ret) + return ret; + + mutex_lock(&spinand->lock); + ret =3D ops->erase(spinand, ofs, len); + mutex_unlock(&spinand->lock); + + return ret; +} + +static int spinand_mtd_otp_lock(struct mtd_info *mtd, loff_t ofs, size_t l= en) +{ + struct spinand_device *spinand =3D mtd_to_spinand(mtd); + const struct spinand_otp_ops *ops =3D spinand->otp->ops; + int ret; + + if (!len) + return 0; + + ret =3D spinand_otp_check_bounds(spinand, ofs, len); + if (ret) + return ret; + + mutex_lock(&spinand->lock); + ret =3D ops->lock(spinand, ofs, len); + mutex_unlock(&spinand->lock); + + return ret; +} + +/** + * spinand_set_mtd_otp_ops() - Setup OTP methods + * @spinand: the spinand device + * + * Setup OTP methods. + * + * Return: 0 on success, a negative error code otherwise. + */ +int spinand_set_mtd_otp_ops(struct spinand_device *spinand) +{ + struct mtd_info *mtd =3D spinand_to_mtd(spinand); + const struct spinand_otp_ops *ops =3D spinand->otp->ops; + + if (!ops) + return -EINVAL; + + if (ops->info) + mtd->_get_user_prot_info =3D spinand_mtd_otp_info; + + if (ops->read) + mtd->_read_user_prot_reg =3D spinand_mtd_otp_read; + + if (ops->write) + mtd->_write_user_prot_reg =3D spinand_mtd_otp_write; + + if (ops->lock) + mtd->_lock_user_prot_reg =3D spinand_mtd_otp_lock; + + if (ops->erase) + mtd->_erase_user_prot_reg =3D spinand_mtd_otp_erase; + + return 0; +} diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h index 555846517faf6..a9ad286de2902 100644 --- a/include/linux/mtd/spinand.h +++ b/include/linux/mtd/spinand.h @@ -322,6 +322,43 @@ struct spinand_ondie_ecc_conf { u8 status; }; =20 +/** + * struct spinand_otp_layout - structure to describe the SPI NAND OTP area + * @npages: number of pages in the OTP + */ +struct spinand_otp_layout { + unsigned int npages; +}; + +/** + * struct spinand_otp_ops - SPI NAND OTP methods + * @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_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_otp - SPI NAND OTP grouping structure + * @layout: OTP region layout + * @ops: OTP access ops + */ +struct spinand_otp { + const struct spinand_otp_layout layout; + const struct spinand_otp_ops *ops; +}; + /** * struct spinand_info - Structure used to describe SPI NAND chips * @model: model name @@ -354,6 +391,7 @@ struct spinand_info { } op_variants; int (*select_target)(struct spinand_device *spinand, unsigned int target); + struct spinand_otp otp; }; =20 #define SPINAND_ID(__method, ...) \ @@ -379,6 +417,14 @@ struct spinand_info { #define SPINAND_SELECT_TARGET(__func) \ .select_target =3D __func, =20 +#define SPINAND_OTP_INFO(__npages, __ops) \ + .otp =3D { \ + .layout =3D { \ + .npages =3D __npages, \ + }, \ + .ops =3D __ops, \ + } + #define SPINAND_INFO(__model, __id, __memorg, __eccreq, __op_variants, \ __flags, ...) \ { \ @@ -422,6 +468,7 @@ struct spinand_dirmap { * passed in spi_mem_op be DMA-able, so we can't based the bufs on * the stack * @manufacturer: SPI NAND manufacturer information + * @otp: SPI NAND OTP info. * @priv: manufacturer private data */ struct spinand_device { @@ -450,6 +497,7 @@ struct spinand_device { u8 *oobbuf; u8 *scratchbuf; const struct spinand_manufacturer *manufacturer; + const struct spinand_otp *otp; void *priv; }; =20 @@ -525,4 +573,8 @@ int spinand_read_page(struct spinand_device *spinand, int spinand_write_page(struct spinand_device *spinand, const struct nand_page_io_req *req); =20 +size_t spinand_otp_size(struct spinand_device *spinand); + +int spinand_set_mtd_otp_ops(struct spinand_device *spinand); + #endif /* __LINUX_MTD_SPINAND_H */ --=20 2.43.0 From nobody Tue Feb 10 00:06:40 2026 Received: from mx1.sberdevices.ru (mx2.sberdevices.ru [45.89.224.132]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 693311D63D9 for ; Thu, 26 Dec 2024 13:56:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.89.224.132 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1735221407; cv=none; b=ihGSvWvyAjzm/Sb+0SwaMY2CtlNWhLuNBXcIkJQUcnj791cDrobgPq2E+7fikhxQ1GLH04mLe7ODIXuI3oKjGIMwmSo1WCKerrpJIB0OgXSsMrxibPIh/wM/IRnNdD2zIwsuwAcLaO0Gv//HXgvQYWgj1nvIo9RYOyiTsTcO4iE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1735221407; c=relaxed/simple; bh=26Pd9g8JxMkKYdFbgxF2UgIr/iHXLcQRYd3mm/50+c0=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=arxtN4ufrf0Pp0Rp+RmAn3/7PqFBG0xlwLiG0INEhtZJqYQSoXeaIpRsmQvy4R1fQhQKWJDEigWcRhBgaIpbT3CWKNKaUBvopOQKKI42VLriO160cfRs32q8141EAkPdOJb2c3emhpAhwzS4jr9GakO9GOVK5Hfk8JbnIGCrnQI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=salutedevices.com; spf=pass smtp.mailfrom=salutedevices.com; dkim=pass (2048-bit key) header.d=salutedevices.com header.i=@salutedevices.com header.b=EfbFAeFa; arc=none smtp.client-ip=45.89.224.132 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=salutedevices.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=salutedevices.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=salutedevices.com header.i=@salutedevices.com header.b="EfbFAeFa" Received: from p-infra-ksmg-sc-msk02.sberdevices.ru (localhost [127.0.0.1]) by mx1.sberdevices.ru (Postfix) with ESMTP id D55BD12000D; Thu, 26 Dec 2024 16:56:36 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.sberdevices.ru D55BD12000D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=salutedevices.com; s=mail; t=1735221396; bh=EC+AhQnFBqRN/0Suzazs1APZmE2vEqAK2nZQiqZ2ZrU=; h=From:To:Subject:Date:Message-ID:MIME-Version:Content-Type:From; b=EfbFAeFasUhVG7SRIGJ7x8/3D0CO3+jzyVYVjtZdbJqRrXCy7W3ckAbO8jZJJi+D8 MslnO/1WtmN2Zw072Al1OQDWQq2RYdOBqsiZcTRRz3dUFRqzoWCRNhshTrlhRFLNhP 73hFc3g2i8wtxqiXpBb+2uKb/CraVdSbnz0C3vB6AWQTzjDOTXSjmOWMj0DYCflOpt sm7TPhTggdiu3RgXNXU9Ssw359U0UVoFyz5YdjB9oS9TDvj3uM513v2z6S9ADs85p3 C2Pby4IqXy8adSNWhS0t6XwjNgZurKutpRY6FcPfFCz2Bd1fdYNq6fER5d+q7MkaZg gDa3Q3pWXIMiA== Received: from smtp.sberdevices.ru (p-i-exch-sc-m01.sberdevices.ru [172.16.192.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.sberdevices.ru (Postfix) with ESMTPS; Thu, 26 Dec 2024 16:56:36 +0300 (MSK) From: Martin Kurbanov To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Ezra Buehler , Alexey Romanov , Frieder Schrempf CC: , , , Martin Kurbanov Subject: [PATCH v3 3/7] mtd: spinand: make spinand_{wait,otp_page_size} global Date: Thu, 26 Dec 2024 16:55:48 +0300 Message-ID: <20241226135623.43098-4-mmkurbanov@salutedevices.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241226135623.43098-1-mmkurbanov@salutedevices.com> References: <20241226135623.43098-1-mmkurbanov@salutedevices.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: p-i-exch-a-m2.sberdevices.ru (172.24.196.120) To p-i-exch-sc-m01.sberdevices.ru (172.16.192.107) X-KSMG-Rule-ID: 10 X-KSMG-Message-Action: clean X-KSMG-AntiSpam-Lua-Profiles: 190075 [Dec 26 2024] X-KSMG-AntiSpam-Version: 6.1.1.7 X-KSMG-AntiSpam-Envelope-From: mmkurbanov@salutedevices.com X-KSMG-AntiSpam-Rate: 0 X-KSMG-AntiSpam-Status: not_detected X-KSMG-AntiSpam-Method: none X-KSMG-AntiSpam-Auth: dkim=none X-KSMG-AntiSpam-Info: LuaCore: 49 0.3.49 28b3b64a43732373258a371bd1554adb2caa23cb, {Tracking_from_domain_doesnt_match_to}, 127.0.0.199:7.1.2;smtp.sberdevices.ru:7.1.1,5.0.1;salutedevices.com:7.1.1;d41d8cd98f00b204e9800998ecf8427e.com:7.1.1, FromAlignment: s X-MS-Exchange-Organization-SCL: -1 X-KSMG-AntiSpam-Interceptor-Info: scan successful X-KSMG-AntiPhishing: Clean X-KSMG-LinksScanning: Clean X-KSMG-AntiVirus: Kaspersky Secure Mail Gateway, version 2.0.1.6960, bases: 2024/12/26 12:50:00 #26919000 X-KSMG-AntiVirus-Status: Clean, skipped Content-Type: text/plain; charset="utf-8" Change the functions spinand_wait() and spinand_otp_page_size() from static to global so that SPI NAND flash drivers don't duplicate it. Signed-off-by: Martin Kurbanov --- drivers/mtd/nand/spi/core.c | 18 ++++++++++++++---- drivers/mtd/nand/spi/otp.c | 19 ++++++++++++++----- include/linux/mtd/spinand.h | 4 ++++ 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c index d12f09b28e371..018d6b6c61d10 100644 --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c @@ -496,10 +496,20 @@ static int spinand_erase_op(struct spinand_device *sp= inand, return spi_mem_exec_op(spinand->spimem, &op); } =20 -static int spinand_wait(struct spinand_device *spinand, - unsigned long initial_delay_us, - unsigned long poll_delay_us, - u8 *s) +/** + * spinand_wait() - Poll memory device status + * @spinand: the spinand device + * @initial_delay_us: delay in us before starting to poll + * @poll_delay_us: time to sleep between reads in us + * @s: the pointer to variable to store the value of REG_STATUS + * + * This function polls a status register (REG_STATUS) and returns when + * the STATUS_READY bit is 0 or when the timeout has expired. + * + * Return: 0 on success, a negative error code otherwise. + */ +int spinand_wait(struct spinand_device *spinand, unsigned long initial_del= ay_us, + unsigned long poll_delay_us, u8 *s) { struct spi_mem_op op =3D SPINAND_GET_FEATURE_OP(REG_STATUS, spinand->scratchbuf); diff --git a/drivers/mtd/nand/spi/otp.c b/drivers/mtd/nand/spi/otp.c index 3650ff336db14..a50d6af818613 100644 --- a/drivers/mtd/nand/spi/otp.c +++ b/drivers/mtd/nand/spi/otp.c @@ -8,6 +8,19 @@ #include #include =20 +/** + * spinand_otp_page_size() - Get SPI-NAND OTP page size + * @spinand: the spinand device + * + * Return: the OTP page size. + */ +size_t spinand_otp_page_size(struct spinand_device *spinand) +{ + struct nand_device *nand =3D spinand_to_nand(spinand); + + return nanddev_page_size(nand) + nanddev_per_page_oobsize(nand); +} + /** * spinand_otp_size() - Get SPI-NAND OTP area size * @spinand: the spinand device @@ -16,11 +29,7 @@ */ size_t spinand_otp_size(struct spinand_device *spinand) { - struct nand_device *nand =3D spinand_to_nand(spinand); - size_t otp_pagesize =3D nanddev_page_size(nand) + - nanddev_per_page_oobsize(nand); - - return spinand->otp->layout.npages * otp_pagesize; + return spinand->otp->layout.npages * spinand_otp_page_size(spinand); } =20 static int spinand_otp_check_bounds(struct spinand_device *spinand, loff_t= ofs, diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h index a9ad286de2902..19d76057c0444 100644 --- a/include/linux/mtd/spinand.h +++ b/include/linux/mtd/spinand.h @@ -567,12 +567,16 @@ int spinand_match_and_init(struct spinand_device *spi= nand, int spinand_upd_cfg(struct spinand_device *spinand, u8 mask, u8 val); int spinand_select_target(struct spinand_device *spinand, unsigned int tar= get); =20 +int spinand_wait(struct spinand_device *spinand, unsigned long initial_del= ay_us, + unsigned long poll_delay_us, u8 *s); + int spinand_read_page(struct spinand_device *spinand, const struct nand_page_io_req *req); =20 int spinand_write_page(struct spinand_device *spinand, const struct nand_page_io_req *req); =20 +size_t spinand_otp_page_size(struct spinand_device *spinand); size_t spinand_otp_size(struct spinand_device *spinand); =20 int spinand_set_mtd_otp_ops(struct spinand_device *spinand); --=20 2.43.0 From nobody Tue Feb 10 00:06:40 2026 Received: from mx1.sberdevices.ru (mx1.sberdevices.ru [37.18.73.165]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5D42D185E53 for ; Thu, 26 Dec 2024 13:56:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=37.18.73.165 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1735221402; cv=none; b=F47mvOC9nUyW2MtIBxK10CPtWxUJG2HCQMHifB4aBN3X2Ihr/Qhdg2aFsrnZBI+8vv1Oob3htoSq+D/MwJC8DenA0se33IbJdBXPmNE5QslSZaE7JqOhBBZqGpzN9R1qksxdLNeYlnoFAdZmJqNnQ2a2DVdrtCwYmq9yTqrnwAA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1735221402; c=relaxed/simple; bh=XKjaz6vAorsG5tRlJPMGt5nH/dPFs/cWvt49q4c9Y2c=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Bwfwqcqne8L9+jpXSKlJJ29TWJnX+syLg+GtMhcQhOGQMBYE5y+EbZ+CqJnvd6h+IUV0G0LBxaN5qxjjx+FVQERdCDBGFxwLod19EFr4XU/TvEYBRlvD1TjYO1vBi2b5VUjYlI8YztyQNloRyaxQV6D/t65pPKok4tZ9haPHOwk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=salutedevices.com; spf=pass smtp.mailfrom=salutedevices.com; dkim=pass (2048-bit key) header.d=salutedevices.com header.i=@salutedevices.com header.b=s2cW43T4; arc=none smtp.client-ip=37.18.73.165 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=salutedevices.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=salutedevices.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=salutedevices.com header.i=@salutedevices.com header.b="s2cW43T4" Received: from p-infra-ksmg-sc-msk01.sberdevices.ru (localhost [127.0.0.1]) by mx1.sberdevices.ru (Postfix) with ESMTP id 27ADF100009; Thu, 26 Dec 2024 16:56:37 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.sberdevices.ru 27ADF100009 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=salutedevices.com; s=mail; t=1735221397; bh=Nu38CUOAfNVgdmBMZ6cigO1QOgYOx2qWaYB6HSqY2G4=; h=From:To:Subject:Date:Message-ID:MIME-Version:Content-Type:From; b=s2cW43T4LSCWcZkCG/SFSI7pmTvayT2mtWSTmc1fWD9o8SoKdg8D5p1Wt0gUteawX Pu4gdZGZUP8Z20yBAW8zqduBDMCRoma8Lne8jXYz38siR/cLM0j+RCLI5iXp9zPu0S F2MFF4R39QU03P9Ze2wB0xLlujag1GN9vvJ1bK+297Q1tWFbIZ1Nl+Tl4qHeJXjuPc a4U5469lS1KNREv9lQqa66mWE3CkP4RNY2lHAw0KW/d1qFp8/grp6dN6khwt/16jOB LNWJDDYm+L7mHkTzY4bZN04b/IfW2FjoWLell4tIlTr7P0qAdejMkbH+/aR5IMHtyL Iw17bYAkYal7Q== Received: from smtp.sberdevices.ru (p-i-exch-sc-m01.sberdevices.ru [172.16.192.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.sberdevices.ru (Postfix) with ESMTPS; Thu, 26 Dec 2024 16:56:36 +0300 (MSK) From: Martin Kurbanov To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Ezra Buehler , Alexey Romanov , Frieder Schrempf CC: , , , Martin Kurbanov Subject: [PATCH v3 4/7] mtd: spinand: add start_page to otp layout Date: Thu, 26 Dec 2024 16:55:49 +0300 Message-ID: <20241226135623.43098-5-mmkurbanov@salutedevices.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241226135623.43098-1-mmkurbanov@salutedevices.com> References: <20241226135623.43098-1-mmkurbanov@salutedevices.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: p-i-exch-a-m2.sberdevices.ru (172.24.196.120) To p-i-exch-sc-m01.sberdevices.ru (172.16.192.107) X-KSMG-Rule-ID: 10 X-KSMG-Message-Action: clean X-KSMG-AntiSpam-Lua-Profiles: 190075 [Dec 26 2024] X-KSMG-AntiSpam-Version: 6.1.1.7 X-KSMG-AntiSpam-Envelope-From: mmkurbanov@salutedevices.com X-KSMG-AntiSpam-Rate: 0 X-KSMG-AntiSpam-Status: not_detected X-KSMG-AntiSpam-Method: none X-KSMG-AntiSpam-Auth: dkim=none X-KSMG-AntiSpam-Info: LuaCore: 49 0.3.49 28b3b64a43732373258a371bd1554adb2caa23cb, {Tracking_from_domain_doesnt_match_to}, smtp.sberdevices.ru:5.0.1,7.1.1;127.0.0.199:7.1.2;salutedevices.com:7.1.1;d41d8cd98f00b204e9800998ecf8427e.com:7.1.1, FromAlignment: s X-MS-Exchange-Organization-SCL: -1 X-KSMG-AntiSpam-Interceptor-Info: scan successful X-KSMG-AntiPhishing: Clean X-KSMG-LinksScanning: Clean X-KSMG-AntiVirus: Kaspersky Secure Mail Gateway, version 2.0.1.6960, bases: 2024/12/26 12:50:00 #26919000 X-KSMG-AntiVirus-Status: Clean, skipped Content-Type: text/plain; charset="utf-8" The OTP area is divided into two parts: the factory and the user. In SPI-NAND, it is usually this one OTP region: the first few pages are allocated to the factory area. Therefore, enter the start_page field, which indicates from which page the custom OTP region starts. Signed-off-by: Martin Kurbanov --- include/linux/mtd/spinand.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h index 19d76057c0444..d6dbb85094283 100644 --- a/include/linux/mtd/spinand.h +++ b/include/linux/mtd/spinand.h @@ -325,9 +325,11 @@ struct spinand_ondie_ecc_conf { /** * 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 OTP area. */ struct spinand_otp_layout { unsigned int npages; + unsigned int start_page; }; =20 /** @@ -417,10 +419,11 @@ struct spinand_info { #define SPINAND_SELECT_TARGET(__func) \ .select_target =3D __func, =20 -#define SPINAND_OTP_INFO(__npages, __ops) \ +#define SPINAND_OTP_INFO(__npages, __start_page, __ops) \ .otp =3D { \ .layout =3D { \ .npages =3D __npages, \ + .start_page =3D __start_page, \ }, \ .ops =3D __ops, \ } --=20 2.43.0 From nobody Tue Feb 10 00:06:40 2026 Received: from mx1.sberdevices.ru (mx2.sberdevices.ru [45.89.224.132]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6795A1D63D8 for ; Thu, 26 Dec 2024 13:56:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.89.224.132 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1735221407; cv=none; b=gEfW5ZEx++jaEXh5dKYl7rTrl9tvAsC0uNk0cA7/rRIN8hH7Z+NF9engX3zsUb5ciUiChOJDn88bqNpgObw9wKI66UJ9QXaqO/qqF92OilPQYPNC8uJwtf+uc073h+D8uCe7j/eNag1vbHandJ5tl3JdNKuG6gRl+g4ceeDR4Cc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1735221407; c=relaxed/simple; bh=KvRMPRqF3hhepSO5mrN4yE0cor8JL8oqAOhimGICBco=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=gNPhUOGhVxBRC52Pm/X+SbL7l1TxxtiZxq8JqJ+D+QhHPInYTVMxM61FEvZiJ9n8voGKVHw89601cusQLvlfSic8ITfuF6dd5CYUCdHCB+a+hLYvhI4xt6yj3OacPCnRTzWNe7DPX0TeFpQdon76m2sg5BdUj9aN8Mae2EI2rDk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=salutedevices.com; spf=pass smtp.mailfrom=salutedevices.com; dkim=pass (2048-bit key) header.d=salutedevices.com header.i=@salutedevices.com header.b=cjToTACr; arc=none smtp.client-ip=45.89.224.132 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=salutedevices.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=salutedevices.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=salutedevices.com header.i=@salutedevices.com header.b="cjToTACr" Received: from p-infra-ksmg-sc-msk02.sberdevices.ru (localhost [127.0.0.1]) by mx1.sberdevices.ru (Postfix) with ESMTP id 70A0612001E; Thu, 26 Dec 2024 16:56:37 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.sberdevices.ru 70A0612001E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=salutedevices.com; s=mail; t=1735221397; bh=XnP9caPq4vXDueT/dnDu27xM9UZnwpPDLHw6palnojI=; h=From:To:Subject:Date:Message-ID:MIME-Version:Content-Type:From; b=cjToTACrl35T6k8k0n3zPCJioUQlQR7V9UDFAzzV53+APR0y9oNLK/jmCWKheLeai +yCKdFskWL8YtTlbyqWctKjAN0n30sh9HEZ14tw5MAznByCjSFY+yguiDInkqC2Y+F xr1Msd4OViPmw/U8oTtUxnoUgqFYSD8Q4+BYYGZCgwb+b73Ngzr6Yj3FitYPzSOz8X xTP8MexNul/hu/6Yq6vuSvff95q4Wh8MGJ854irCPfacBiHby0zKbziiM+DhNvUCt6 nn7uD4Q9YeNxzZOSXe9CMOT3RosP6WxkW3+aT4I+FMeSlKvmgu+nc52Agx00mdcBXp oafnaU7Q6XPZA== Received: from smtp.sberdevices.ru (p-i-exch-sc-m01.sberdevices.ru [172.16.192.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.sberdevices.ru (Postfix) with ESMTPS; Thu, 26 Dec 2024 16:56:37 +0300 (MSK) From: Martin Kurbanov To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Ezra Buehler , Alexey Romanov , Frieder Schrempf CC: , , , Martin Kurbanov Subject: [PATCH v3 5/7] mtd: spinand: otp: add helpers functions Date: Thu, 26 Dec 2024 16:55:50 +0300 Message-ID: <20241226135623.43098-6-mmkurbanov@salutedevices.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241226135623.43098-1-mmkurbanov@salutedevices.com> References: <20241226135623.43098-1-mmkurbanov@salutedevices.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: p-i-exch-a-m2.sberdevices.ru (172.24.196.120) To p-i-exch-sc-m01.sberdevices.ru (172.16.192.107) X-KSMG-Rule-ID: 10 X-KSMG-Message-Action: clean X-KSMG-AntiSpam-Lua-Profiles: 190075 [Dec 26 2024] X-KSMG-AntiSpam-Version: 6.1.1.7 X-KSMG-AntiSpam-Envelope-From: mmkurbanov@salutedevices.com X-KSMG-AntiSpam-Rate: 0 X-KSMG-AntiSpam-Status: not_detected X-KSMG-AntiSpam-Method: none X-KSMG-AntiSpam-Auth: dkim=none X-KSMG-AntiSpam-Info: LuaCore: 49 0.3.49 28b3b64a43732373258a371bd1554adb2caa23cb, {Tracking_from_domain_doesnt_match_to}, 127.0.0.199:7.1.2;smtp.sberdevices.ru:7.1.1,5.0.1;salutedevices.com:7.1.1;d41d8cd98f00b204e9800998ecf8427e.com:7.1.1, FromAlignment: s X-MS-Exchange-Organization-SCL: -1 X-KSMG-AntiSpam-Interceptor-Info: scan successful X-KSMG-AntiPhishing: Clean X-KSMG-LinksScanning: Clean X-KSMG-AntiVirus: Kaspersky Secure Mail Gateway, version 2.0.1.6960, bases: 2024/12/26 12:50:00 #26919000 X-KSMG-AntiVirus-Status: Clean, skipped Content-Type: text/plain; charset="utf-8" The global functions spinand_otp_read() and spinand_otp_write() have been introduced. Since most SPI-NAND flashes read/write OTP in the same way, let's define global functions to avoid code duplication. Signed-off-by: Martin Kurbanov --- drivers/mtd/nand/spi/otp.c | 89 +++++++++++++++++++++++++++++++++++++ include/linux/mtd/spinand.h | 5 +++ 2 files changed, 94 insertions(+) diff --git a/drivers/mtd/nand/spi/otp.c b/drivers/mtd/nand/spi/otp.c index a50d6af818613..b8204bb6d848e 100644 --- a/drivers/mtd/nand/spi/otp.c +++ b/drivers/mtd/nand/spi/otp.c @@ -41,6 +41,95 @@ static int spinand_otp_check_bounds(struct spinand_devic= e *spinand, loff_t ofs, return 0; } =20 +static int spinand_otp_rw(struct spinand_device *spinand, loff_t ofs, + size_t len, size_t *retlen, u8 *buf, bool is_write) +{ + struct nand_page_io_req req =3D {}; + unsigned long long page; + size_t copied =3D 0; + size_t otp_pagesize =3D spinand_otp_page_size(spinand); + int ret; + + if (!len) + return 0; + + ret =3D spinand_otp_check_bounds(spinand, ofs, len); + if (ret) + return ret; + + ret =3D spinand_upd_cfg(spinand, CFG_OTP_ENABLE, CFG_OTP_ENABLE); + if (ret) + return ret; + + page =3D ofs; + req.dataoffs =3D do_div(page, otp_pagesize); + req.pos.page =3D page + spinand->otp->layout.start_page; + req.type =3D is_write ? NAND_PAGE_WRITE : NAND_PAGE_READ; + req.mode =3D MTD_OPS_RAW; + req.databuf.in =3D buf; + + while (copied < len) { + req.datalen =3D min_t(unsigned int, + otp_pagesize - req.dataoffs, + len - copied); + + if (is_write) + ret =3D spinand_write_page(spinand, &req); + else + ret =3D spinand_read_page(spinand, &req); + + if (ret < 0) + break; + + req.databuf.in +=3D req.datalen; + req.pos.page++; + req.dataoffs =3D 0; + copied +=3D req.datalen; + } + + *retlen =3D copied; + + if (spinand_upd_cfg(spinand, CFG_OTP_ENABLE, 0)) { + dev_warn(&spinand_to_mtd(spinand)->dev, + "Can not disable OTP mode\n"); + ret =3D -EIO; + } + + return ret; +} + +/** + * spinand_otp_read() - Read from OTP area + * @spinand: the spinand device + * @ofs: the offset to read + * @len: the number of data bytes to read + * @retlen: the pointer to variable to store the number of read bytes + * @buf: the buffer to store the read data + * + * Return: 0 on success, an error code otherwise. + */ +int spinand_otp_read(struct spinand_device *spinand, loff_t ofs, size_t le= n, + size_t *retlen, u8 *buf) +{ + return spinand_otp_rw(spinand, ofs, len, retlen, buf, false); +} + +/** + * spinand_otp_write() - Write to OTP area + * @spinand: the spinand device + * @ofs: the offset to write to + * @len: the number of bytes to write + * @retlen: the pointer to variable to store the number of written bytes + * @buf: the buffer with data to write + * + * Return: 0 on success, an error code otherwise. + */ +int spinand_otp_write(struct spinand_device *spinand, loff_t ofs, size_t l= en, + size_t *retlen, const u8 *buf) +{ + return spinand_otp_rw(spinand, ofs, len, retlen, (u8 *)buf, true); +} + static int spinand_mtd_otp_info(struct mtd_info *mtd, size_t len, size_t *retlen, struct otp_info *buf) { diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h index d6dbb85094283..dcb1811e55d25 100644 --- a/include/linux/mtd/spinand.h +++ b/include/linux/mtd/spinand.h @@ -582,6 +582,11 @@ int spinand_write_page(struct spinand_device *spinand, size_t spinand_otp_page_size(struct spinand_device *spinand); size_t spinand_otp_size(struct spinand_device *spinand); =20 +int spinand_otp_read(struct spinand_device *spinand, loff_t ofs, size_t le= n, + size_t *retlen, u8 *buf); +int spinand_otp_write(struct spinand_device *spinand, loff_t ofs, size_t l= en, + size_t *retlen, const u8 *buf); + int spinand_set_mtd_otp_ops(struct spinand_device *spinand); =20 #endif /* __LINUX_MTD_SPINAND_H */ --=20 2.43.0 From nobody Tue Feb 10 00:06:40 2026 Received: from mx1.sberdevices.ru (mx1.sberdevices.ru [37.18.73.165]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7578C1D4341 for ; Thu, 26 Dec 2024 13:56:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=37.18.73.165 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1735221405; cv=none; b=GIWZVMmdQScc0vtGPHFWWIznCsh3f59wyhLzvOruV1ep7app6Mea/+NX4oN7ktIEX6E0bKJ+67CnsJgTdSrceQoqv5RSE++q8IHbnX0m1U8hgLPlQ2gXC5NbVX6r22rkvlmYDvf12HlocUfaS73ssJfRuwnQ0f8WMC0YAwehKsY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1735221405; c=relaxed/simple; bh=8OwSSpcLuYZ1QxMKAh3Z1M9f5RDKur7/S8oEXLXe4PY=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=TIgdvQrCcVo9kWxvlvVtC0KK2uJPYkFa3MIbzAkaWxcQa+RIecZz+XBWJkyyipfdYDs59dyFq1ytDNdtKDEjEcebSsDit9mujN3R8WUVXG2m0ZepdMjphQXH0BUh+iw4FAgYcnv0NLHm4/3Q8FzdJlCFPIuhAJVBMCWHKTSAuaI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=salutedevices.com; spf=pass smtp.mailfrom=salutedevices.com; dkim=pass (2048-bit key) header.d=salutedevices.com header.i=@salutedevices.com header.b=VT9e96V4; arc=none smtp.client-ip=37.18.73.165 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=salutedevices.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=salutedevices.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=salutedevices.com header.i=@salutedevices.com header.b="VT9e96V4" Received: from p-infra-ksmg-sc-msk01.sberdevices.ru (localhost [127.0.0.1]) by mx1.sberdevices.ru (Postfix) with ESMTP id BB5C510000C; Thu, 26 Dec 2024 16:56:37 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.sberdevices.ru BB5C510000C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=salutedevices.com; s=mail; t=1735221397; bh=GjYDJBTjTKGjKkiBfobc73Px8oF5sVTYIjM4fm+PFwg=; h=From:To:Subject:Date:Message-ID:MIME-Version:Content-Type:From; b=VT9e96V4Z+2ldcKu1EMvnDcXm92nb79zZBwqITAHV6fH+KLesjyVtwmIzk9e79iOb M+Rp2NztwzJ8VkfzSt1DLUBfEigZTPMs1cgx27Fh/Bm08B/WfEfUsLYK8owPC+fnET 8KZQc+0TuM79G2e6lVZF89T4xyX/c/zO+eQkhn2u0XNz2M7hQauOFuscUrB6OLZStg /PY+YLU51h/Q4hypJLH1tQDzXWaVjYKXTXfn8cfkznzV2FenYcorXZOys5NFuGG2Ta ZHOlV/tqNKtOgK6EOU9O78bla3kxsKOnFNlBK36U/TXYpIWc71zt3FBJ8PF56mTw3B ckxJVcbhGy4DA== Received: from smtp.sberdevices.ru (p-i-exch-sc-m01.sberdevices.ru [172.16.192.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.sberdevices.ru (Postfix) with ESMTPS; Thu, 26 Dec 2024 16:56:37 +0300 (MSK) From: Martin Kurbanov To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Ezra Buehler , Alexey Romanov , Frieder Schrempf CC: , , , Martin Kurbanov Subject: [PATCH v3 6/7] mtd: spinand: micron: OTP access for MT29F2G01ABAGD Date: Thu, 26 Dec 2024 16:55:51 +0300 Message-ID: <20241226135623.43098-7-mmkurbanov@salutedevices.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241226135623.43098-1-mmkurbanov@salutedevices.com> References: <20241226135623.43098-1-mmkurbanov@salutedevices.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: p-i-exch-a-m2.sberdevices.ru (172.24.196.120) To p-i-exch-sc-m01.sberdevices.ru (172.16.192.107) X-KSMG-Rule-ID: 10 X-KSMG-Message-Action: clean X-KSMG-AntiSpam-Lua-Profiles: 190075 [Dec 26 2024] X-KSMG-AntiSpam-Version: 6.1.1.7 X-KSMG-AntiSpam-Envelope-From: mmkurbanov@salutedevices.com X-KSMG-AntiSpam-Rate: 0 X-KSMG-AntiSpam-Status: not_detected X-KSMG-AntiSpam-Method: none X-KSMG-AntiSpam-Auth: dkim=none X-KSMG-AntiSpam-Info: LuaCore: 49 0.3.49 28b3b64a43732373258a371bd1554adb2caa23cb, {Tracking_from_domain_doesnt_match_to}, smtp.sberdevices.ru:5.0.1,7.1.1;127.0.0.199:7.1.2;salutedevices.com:7.1.1;d41d8cd98f00b204e9800998ecf8427e.com:7.1.1, FromAlignment: s X-MS-Exchange-Organization-SCL: -1 X-KSMG-AntiSpam-Interceptor-Info: scan successful X-KSMG-AntiPhishing: Clean X-KSMG-LinksScanning: Clean X-KSMG-AntiVirus: Kaspersky Secure Mail Gateway, version 2.0.1.6960, bases: 2024/12/26 12:50:00 #26919000 X-KSMG-AntiVirus-Status: Clean, skipped Content-Type: text/plain; charset="utf-8" Support for OTP area access on Micron MT29F2G01ABAGD chip. Signed-off-by: Martin Kurbanov --- drivers/mtd/nand/spi/micron.c | 113 +++++++++++++++++++++++++++++++++- 1 file changed, 112 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c index 8d741be6d5f3e..beb4ca8df0653 100644 --- a/drivers/mtd/nand/spi/micron.c +++ b/drivers/mtd/nand/spi/micron.c @@ -9,6 +9,8 @@ #include #include #include +#include +#include =20 #define SPINAND_MFR_MICRON 0x2c =20 @@ -28,6 +30,10 @@ =20 #define MICRON_SELECT_DIE(x) ((x) << 6) =20 +#define MICRON_MT29F2G01ABAGD_CFG_OTP_STATE BIT(7) +#define MICRON_MT29F2G01ABAGD_CFG_OTP_LOCK \ + (CFG_OTP_ENABLE | MICRON_MT29F2G01ABAGD_CFG_OTP_STATE) + static SPINAND_OP_VARIANTS(quadio_read_cache_variants, //SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0), SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), @@ -182,6 +188,110 @@ static int micron_8_ecc_get_status(struct spinand_dev= ice *spinand, return -EINVAL; } =20 +static int mt29f2g01abagd_otp_is_locked(struct spinand_device *spinand) +{ + size_t bufsize =3D spinand_otp_page_size(spinand); + size_t retlen; + u8 *buf; + int ret; + + buf =3D kmalloc(bufsize, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + ret =3D spinand_upd_cfg(spinand, + MICRON_MT29F2G01ABAGD_CFG_OTP_LOCK, + MICRON_MT29F2G01ABAGD_CFG_OTP_STATE); + if (ret) + goto free_buf; + + ret =3D spinand_otp_read(spinand, 0, bufsize, &retlen, buf); + + if (spinand_upd_cfg(spinand, MICRON_MT29F2G01ABAGD_CFG_OTP_LOCK, + 0)) { + dev_warn(&spinand_to_mtd(spinand)->dev, + "Can not disable OTP mode\n"); + ret =3D -EIO; + } + + if (ret) + goto free_buf; + + /* If all zeros, then the OTP area is locked. */ + if (mem_is_zero(buf, bufsize)) + ret =3D 1; + +free_buf: + kfree(buf); + return ret; +} + +static int mt29f2g01abagd_otp_info(struct spinand_device *spinand, size_t = len, + struct otp_info *buf, size_t *retlen) +{ + int locked; + + if (len < sizeof(*buf)) + return -EINVAL; + + locked =3D mt29f2g01abagd_otp_is_locked(spinand); + if (locked < 0) + return locked; + + buf->locked =3D locked; + buf->start =3D 0; + buf->length =3D spinand_otp_size(spinand); + + *retlen =3D sizeof(*buf); + return 0; +} + +static int mt29f2g01abagd_otp_lock(struct spinand_device *spinand, loff_t = from, + size_t len) +{ + struct spi_mem_op write_op =3D SPINAND_WR_EN_DIS_OP(true); + struct spi_mem_op exec_op =3D SPINAND_PROG_EXEC_OP(0); + u8 status; + int ret; + + ret =3D spinand_upd_cfg(spinand, + MICRON_MT29F2G01ABAGD_CFG_OTP_LOCK, + MICRON_MT29F2G01ABAGD_CFG_OTP_LOCK); + if (!ret) + return ret; + + ret =3D spi_mem_exec_op(spinand->spimem, &write_op); + if (!ret) + goto out; + + ret =3D spi_mem_exec_op(spinand->spimem, &exec_op); + if (!ret) + goto out; + + ret =3D spinand_wait(spinand, + SPINAND_WRITE_INITIAL_DELAY_US, + SPINAND_WRITE_POLL_DELAY_US, + &status); + if (!ret && (status & STATUS_PROG_FAILED)) + ret =3D -EIO; + +out: + if (spinand_upd_cfg(spinand, MICRON_MT29F2G01ABAGD_CFG_OTP_LOCK, 0)) { + dev_warn(&spinand_to_mtd(spinand)->dev, + "Can not disable OTP mode\n"); + ret =3D -EIO; + } + + return ret; +} + +static const struct spinand_otp_ops mt29f2g01abagd_otp_ops =3D { + .info =3D mt29f2g01abagd_otp_info, + .lock =3D mt29f2g01abagd_otp_lock, + .read =3D spinand_otp_read, + .write =3D spinand_otp_write, +}; + static const struct spinand_info micron_spinand_table[] =3D { /* M79A 2Gb 3.3V */ SPINAND_INFO("MT29F2G01ABAGD", @@ -193,7 +303,8 @@ static const struct spinand_info micron_spinand_table[]= =3D { &x4_update_cache_variants), 0, SPINAND_ECCINFO(µn_8_ooblayout, - micron_8_ecc_get_status)), + micron_8_ecc_get_status), + SPINAND_OTP_INFO(12, 2, &mt29f2g01abagd_otp_ops)), /* M79A 2Gb 1.8V */ SPINAND_INFO("MT29F2G01ABBGD", SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x25), --=20 2.43.0 From nobody Tue Feb 10 00:06:40 2026 Received: from mx1.sberdevices.ru (mx2.sberdevices.ru [45.89.224.132]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AA56D1D6DBC for ; Thu, 26 Dec 2024 13:56:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.89.224.132 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1735221407; cv=none; b=Qmi2oE1cw8yfATKebnd3bCVDWNOEcCu3QMFRAURSxdUIQf5BDTqgWYFKzTgtId0MgL+PUiQseq+w9riPk8BWK/eEZ///T5DeBzdbtatRB+2h9m3s3feHLiH+3Z5qprb5gh2ecuBQmBU9c2fxXmtuPotwXrztkLuhymQt1JKoCjY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1735221407; c=relaxed/simple; bh=keyR3lskfE6DwK5WIR4oP5fzufWtuStl4WDwN6McwMU=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=TTuIwnNB3g/JyDq4FQa8k0ojXLlAC4TnczIFwvVBlLOpQKdz4tXwK8ivKv5vWU33f2EKE/iUHO/Vt06tVfnPmChrWwMhljoDMh5IYmn3mRRcFav+T90M8FP/Q0c56k66b+yFvvZPuf48pxpWXgCVBObF90R4Ap3apCMcgDuuN+U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=salutedevices.com; spf=pass smtp.mailfrom=salutedevices.com; dkim=pass (2048-bit key) header.d=salutedevices.com header.i=@salutedevices.com header.b=Py1Musc2; arc=none smtp.client-ip=45.89.224.132 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=salutedevices.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=salutedevices.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=salutedevices.com header.i=@salutedevices.com header.b="Py1Musc2" Received: from p-infra-ksmg-sc-msk02.sberdevices.ru (localhost [127.0.0.1]) by mx1.sberdevices.ru (Postfix) with ESMTP id 05722120026; Thu, 26 Dec 2024 16:56:38 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.sberdevices.ru 05722120026 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=salutedevices.com; s=mail; t=1735221398; bh=P01YHTijqZC1FwRzPHK4svt6kZH0FcJqhN7b0poWTuo=; h=From:To:Subject:Date:Message-ID:MIME-Version:Content-Type:From; b=Py1Musc2UZ+4VbIWPCCva8ry/CzZLsm/A8tXPm306Nii4eeK3ftbiI0Dxrcd2fAzz olu1T3i9C7dkstppBrV5IqdtysDUgb4u0S8B4BCVLfiEztJJ875csKa+cNAF2vdIKx gtA3NNZkCqfNL5F/RKkEpsxNlCWst4PBNIZlZv7ql+ux5sIaeDxdWe6gwRT+rvOvvM l9bMiWu33w3d4O4KRGPn8SLTK62Pskh7ToMazb1eqEx+WZ8zO05VCMBoyBSE2Nlz3L ybM6sK0XmVx4Bo3ZlT2Bs5X6YBOsrO6PydpX03F1LwlcWaeM684n//kdKQVXNWo6Eb Wkk606Dw/Zy2A== Received: from smtp.sberdevices.ru (p-i-exch-sc-m01.sberdevices.ru [172.16.192.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.sberdevices.ru (Postfix) with ESMTPS; Thu, 26 Dec 2024 16:56:37 +0300 (MSK) From: Martin Kurbanov To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Ezra Buehler , Alexey Romanov , Frieder Schrempf CC: , , , Martin Kurbanov Subject: [PATCH v3 7/7] mtd: spinand: esmt: OTP access for F50{L,D}1G41LB Date: Thu, 26 Dec 2024 16:55:52 +0300 Message-ID: <20241226135623.43098-8-mmkurbanov@salutedevices.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241226135623.43098-1-mmkurbanov@salutedevices.com> References: <20241226135623.43098-1-mmkurbanov@salutedevices.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: p-i-exch-a-m2.sberdevices.ru (172.24.196.120) To p-i-exch-sc-m01.sberdevices.ru (172.16.192.107) X-KSMG-Rule-ID: 10 X-KSMG-Message-Action: clean X-KSMG-AntiSpam-Lua-Profiles: 190075 [Dec 26 2024] X-KSMG-AntiSpam-Version: 6.1.1.7 X-KSMG-AntiSpam-Envelope-From: mmkurbanov@salutedevices.com X-KSMG-AntiSpam-Rate: 0 X-KSMG-AntiSpam-Status: not_detected X-KSMG-AntiSpam-Method: none X-KSMG-AntiSpam-Auth: dkim=none X-KSMG-AntiSpam-Info: LuaCore: 49 0.3.49 28b3b64a43732373258a371bd1554adb2caa23cb, {Tracking_from_domain_doesnt_match_to}, 127.0.0.199:7.1.2;smtp.sberdevices.ru:7.1.1,5.0.1;salutedevices.com:7.1.1;d41d8cd98f00b204e9800998ecf8427e.com:7.1.1, FromAlignment: s X-MS-Exchange-Organization-SCL: -1 X-KSMG-AntiSpam-Interceptor-Info: scan successful X-KSMG-AntiPhishing: Clean X-KSMG-LinksScanning: Clean X-KSMG-AntiVirus: Kaspersky Secure Mail Gateway, version 2.0.1.6960, bases: 2024/12/26 12:50:00 #26919000 X-KSMG-AntiVirus-Status: Clean, skipped Content-Type: text/plain; charset="utf-8" Support for OTP area access on ESMT F50L1G41LB and F50D1G41LB chips. Signed-off-by: Martin Kurbanov --- drivers/mtd/nand/spi/esmt.c | 70 +++++++++++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/nand/spi/esmt.c b/drivers/mtd/nand/spi/esmt.c index 4597a82de23a4..481005c518f15 100644 --- a/drivers/mtd/nand/spi/esmt.c +++ b/drivers/mtd/nand/spi/esmt.c @@ -8,10 +8,15 @@ #include #include #include +#include =20 /* ESMT uses GigaDevice 0xc8 JECDEC ID on some SPI NANDs */ #define SPINAND_MFR_ESMT_C8 0xc8 =20 +#define ESMT_F50L1G41LB_CFG_OTP_PROTECT BIT(7) +#define ESMT_F50L1G41LB_CFG_OTP_LOCK \ + (CFG_OTP_ENABLE | ESMT_F50L1G41LB_CFG_OTP_PROTECT) + static SPINAND_OP_VARIANTS(read_cache_variants, SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0), @@ -102,6 +107,65 @@ static const struct mtd_ooblayout_ops f50l1g41lb_oobla= yout =3D { .free =3D f50l1g41lb_ooblayout_free, }; =20 +static int f50l1g41lb_otp_info(struct spinand_device *spinand, size_t len, + struct otp_info *buf, size_t *retlen) +{ + if (len < sizeof(*buf)) + return -EINVAL; + + buf->locked =3D 0; + buf->start =3D 0; + buf->length =3D spinand_otp_size(spinand); + + *retlen =3D sizeof(*buf); + return 0; +} + +static int f50l1g41lb_otp_lock(struct spinand_device *spinand, loff_t from, + size_t len) +{ + struct spi_mem_op write_op =3D SPINAND_WR_EN_DIS_OP(true); + struct spi_mem_op exec_op =3D SPINAND_PROG_EXEC_OP(0); + u8 status; + int ret; + + ret =3D spinand_upd_cfg(spinand, ESMT_F50L1G41LB_CFG_OTP_LOCK, + ESMT_F50L1G41LB_CFG_OTP_LOCK); + if (!ret) + return ret; + + ret =3D spi_mem_exec_op(spinand->spimem, &write_op); + if (!ret) + goto out; + + ret =3D spi_mem_exec_op(spinand->spimem, &exec_op); + if (!ret) + goto out; + + ret =3D spinand_wait(spinand, + SPINAND_WRITE_INITIAL_DELAY_US, + SPINAND_WRITE_POLL_DELAY_US, + &status); + if (!ret && (status & STATUS_PROG_FAILED)) + ret =3D -EIO; + +out: + if (spinand_upd_cfg(spinand, ESMT_F50L1G41LB_CFG_OTP_LOCK, 0)) { + dev_warn(&spinand_to_mtd(spinand)->dev, + "Can not disable OTP mode\n"); + ret =3D -EIO; + } + + return ret; +} + +static const struct spinand_otp_ops f50l1g41lb_otp_ops =3D { + .info =3D f50l1g41lb_otp_info, + .lock =3D f50l1g41lb_otp_lock, + .read =3D spinand_otp_read, + .write =3D spinand_otp_write, +}; + static const struct spinand_info esmt_c8_spinand_table[] =3D { SPINAND_INFO("F50L1G41LB", SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x01, 0x7f, @@ -112,7 +176,8 @@ static const struct spinand_info esmt_c8_spinand_table[= ] =3D { &write_cache_variants, &update_cache_variants), 0, - SPINAND_ECCINFO(&f50l1g41lb_ooblayout, NULL)), + SPINAND_ECCINFO(&f50l1g41lb_ooblayout, NULL), + SPINAND_OTP_INFO(28, 2, &f50l1g41lb_otp_ops)), SPINAND_INFO("F50D1G41LB", SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x11, 0x7f, 0x7f, 0x7f), @@ -122,7 +187,8 @@ static const struct spinand_info esmt_c8_spinand_table[= ] =3D { &write_cache_variants, &update_cache_variants), 0, - SPINAND_ECCINFO(&f50l1g41lb_ooblayout, NULL)), + SPINAND_ECCINFO(&f50l1g41lb_ooblayout, NULL), + SPINAND_OTP_INFO(28, 2, &f50l1g41lb_otp_ops)), SPINAND_INFO("F50D2G41KA", SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x51, 0x7f, 0x7f, 0x7f), --=20 2.43.0