From nobody Wed Dec 17 06:34:58 2025 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 1A90B1A2FCC for ; Mon, 17 Jun 2024 13:35:29 +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=1718631334; cv=none; b=S0GNkFkBRzV4Z3JKRxQ775uvo5RwWgauV3FgIw5GKp/USCyJ6yESa09UIROuK4/EuMehQcrR7MDT1H+vOXjhoVarQCL2nLdr++lA1xKLIDDeqJpRrPgfBtnog9AXvNAu8ddv5Xxl19ULYCSVIIv+3uzZ+OuhyiE3x1nYgsWwUU0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718631334; c=relaxed/simple; bh=iTnMFZlI5mMPKNFaQJ/LO1hJGYd7hSpURWHy+1PTo5w=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=uPPAxXK9SWJdmrwPTHzG+rl53MF+vUFFRkE2q2az0k82BoZZqcK7/WeyjS+MPIGLs6pTXwu1yCRgKIBs/Jg/RaVobzHAHLYRhfRxyJQVadzNNjztD+o+LYoi4GuaMDlf3z+uGMbkrUPzqT+OboUs+ff+AnqLhiHhQVU8UxG/xgA= 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=gaPSf/+c; 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="gaPSf/+c" Received: from p-infra-ksmg-sc-msk01.sberdevices.ru (localhost [127.0.0.1]) by mx1.sberdevices.ru (Postfix) with ESMTP id 65F13100007; Mon, 17 Jun 2024 16:35:22 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.sberdevices.ru 65F13100007 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=salutedevices.com; s=mail; t=1718631322; bh=6/RL8IVZXxsdzvdm9UvKBkh1bDI5itnPbUoDhIDETh4=; h=From:To:Subject:Date:Message-ID:MIME-Version:Content-Type:From; b=gaPSf/+cuRtm7oF3DuCWDQfBXa7rxFiBrGu1l85VOZhzHH0ScMfuL4FEikFv3fcHw tMTb4dW70EgkcQ5FBobWGQaH2i0jmQaX6e8CZyvIdWBgyISK0e6rZSFXrgArUlgClA sQlFISL7D1f+2BW2Wg9/0Mk8cTAOIPZiaJJjArdPA6NkOwjWHcuMTLLmNfPWFUqFA4 KMVPQq+6GSXLaxpCMAFpPCdGVepbfIXkfA87U8uVg96c1PSNN/74FXxhTrTkzmRjzW JReLwX7FiAZcS1ghc0auFpDvkXMW8hKwCMKUe5ZmvNNcoJj7SCrC4lTwUPtLokkHJB F4f6gdinvp/iw== Received: from smtp.sberdevices.ru (p-i-exch-sc-m02.sberdevices.ru [172.16.192.103]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.sberdevices.ru (Postfix) with ESMTPS; Mon, 17 Jun 2024 16:35:22 +0300 (MSK) Received: from CAB-WSD-0004828.sberdevices.ru (100.64.160.123) by p-i-exch-sc-m02.sberdevices.ru (172.16.192.103) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.40; Mon, 17 Jun 2024 16:35:21 +0300 From: Martin Kurbanov To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Mika Westerberg , Michael Walle , Mark Brown , Chia-Lin Kao , Md Sadre Alam , Ezra Buehler , Sridharan S N , Frieder Schrempf , Alexey Romanov CC: , , , Martin Kurbanov Subject: [PATCH v1 1/5] mtd: spinand: make spinand_{read,write}_page global Date: Mon, 17 Jun 2024 16:34:53 +0300 Message-ID: <20240617133504.179705-2-mmkurbanov@salutedevices.com> X-Mailer: git-send-email 2.43.2 In-Reply-To: <20240617133504.179705-1-mmkurbanov@salutedevices.com> References: <20240617133504.179705-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-sc-m01.sberdevices.ru (172.16.192.107) To p-i-exch-sc-m02.sberdevices.ru (172.16.192.103) X-KSMG-Rule-ID: 10 X-KSMG-Message-Action: clean X-KSMG-AntiSpam-Lua-Profiles: 185966 [Jun 17 2024] X-KSMG-AntiSpam-Version: 6.1.0.4 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: 20 0.3.20 743589a8af6ec90b529f2124c2bbfc3ce1d2f20f, {Tracking_from_domain_doesnt_match_to}, d41d8cd98f00b204e9800998ecf8427e.com:7.1.1;salutedevices.com:7.1.1;100.64.160.123:7.1.2;smtp.sberdevices.ru:5.0.1,7.1.1;127.0.0.199:7.1.2, FromAlignment: s, ApMailHostAddress: 100.64.160.123 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/06/17 11:22:00 #25639124 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..807c24b0c7c4f 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 the 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 the 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.2 From nobody Wed Dec 17 06:34:58 2025 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 EE7F91A2FCF for ; Mon, 17 Jun 2024 13:35:30 +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=1718631333; cv=none; b=Jk/VTSx7dSuH4J2GmsGriO5xjPA3yQvpc4s0Vt9JoexwYkW7cibKffjFKh6IdBQDGInICnWZ7V84ldzxmx7jCHpyD3KfPjxtkX3fWUMF3JA1K5itoJ5DlePTFkG11wy+o5K66CjZYjEFTwY7TJWlLpg5l2h+sYe2DPjIuqAzdz8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718631333; c=relaxed/simple; bh=G1JbfvXY/qiM+L1edAJCH7BEGJJ3qNIJOnstdUEqxeU=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=YNkQamccftRjlMJ6Zledm9kkR5R7WRASxQsOpVnwOLl7S4SMXS4izoERQ63TGwu4TqCWqnbuuEedz2qgf9pkPOJcwP2fOjq09HEU89cqYSUB+wvts4J1v8reZwsJUvgdzv3SGhuvci9/4gS7cWbuWymN8Fi/Yx0aJmZjuAGhBdk= 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=UTCLUCTB; 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="UTCLUCTB" Received: from p-infra-ksmg-sc-msk02.sberdevices.ru (localhost [127.0.0.1]) by mx1.sberdevices.ru (Postfix) with ESMTP id B942412000B; Mon, 17 Jun 2024 16:35:22 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.sberdevices.ru B942412000B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=salutedevices.com; s=mail; t=1718631322; bh=WcL5BZZJWEHlfSbXCMuvF0QCupxulygIhNPX45T5o3s=; h=From:To:Subject:Date:Message-ID:MIME-Version:Content-Type:From; b=UTCLUCTBoM1LCdwkUwSeYKSgzkZGnZR6ckMCJiHtPJiOmcIXhLiPxexwxyS+277QL AhuKHtCO30NzKNX72/k8dVQuGOcb/9FUp7Ki1WfaYMIGaChxPBWE5cFbiK92OznQLK GXL/LERi4tZ+y58WiSGVA484xOvXUEtO7ifIY3vcXfQpHigY2fn1u9Z9tDqsvQqUvc y3IOMgxCWPhwiJI9TdtTWsT6f9RKlmhBCHAxCpOEu46gPeh6yv+ugZwetYV2f8uYUZ F02RT+jw18S1J9f5Lt5YXGtQUfnpm/H1qd7+D+lOJAhaBDtMTydpmKFFDndKPY8I0G P5YiXBU74fmSg== Received: from smtp.sberdevices.ru (p-i-exch-sc-m02.sberdevices.ru [172.16.192.103]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.sberdevices.ru (Postfix) with ESMTPS; Mon, 17 Jun 2024 16:35:22 +0300 (MSK) Received: from CAB-WSD-0004828.sberdevices.ru (100.64.160.123) by p-i-exch-sc-m02.sberdevices.ru (172.16.192.103) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.40; Mon, 17 Jun 2024 16:35:22 +0300 From: Martin Kurbanov To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Mika Westerberg , Michael Walle , Mark Brown , Chia-Lin Kao , Md Sadre Alam , Ezra Buehler , Sridharan S N , Frieder Schrempf , Alexey Romanov CC: , , , Martin Kurbanov Subject: [PATCH v1 2/5] mtd: spinand: add OTP support Date: Mon, 17 Jun 2024 16:34:54 +0300 Message-ID: <20240617133504.179705-3-mmkurbanov@salutedevices.com> X-Mailer: git-send-email 2.43.2 In-Reply-To: <20240617133504.179705-1-mmkurbanov@salutedevices.com> References: <20240617133504.179705-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-sc-m01.sberdevices.ru (172.16.192.107) To p-i-exch-sc-m02.sberdevices.ru (172.16.192.103) X-KSMG-Rule-ID: 10 X-KSMG-Message-Action: clean X-KSMG-AntiSpam-Lua-Profiles: 185966 [Jun 17 2024] X-KSMG-AntiSpam-Version: 6.1.0.4 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: 20 0.3.20 743589a8af6ec90b529f2124c2bbfc3ce1d2f20f, {Tracking_from_domain_doesnt_match_to}, 100.64.160.123:7.1.2;d41d8cd98f00b204e9800998ecf8427e.com:7.1.1;salutedevices.com:7.1.1;smtp.sberdevices.ru:7.1.1,5.0.1;127.0.0.199:7.1.2, FromAlignment: s, ApMailHostAddress: 100.64.160.123 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/06/17 12:47:00 #25641689 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 | 3 + drivers/mtd/nand/spi/otp.c | 219 ++++++++++++++++++++++++++++++++++ include/linux/mtd/spinand.h | 56 +++++++++ 4 files changed, 280 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 807c24b0c7c4f..2cb825edd49d0 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,8 @@ static int spinand_init(struct spinand_device *spinan= d) mtd->_max_bad_blocks =3D nanddev_mtd_max_bad_blocks; mtd->_resume =3D spinand_mtd_resume; =20 + spinand_set_mtd_otp_ops(spinand); + 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..e1f96b1898dcb --- /dev/null +++ b/drivers/mtd/nand/spi/otp.c @@ -0,0 +1,219 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2024, SaluteDevices. All Rights Reserved. + * + * Author: Martin Kurbanov + */ + +#include +#include + +static 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 unsigned int spinand_otp_npages(const struct spinand_device *spinan= d) +{ + return spinand->otp->layout.npages; +} + +static int spinand_otp_rw(struct spinand_device *spinand, loff_t from, + size_t len, u8 *buf, size_t *retlen, bool is_write) +{ + struct nand_device *nand =3D spinand_to_nand(spinand); + struct nand_page_io_req req =3D { 0 }; + unsigned long long page; + size_t copied =3D 0; + size_t otp_pagesize =3D nanddev_page_size(nand) + + nanddev_per_page_oobsize(nand); + int ret =3D 0; + + page =3D from; + req.dataoffs =3D do_div(page, otp_pagesize); + req.pos.page =3D 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.pos.page < spinand_otp_npages(spinand)) { + 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.dataoffs =3D 0; + copied +=3D req.datalen; + req.pos.page++; + } + + *retlen =3D copied; + + return ret; +} + +/** + * spinand_otp_read() - Read from OTP area + * @spinand: the spinand device + * @from: the offset to read + * @len: the number of data bytes to read + * @buf: the buffer to store the read data + * @retlen: the pointer to variable to store the number of read bytes + * + * Return: 0 on success, an error code otherwise. + */ +int spinand_otp_read(struct spinand_device *spinand, loff_t from, size_t l= en, + u8 *buf, size_t *retlen) +{ + return spinand_otp_rw(spinand, from, len, buf, retlen, false); +} + +/** + * spinand_otp_write() - Write to OTP area + * @spinand: the spinand device + * @from: the offset to write to + * @len: the number of bytes to write + * @buf: the buffer with data to write + * @retlen: the pointer to variable to store the number of written bytes + * + * Return: 0 on success, an error code otherwise. + */ +int spinand_otp_write(struct spinand_device *spinand, loff_t from, size_t = len, + const u8 *buf, size_t *retlen) +{ + return spinand_otp_rw(spinand, from, len, (u8 *)buf, retlen, true); +} + +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; + + mutex_lock(&spinand->lock); + ret =3D ops->info(spinand, len, buf, retlen); + mutex_unlock(&spinand->lock); + + return ret; +} + +static int spinand_mtd_otp_rw(struct mtd_info *mtd, loff_t ofs, size_t len, + size_t *retlen, u8 *buf, bool is_write) +{ + struct spinand_device *spinand =3D mtd_to_spinand(mtd); + const struct spinand_otp_ops *ops =3D spinand->otp->ops; + size_t total_len =3D len; + int ret; + + if (ofs < 0 || ofs + len > spinand_otp_size(spinand)) + return -EINVAL; + + total_len =3D min_t(size_t, total_len, spinand_otp_size(spinand) - ofs); + if (!total_len) + return 0; + + mutex_lock(&spinand->lock); + + ret =3D spinand_upd_cfg(spinand, CFG_OTP_ENABLE, CFG_OTP_ENABLE); + if (ret) + goto out_unlock; + + if (is_write) + ret =3D ops->write(spinand, ofs, len, buf, retlen); + else + ret =3D ops->read(spinand, ofs, len, buf, retlen); + + if (spinand_upd_cfg(spinand, CFG_OTP_ENABLE, 0)) { + WARN(1, "Can not disable OTP mode\n"); + ret =3D -EIO; + } + +out_unlock: + mutex_unlock(&spinand->lock); + return ret; +} + +static int spinand_mtd_otp_read(struct mtd_info *mtd, loff_t from, size_t = len, + size_t *retlen, u8 *buf) +{ + return spinand_mtd_otp_rw(mtd, from, len, retlen, buf, false); +} + +static int spinand_mtd_otp_write(struct mtd_info *mtd, loff_t to, size_t l= en, + size_t *retlen, const u8 *buf) +{ + return spinand_mtd_otp_rw(mtd, to, len, retlen, (u8 *)buf, true); +} + +static int spinand_mtd_otp_erase(struct mtd_info *mtd, loff_t from, 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 (!ops->erase) + return -EOPNOTSUPP; + + if (!len) + return 0; + + if (from < 0 || (from + len) > spinand_otp_size(spinand)) + return -EINVAL; + + mutex_lock(&spinand->lock); + ret =3D ops->erase(spinand, from, len); + mutex_unlock(&spinand->lock); + + return ret; +} + +static int spinand_mtd_otp_lock(struct mtd_info *mtd, loff_t from, 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 (!ops->lock) + return -EOPNOTSUPP; + + if (from < 0 || (from + len) > spinand_otp_size(spinand)) + return -EINVAL; + + mutex_lock(&spinand->lock); + ret =3D ops->lock(spinand, from, len); + mutex_unlock(&spinand->lock); + + return ret; +} + +/** + * spinand_set_mtd_otp_ops() - Set up OTP methods + * @spinand: the spinand device + * + * Set up OTP methods. + */ +void spinand_set_mtd_otp_ops(struct spinand_device *spinand) +{ + struct mtd_info *mtd =3D spinand_to_mtd(spinand); + + if (!spinand->otp->ops) + return; + + mtd->_get_user_prot_info =3D spinand_mtd_otp_info; + mtd->_read_user_prot_reg =3D spinand_mtd_otp_read; + mtd->_write_user_prot_reg =3D spinand_mtd_otp_write; + mtd->_lock_user_prot_reg =3D spinand_mtd_otp_lock; + mtd->_erase_user_prot_reg =3D spinand_mtd_otp_erase; +} diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h index 555846517faf6..a0d42a9be333f 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, + u8 *buf, size_t *retlen); + int (*write)(struct spinand_device *spinand, loff_t from, size_t len, + const u8 *buf, size_t *retlen); +}; + +/** + * 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,12 @@ int spinand_read_page(struct spinand_device *spinand, int spinand_write_page(struct spinand_device *spinand, const struct nand_page_io_req *req); =20 +void spinand_set_mtd_otp_ops(struct spinand_device *spinand); + +int spinand_otp_read(struct spinand_device *spinand, loff_t from, size_t l= en, + u8 *buf, size_t *retlen); + +int spinand_otp_write(struct spinand_device *spinand, loff_t from, size_t = len, + const u8 *buf, size_t *retlen); + #endif /* __LINUX_MTD_SPINAND_H */ --=20 2.43.2 From nobody Wed Dec 17 06:34:58 2025 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 D33331A2FC2 for ; Mon, 17 Jun 2024 13:35:30 +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=1718631333; cv=none; b=Q6faom7USboPclUUkD9VnwbvN4fdUhPM4p1WxOY57zDNLUX7AQLh7omvjVlMlbLztYFJo7YYXsul0MaRdsVbX3gjJQR9rHUNRfKHwlCZGT36hFbfMeNIMhpIHuer74lvGuni6sYLJ4oaYoseJhs+fCeITRW/FKrk0Rg3dnYhqEs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718631333; c=relaxed/simple; bh=35WKRlgt95dlXzrYED3ZuLd2zlL2yZUiX9zfMTO7aB8=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=EYanKtN6IzZkr4VDTnpvZI7aMYM/xn4x8mpmtnr7bOw5wrlNXlKxhcf2BivgxhM8lg5j5hO8+BHD2nBCm7gjOdZVBJBVNUm14ntplYqutG9PX6HHjywh4IgZQriV6q6SVBba/jKvMG+3a61fvz+gcKGFBLRXFcNUjRwa0MzhjdY= 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=AmHPfDiT; 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="AmHPfDiT" Received: from p-infra-ksmg-sc-msk01.sberdevices.ru (localhost [127.0.0.1]) by mx1.sberdevices.ru (Postfix) with ESMTP id 1D6CB100009; Mon, 17 Jun 2024 16:35:23 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.sberdevices.ru 1D6CB100009 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=salutedevices.com; s=mail; t=1718631323; bh=s3IdEpoU8Idriuk8g63QAeoI/TR/7zBrB1N7H/17w8U=; h=From:To:Subject:Date:Message-ID:MIME-Version:Content-Type:From; b=AmHPfDiTxt1A03tynXh9e4ElOYSFwA3pboSyYhjiSNG8gKbnaYEZAZZMOSy6rwT1x y4WyLGydxdIAhK7mFXjCMFz0gCGChrXigonvXRyRzMmsCTESZyRjUc1uU40TgPhgxQ 7Rii47N1O2fy7bzmaP7fvLDGk3fcUpd/C1Pd2vLou5cx0GljRkqT7nvOXaKQQFfbUb dUGzzHs7Ot/Noyca2lt8U1joca4VAqTw5Z287f85cphupiZRAxk101WBU4vBUhRX2x QLs88HsEufe8DnBR+MWI7Vn1WnvCH/t8vuGlocrP4f98uhd2L2KJ7CPjcUM3ZTVw3F traq7Z2IKwx1g== Received: from smtp.sberdevices.ru (p-i-exch-sc-m02.sberdevices.ru [172.16.192.103]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.sberdevices.ru (Postfix) with ESMTPS; Mon, 17 Jun 2024 16:35:22 +0300 (MSK) Received: from CAB-WSD-0004828.sberdevices.ru (100.64.160.123) by p-i-exch-sc-m02.sberdevices.ru (172.16.192.103) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.40; Mon, 17 Jun 2024 16:35:22 +0300 From: Martin Kurbanov To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Mika Westerberg , Michael Walle , Mark Brown , Chia-Lin Kao , Md Sadre Alam , Ezra Buehler , Sridharan S N , Frieder Schrempf , Alexey Romanov CC: , , , Martin Kurbanov Subject: [PATCH v1 3/5] mtd: spinand: make spinand_wait() global Date: Mon, 17 Jun 2024 16:34:55 +0300 Message-ID: <20240617133504.179705-4-mmkurbanov@salutedevices.com> X-Mailer: git-send-email 2.43.2 In-Reply-To: <20240617133504.179705-1-mmkurbanov@salutedevices.com> References: <20240617133504.179705-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-sc-m01.sberdevices.ru (172.16.192.107) To p-i-exch-sc-m02.sberdevices.ru (172.16.192.103) X-KSMG-Rule-ID: 10 X-KSMG-Message-Action: clean X-KSMG-AntiSpam-Lua-Profiles: 185966 [Jun 17 2024] X-KSMG-AntiSpam-Version: 6.1.0.4 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: 20 0.3.20 743589a8af6ec90b529f2124c2bbfc3ce1d2f20f, {Tracking_from_domain_doesnt_match_to}, d41d8cd98f00b204e9800998ecf8427e.com:7.1.1;salutedevices.com:7.1.1;100.64.160.123:7.1.2;smtp.sberdevices.ru:5.0.1,7.1.1;127.0.0.199:7.1.2, FromAlignment: s, ApMailHostAddress: 100.64.160.123 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/06/17 11:22:00 #25639124 X-KSMG-AntiVirus-Status: Clean, skipped Content-Type: text/plain; charset="utf-8" Change the function spinand_wait() 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 ++++++++++++++---- include/linux/mtd/spinand.h | 3 +++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c index 2cb825edd49d0..c3e3d1e9599f1 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/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h index a0d42a9be333f..3b9e7ed32c81d 100644 --- a/include/linux/mtd/spinand.h +++ b/include/linux/mtd/spinand.h @@ -567,6 +567,9 @@ int spinand_match_and_init(struct spinand_device *spina= nd, 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 --=20 2.43.2 From nobody Wed Dec 17 06:34:58 2025 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 EE8471A2FD2 for ; Mon, 17 Jun 2024 13:35:30 +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=1718631333; cv=none; b=jaFiY77c6mL7NG9mfe/Yg+NpxAHPLQlAUq2h0f/OyKKxySqAbcuv7b1jdaepqxRJwuFsNexJbOuL7FCKCYz7UWWbk79gQyiBVlWFH1omnM4JIIsAJLaprCJo3Jp0/ahGKGTVVxEeHJiyMI0RYRVBQJKSoUtfAQnyVxJng6DV42A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718631333; c=relaxed/simple; bh=I2xX5u+UMBg41/s6mOj4KmE/IyEX9gwKjikWs3IJx4c=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=c7rbsqvKbEUrImXjH8qoHMYkduoSfnl6q8MKpnlNqZ8iMLIftHH0fEpVE3hIgkMDZTh9mSNRIydqUaU262yZmYiRbYKGFJOLRq3XjFCliafjKuGZhdTC0oE0i52TAsGcLZ8q6GpYPTbiRPVpXYs+1YYnSrx6DNGdkPRmsAw/Z5M= 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=B42RruPx; 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="B42RruPx" Received: from p-infra-ksmg-sc-msk02.sberdevices.ru (localhost [127.0.0.1]) by mx1.sberdevices.ru (Postfix) with ESMTP id 5913812000C; Mon, 17 Jun 2024 16:35:23 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.sberdevices.ru 5913812000C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=salutedevices.com; s=mail; t=1718631323; bh=/PdmQDr5X1ZUQQlzbIxZZmM5eEFyv/yRCGrGua+f4yo=; h=From:To:Subject:Date:Message-ID:MIME-Version:Content-Type:From; b=B42RruPxDcQ7Qnmb1F2d92k0TDLMQae2lgOBpkj0qKyN/yxq2T99FyelQKXt7Aa1n nIrmyq6gHFleC+UrmJC2ZIcTiBOZE4ItxeyTBP9UWBVSeDZ+mOrCaWPlPcE6YQi0vi VnlkiUgkBuTH3zDGc5AJM45SBO2kVark8wPT5wsUAUiU6axjcW3o/27xDTfsWJ5B7s OjtlYHnC3jm871sRUffltz8JB1sCyYvEQcF2vMD+5uZV/NoQ0YWFlWDJlspV1AgQql vkC5ajsTXkQAHa6+q2ZB6gYW9Prk3P8fEYD1Cm7DxBQrRl7xa2CAi5e+4RPFFF6aah R7f+j0wlL/TwA== Received: from smtp.sberdevices.ru (p-i-exch-sc-m02.sberdevices.ru [172.16.192.103]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.sberdevices.ru (Postfix) with ESMTPS; Mon, 17 Jun 2024 16:35:23 +0300 (MSK) Received: from CAB-WSD-0004828.sberdevices.ru (100.64.160.123) by p-i-exch-sc-m02.sberdevices.ru (172.16.192.103) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.40; Mon, 17 Jun 2024 16:35:22 +0300 From: Martin Kurbanov To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Mika Westerberg , Michael Walle , Mark Brown , Chia-Lin Kao , Md Sadre Alam , Ezra Buehler , Sridharan S N , Frieder Schrempf , Alexey Romanov CC: , , , Martin Kurbanov Subject: [PATCH v1 4/5] mtd: spinand: micron: OTP access for MT29F2G01ABAGD Date: Mon, 17 Jun 2024 16:34:56 +0300 Message-ID: <20240617133504.179705-5-mmkurbanov@salutedevices.com> X-Mailer: git-send-email 2.43.2 In-Reply-To: <20240617133504.179705-1-mmkurbanov@salutedevices.com> References: <20240617133504.179705-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-sc-m01.sberdevices.ru (172.16.192.107) To p-i-exch-sc-m02.sberdevices.ru (172.16.192.103) X-KSMG-Rule-ID: 10 X-KSMG-Message-Action: clean X-KSMG-AntiSpam-Lua-Profiles: 185966 [Jun 17 2024] X-KSMG-AntiSpam-Version: 6.1.0.4 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: 20 0.3.20 743589a8af6ec90b529f2124c2bbfc3ce1d2f20f, {Tracking_from_domain_doesnt_match_to}, 100.64.160.123:7.1.2;d41d8cd98f00b204e9800998ecf8427e.com:7.1.1;salutedevices.com:7.1.1;smtp.sberdevices.ru:7.1.1,5.0.1;127.0.0.199:7.1.2, FromAlignment: s, ApMailHostAddress: 100.64.160.123 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/06/17 12:47:00 #25641689 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 | 117 +++++++++++++++++++++++++++++++++- 1 file changed, 116 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c index 8d741be6d5f3e..a538409db4ccd 100644 --- a/drivers/mtd/nand/spi/micron.c +++ b/drivers/mtd/nand/spi/micron.c @@ -9,6 +9,7 @@ #include #include #include +#include =20 #define SPINAND_MFR_MICRON 0x2c =20 @@ -28,6 +29,16 @@ =20 #define MICRON_SELECT_DIE(x) ((x) << 6) =20 +#define MICRON_MT29F2G01ABAGD_OTP_PAGES 12 +#define MICRON_MT29F2G01ABAGD_OTP_PAGE_SIZE 2176 +#define MICRON_MT29F2G01ABAGD_OTP_SIZE_BYTES \ + (MICRON_MT29F2G01ABAGD_OTP_PAGES * \ + MICRON_MT29F2G01ABAGD_OTP_PAGE_SIZE) + +#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 +193,108 @@ 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 buf_size =3D MICRON_MT29F2G01ABAGD_OTP_PAGE_SIZE; + size_t retlen; + u8 *buf; + int ret; + + buf =3D kmalloc(buf_size, 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 out; + + ret =3D spinand_otp_read(spinand, 0, buf_size, buf, &retlen); + + if (spinand_upd_cfg(spinand, MICRON_MT29F2G01ABAGD_CFG_OTP_LOCK, + 0)) { + WARN(1, "Can not disable OTP mode\n"); + ret =3D -EIO; + } + + if (!ret) { + size_t i =3D 0; + + /* If all zeros, then the OTP area is locked. */ + while (i < buf_size && *(uint32_t *)(&buf[i]) =3D=3D 0) + i +=3D 4; + + if (i =3D=3D buf_size) + ret =3D 1; + } + +out: + 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 MICRON_MT29F2G01ABAGD_OTP_SIZE_BYTES; + + *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); + 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, 10, 5, NULL); + if (!ret) + goto out; + +out: + if (spinand_upd_cfg(spinand, MICRON_MT29F2G01ABAGD_CFG_OTP_LOCK, 0)) { + WARN(1, "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 +306,9 @@ 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(MICRON_MT29F2G01ABAGD_OTP_PAGES, + &mt29f2g01abagd_otp_ops)), /* M79A 2Gb 1.8V */ SPINAND_INFO("MT29F2G01ABBGD", SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x25), --=20 2.43.2 From nobody Wed Dec 17 06:34:58 2025 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 5BE9C19AA59 for ; Mon, 17 Jun 2024 13:35:31 +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=1718631334; cv=none; b=UovkMRdkOzGW1NFkdIHlalqdHE2uo7C1F/ble3Lfn+mueyT1WaSrhJ6rmw9f9PdhR4+MCh/+InT7RLy0e5yPthQyc+uf7aYLgLUO7uwC8VMoyPGBQXUQ3Xrokj5zANsGxoIW6VpMhrKIOB1QetBx3+9zlaGwkkYkU+Z97hQFbOQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718631334; c=relaxed/simple; bh=Ejaw2UcHOwsVJe6Dop7ZufRwkMAyG6vDZ5UoXcEF50I=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=pofyWPvj1my0LCbI+O1ikgn/x3mfSV43o9IdTxgSrFpR+15ydZVXdCNX8qiBLDawXgeUOtD8SoE2phFu5OEg/mJhnH9ME9kTUcE+Pwn74bIa2QWbO/632VvJuH7VGXbqcuesJOc/WHY4b+q7vGP3BFQeEhDF+5zV48zlgSZ17tE= 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=oox7kvXC; 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="oox7kvXC" Received: from p-infra-ksmg-sc-msk01.sberdevices.ru (localhost [127.0.0.1]) by mx1.sberdevices.ru (Postfix) with ESMTP id A5BDA10000B; Mon, 17 Jun 2024 16:35:23 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.sberdevices.ru A5BDA10000B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=salutedevices.com; s=mail; t=1718631323; bh=YcHG6WWlH0ElSTuFNLEX2yBk3OYum4OtJYp6S6fudRY=; h=From:To:Subject:Date:Message-ID:MIME-Version:Content-Type:From; b=oox7kvXCIibITAlHTmBPP+PQgiGmN+ytwo7GRD1FAakArfLHnuuCIONgRs7OnI5cb VKlgm6mTm0dfolhKJSvHLPdacW5HP9LsnV2gn3a+BXoIse8ooynrr4Bn6rVhuIlfhT 3eVYhBQpky9ptqMS9r8txCdeeoZq/2O2MXxBnpSUoLg8RSiguji0/gK2cYV3/cNtNE mtAK+9xaZH6kdtEFR4JvdOdYc16ikFCAPpw+E6djeq/3cWLaZs3dIdOoIkydH8rhUU rVOX/PYk5QExj5eXwC6vPOYQ+V3om3sq5LgsDaWRoT7Nk5o8ImYhxEfjQ0puNXtUy1 DlJNAdGsXuheg== Received: from smtp.sberdevices.ru (p-i-exch-sc-m02.sberdevices.ru [172.16.192.103]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.sberdevices.ru (Postfix) with ESMTPS; Mon, 17 Jun 2024 16:35:23 +0300 (MSK) Received: from CAB-WSD-0004828.sberdevices.ru (100.64.160.123) by p-i-exch-sc-m02.sberdevices.ru (172.16.192.103) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.40; Mon, 17 Jun 2024 16:35:23 +0300 From: Martin Kurbanov To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Mika Westerberg , Michael Walle , Mark Brown , Chia-Lin Kao , Md Sadre Alam , Ezra Buehler , Sridharan S N , Frieder Schrempf , Alexey Romanov CC: , , , Martin Kurbanov Subject: [PATCH v1 5/5] mtd: spinand: esmt: OTP access for F50{L,D}1G41LB Date: Mon, 17 Jun 2024 16:34:57 +0300 Message-ID: <20240617133504.179705-6-mmkurbanov@salutedevices.com> X-Mailer: git-send-email 2.43.2 In-Reply-To: <20240617133504.179705-1-mmkurbanov@salutedevices.com> References: <20240617133504.179705-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-sc-m01.sberdevices.ru (172.16.192.107) To p-i-exch-sc-m02.sberdevices.ru (172.16.192.103) X-KSMG-Rule-ID: 10 X-KSMG-Message-Action: clean X-KSMG-AntiSpam-Lua-Profiles: 185966 [Jun 17 2024] X-KSMG-AntiSpam-Version: 6.1.0.4 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: 20 0.3.20 743589a8af6ec90b529f2124c2bbfc3ce1d2f20f, {Tracking_from_domain_doesnt_match_to}, d41d8cd98f00b204e9800998ecf8427e.com:7.1.1;salutedevices.com:7.1.1;100.64.160.123:7.1.2;smtp.sberdevices.ru:5.0.1,7.1.1;127.0.0.199:7.1.2, FromAlignment: s, ApMailHostAddress: 100.64.160.123 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/06/17 11:22:00 #25639124 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 | 69 +++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/nand/spi/esmt.c b/drivers/mtd/nand/spi/esmt.c index 4597a82de23a4..1806e9d48c176 100644 --- a/drivers/mtd/nand/spi/esmt.c +++ b/drivers/mtd/nand/spi/esmt.c @@ -12,6 +12,13 @@ /* 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) + +#define ESMT_F50L1G41LB_PAGE_SIZE 2112 +#define ESMT_F50L1G41LB_OTP_PAGES 28 + 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 +109,60 @@ 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 ESMT_F50L1G41LB_PAGE_SIZE * ESMT_F50L1G41LB_OTP_PAGES; + + *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); + 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, 10, 5, NULL); + if (!ret) + goto out; + +out: + if (spinand_upd_cfg(spinand, ESMT_F50L1G41LB_CFG_OTP_LOCK, 0)) { + WARN(1, "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 +173,9 @@ 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(ESMT_F50L1G41LB_OTP_PAGES, + &f50l1g41lb_otp_ops)), SPINAND_INFO("F50D1G41LB", SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x11, 0x7f, 0x7f, 0x7f), @@ -122,7 +185,9 @@ 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(ESMT_F50L1G41LB_OTP_PAGES, + &f50l1g41lb_otp_ops)), SPINAND_INFO("F50D2G41KA", SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x51, 0x7f, 0x7f, 0x7f), --=20 2.43.2