From patchwork Fri Aug 12 08:06:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Takahiro Kuwano X-Patchwork-Id: 1665813 X-Patchwork-Delegate: tudor.ambarus@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=bombadil.20210309 header.b=TBK6uhRh; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20210112 header.b=ExEImUuk; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:3::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4M3xB95RFRz9sGG for ; Fri, 12 Aug 2022 18:08:01 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=qFE0jILWAyoBCvmjEjuLnwxaonKqDu6BvFK7MXOBwWE=; b=TBK6uhRhBstUc7 Gqd5nS7mopWdq1xG26rYPptLhQQrC9iShviUfUx+uFqBHWDJW6bWGYLOa/EwC+Kb/S7PaolQQnH6I 4RyTfbgtscnZwA9yZyo5LubFCHW37Vvx1J9HJwtvzzCBrDY9jGHF8Ryoiyk8rcSXklauQLKtJbwW2 Exo++bJLaDDEGJVKnbWNV+m6pyDmDrKeVz5IJXT1RfR0a1ZsDUq3q5FLZYrB1cyT1CRJiijkDDen5 9KvXGEUP3i9xwSfhSzdX1wnfeuu97cl27qG8ThTb+U+03qbc/8Xv7RmZbVZllvK+e+DCb0aOc2lWt /S5tecsEvk7cPNMKgGcQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1oMPhT-002UnR-RX; Fri, 12 Aug 2022 08:07:24 +0000 Received: from mail-pf1-x42c.google.com ([2607:f8b0:4864:20::42c]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1oMPhI-002UOV-O6 for linux-mtd@lists.infradead.org; Fri, 12 Aug 2022 08:07:15 +0000 Received: by mail-pf1-x42c.google.com with SMTP id f30so319257pfq.4 for ; Fri, 12 Aug 2022 01:07:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc; bh=zuHWbJBc/sLNoIZnACDP0TFKgedOgbrSIRavKxG9kQk=; b=ExEImUukaK9ab+AgKQbWrpEVw9hn3KU2y3G0P7ZsmHMllyTNFw3NIKXAXFcVVQ95cO Lx/ogmzNgIwqrDteyl/eRoQHBPSfxmIcRC1ITEbVBR1LRbm+RLvw1/DvJFMKVEeUruQh IOmEVGjcWRUSb5/Ms7yOkPc60tAhEAJ2cux1G62MmskAMlq7dRqaxSDKMfxc5xig9zts 44cQhaPby7wJG8/SRRJpP3JM616mavH7ffoUkLfibCg9PoYfnACMWZeq5Jy5bzUmzZxY 2v97hPnYhOFY5T2LshnhHM5XmU5cf7MxGFGbV/Ej1V/oLRQFjJpp4TRvmTG0Y3mL5wFw bnPA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc; bh=zuHWbJBc/sLNoIZnACDP0TFKgedOgbrSIRavKxG9kQk=; b=KvNdQyJnaJZJv0UHHikWp8iBjIuNZs1ptuXeEVtNgiO3Fx3mSf61y/33/Padjny4GR sYFnsTnRCR/4lsQa+V4hWV8GCDHg15T5b28Wy+WtMaiYKLjqP3vpumRJUUxLG6a6n2Ps Te6j7Bb1MjjH51bw/oTM0bWu/1b3NFqTSw49z6uo5I9HfBgTJ+CJKIPNkbCxJx0/aLGB JtSl2MVzP1bLmmNeIfKpo5li4c1WrOszLxoKoh1f4F4AyOSdADLHu94YlTbjyfgeSe+b PY+nmC5K3TrgkuZUeJM3riCvP1yIKh5oBKeKAWM/mQbU+J3kYGkK8CZI+dCEzH2T7NCn 4j3A== X-Gm-Message-State: ACgBeo04bLCqyZHkD9upMyUsBxRVEjWorsOBhnhEtOxY5i5n8hxjCSKw TQVU9to1PvU/+5ho/Yytf9GCjmsYL+Q= X-Google-Smtp-Source: AA6agR6FJ4Jg+LzeD3ZtuX3PySU+Tyt7CHGIyCpfuhWef5Lb3pB3rm56hA9XSj8GNlAfDEdSktkCZA== X-Received: by 2002:aa7:88cb:0:b0:52f:76bd:7a65 with SMTP id k11-20020aa788cb000000b0052f76bd7a65mr2913202pff.72.1660291629946; Fri, 12 Aug 2022 01:07:09 -0700 (PDT) Received: from ISCNPF1JZGWX.infineon.com (KD106168128197.ppp-bb.dion.ne.jp. [106.168.128.197]) by smtp.gmail.com with ESMTPSA id y192-20020a6264c9000000b0052dce4edceesm960013pfb.169.2022.08.12.01.07.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 12 Aug 2022 01:07:09 -0700 (PDT) From: tkuw584924@gmail.com X-Google-Original-From: Takahiro.Kuwano@infineon.com To: linux-mtd@lists.infradead.org Cc: tudor.ambarus@microchip.com, pratyush@kernel.org, michael@walle.cc, miquel.raynal@bootlin.com, richard@nod.at, vigneshr@ti.com, tkuw584924@gmail.com, Bacem.Daassi@infineon.com, Takahiro Kuwano Subject: [PATCH 1/2] mtd: spi-nor: core: Add a helper to read with alternative method Date: Fri, 12 Aug 2022 17:06:32 +0900 Message-Id: X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220812_010712_842132_41D8AA95 X-CRM114-Status: GOOD ( 11.99 ) X-Spam-Score: 0.1 (/) X-Spam-Report: Spam detection software, running on the system "bombadil.infradead.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: From: Takahiro Kuwano The existing spi_nor_read_data() uses preset opcode, number of address bytes, and dummy cycles. During SFDP parse and corresponding fixups we need to perform read op with different opcode, number of a [...] Content analysis details: (0.1 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [2607:f8b0:4864:20:0:0:0:42c listed in] [list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider [tkuw584924[at]gmail.com] 0.2 FREEMAIL_ENVFROM_END_DIGIT Envelope-from freemail username ends in digit [tkuw584924[at]gmail.com] -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: Takahiro Kuwano The existing spi_nor_read_data() uses preset opcode, number of address bytes, and dummy cycles. During SFDP parse and corresponding fixups we need to perform read op with different opcode, number of address, and/or dummy cycles from preset ones. The spi_nor_alt_read() helps that by backup - read op - restore the preset opcode, etc. Signed-off-by: Takahiro Kuwano --- drivers/mtd/spi-nor/core.c | 48 ++++++++++++++++++++++++++++++++++++++ drivers/mtd/spi-nor/core.h | 2 ++ 2 files changed, 50 insertions(+) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index f2c64006f8d7..ae98b4ad9b19 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -247,6 +247,54 @@ ssize_t spi_nor_read_data(struct spi_nor *nor, loff_t from, size_t len, u8 *buf) return nor->controller_ops->read(nor, from, len, buf); } +/** + * spi_nor_alt_read() - read data from flash memory with alternative opcode, + * number of address bytes, and dummy cycles. + * @nor: pointer to 'struct spi_nor' + * @from: offset to read from + * @len: number of bytes to read + * @buf: pointer to dst buffer + * @read_opcode: read opcode to issue + * @addr_nbytes: number of address bytes to send + * @read_dummy: number of dummy cycles needed to read + * + * Return: 0 on success, -errno otherwise + */ +int spi_nor_alt_read(struct spi_nor *nor, u32 addr, size_t len, u8 *buf, + u8 read_opcode, u8 addr_nbytes, u8 read_dummy) +{ + u8 bak_read_opcode = nor->read_opcode; + u8 bak_addr_nbytes = nor->addr_nbytes; + u8 bak_read_dummy = nor->read_dummy; + ssize_t ret; + + nor->read_opcode = read_opcode; + nor->addr_nbytes = addr_nbytes; + nor->read_dummy = read_dummy; + + while (len) { + ret = spi_nor_read_data(nor, addr, len, buf); + if (ret < 0) + goto out; + if (!ret || ret > len) { + ret = -EIO; + goto out; + } + + buf += ret; + addr += ret; + len -= ret; + } + ret = 0; + +out: + nor->read_opcode = bak_read_opcode; + nor->addr_nbytes = bak_addr_nbytes; + nor->read_dummy = bak_read_dummy; + + return ret; +} + /** * spi_nor_spimem_write_data() - write data to flash memory via * spi-mem diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h index 85b0cf254e97..4f1e636f9362 100644 --- a/drivers/mtd/spi-nor/core.h +++ b/drivers/mtd/spi-nor/core.h @@ -656,6 +656,8 @@ ssize_t spi_nor_read_data(struct spi_nor *nor, loff_t from, size_t len, u8 *buf); ssize_t spi_nor_write_data(struct spi_nor *nor, loff_t to, size_t len, const u8 *buf); +int spi_nor_alt_read(struct spi_nor *nor, u32 addr, size_t len, u8 *buf, + u8 read_opcode, u8 addr_nbytes, u8 read_dummy); int spi_nor_read_any_reg(struct spi_nor *nor, struct spi_mem_op *op, enum spi_nor_protocol proto); int spi_nor_write_any_volatile_reg(struct spi_nor *nor, struct spi_mem_op *op, From patchwork Fri Aug 12 08:06:33 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Takahiro Kuwano X-Patchwork-Id: 1665815 X-Patchwork-Delegate: tudor.ambarus@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=bombadil.20210309 header.b=KHuvjVVg; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20210112 header.b=lcotQ3ts; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:3::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4M3xBG6dZVz9sG6 for ; Fri, 12 Aug 2022 18:08:06 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=PJt3lJHD9g8mBIZWc/tkef2RSnWYgtHAa0Tw62hSjKI=; b=KHuvjVVgIL56Pf SabG7zNSGtvLd2zHaRzqw0uN1hHlS4J3bXXRRko3Gd2rGI8rdzjfRgfhLEijrXB47NOPqcbAtXH/Z 3ZSz30BVK4ghsVtDveJQjq+yrQHNRAehNh6hBylXzb8FN2OXOOQyMMrsWc0nz3FegbwoW0+817CrE BpTL0n6awnZWsRbmSJY9v7tWc5tK5GqhKv+V2qSHXfbtxfw4yiSxoVVO48yoObDWfK6LweCJyiG5K b6shjhBnG0V/xFNaDnLbZyUiX0+bTI1FLQnQw8Q27bZY5wL8tCgxutprU0yk12kUOM06eO23QlExr GfKdmHjPgPPSdbsrWN6g==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1oMPhc-002V2Z-N8; Fri, 12 Aug 2022 08:07:33 +0000 Received: from mail-pj1-x102b.google.com ([2607:f8b0:4864:20::102b]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1oMPhJ-002UTC-Ba for linux-mtd@lists.infradead.org; Fri, 12 Aug 2022 08:07:16 +0000 Received: by mail-pj1-x102b.google.com with SMTP id a8so324383pjg.5 for ; Fri, 12 Aug 2022 01:07:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc; bh=lvRrH/UQjtY9wWgGPlxUog7WaOl+uB+5I8N2soyG+hw=; b=lcotQ3tse4/IzAWxjtgFckSnJev8GOKJJEGVtrQEP9RZoIUEVlKmErJgHCBttFwR+k nlVmiAODWM2wtR6OAc8s4Gz+DOTi9BWX7rcLkoWtH9joTphqAPnKzq2SdL5CN1Gqb59O 6pI4Cc26M7vHEq0NukzBPSTKf+7pwbhQVd1s4qFn8XdokJsyhCwvV+spUcx24a9UJ2W0 pG1JJIEQitr5xrCa0l4IX3wFmglDBebvm7jW6afcYBcGNZYFphVeK9SPoHvlMUf3+a7o zWpKvZ9UqulSs0hgQr0/ZEHw0G08k74wCX66UbNP0L/oAwwHwJjOtaQp6TAevYo7Kwkt KPlg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc; bh=lvRrH/UQjtY9wWgGPlxUog7WaOl+uB+5I8N2soyG+hw=; b=e6tYV2z9V5brnabCTYLfViwYnArPhUXWQuOZ4HR8ulh+89+sn2zGFI9AugGvR6/F1B 5iX+A3n3djA78ZMvV9CBs92Zymdj7NzqyrBaLXXQTxyJbfcGwpJio3o5PWAwSjKlIzMC cipK223ltuOY4haHAJh/HGn8ZTZYD6IdkMUm5ZP8iBEn/jQ4cz1g3L8I/xIhC91GgTyS VhbFC66z0V2ngmwbYH5UlRSIozca20Cck2yPQP3UBSIOvrBIIjQsohkaePwQa/l3c/EY /l7VcE9N54Z3fijN65lcngO7P+Jy1BNV2RYmhyhh9u8NpmqyxJN+QIYs/lxM8lJLLAMe XMqA== X-Gm-Message-State: ACgBeo0mpD8dBspeZvmOLRHIzn3eB4Eb6qmOGcq5vNBD0WLYPRPGaRdm le9bqJ+1W+Qt6AzLHJCiQwYQ6aWrkEg= X-Google-Smtp-Source: AA6agR7DMbkGPxF6Q50/0obxnpufZkCdNabCFgCcW0LIsjgrDkOg8+PSlKtk1v9+eDeaO1X6XNXaUw== X-Received: by 2002:a17:90b:38cc:b0:1f7:2835:d45e with SMTP id nn12-20020a17090b38cc00b001f72835d45emr2854592pjb.177.1660291632328; Fri, 12 Aug 2022 01:07:12 -0700 (PDT) Received: from ISCNPF1JZGWX.infineon.com (KD106168128197.ppp-bb.dion.ne.jp. [106.168.128.197]) by smtp.gmail.com with ESMTPSA id y192-20020a6264c9000000b0052dce4edceesm960013pfb.169.2022.08.12.01.07.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 12 Aug 2022 01:07:12 -0700 (PDT) From: tkuw584924@gmail.com X-Google-Original-From: Takahiro.Kuwano@infineon.com To: linux-mtd@lists.infradead.org Cc: tudor.ambarus@microchip.com, pratyush@kernel.org, michael@walle.cc, miquel.raynal@bootlin.com, richard@nod.at, vigneshr@ti.com, tkuw584924@gmail.com, Bacem.Daassi@infineon.com, Takahiro Kuwano Subject: [PATCH 2/2] mtd: spi-nor: spansion: Discover current address mode by CRC Date: Fri, 12 Aug 2022 17:06:33 +0900 Message-Id: <53d37eead9bdd09744af555b93381af477643a46.1660291281.git.Takahiro.Kuwano@infineon.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220812_010713_444371_EF0F6EFB X-CRM114-Status: GOOD ( 22.12 ) X-Spam-Score: 0.1 (/) X-Spam-Report: Spam detection software, running on the system "bombadil.infradead.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: From: Takahiro Kuwano In some Infineon devices, the address mode (3- or 4-byte) is configurable in both volatile and non-volatile registers. Determining current address mode prior to SMPT parse is crucial because Read Any [...] Content analysis details: (0.1 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [2607:f8b0:4864:20:0:0:0:102b listed in] [list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider [tkuw584924[at]gmail.com] 0.2 FREEMAIL_ENVFROM_END_DIGIT Envelope-from freemail username ends in digit [tkuw584924[at]gmail.com] -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: Takahiro Kuwano In some Infineon devices, the address mode (3- or 4-byte) is configurable in both volatile and non-volatile registers. Determining current address mode prior to SMPT parse is crucial because Read Any Reg op used in SMPT takes 3- or 4-byte address depending on current address mode. The current address mode is found in CFR2V[7] but CFR2V can be read by Read Any Reg op (chicken-and-egg). This patch introduce a way to discover the current address mode by using on-die CRC feature in Infineon SEMPER family. The data integrity CRC (on-die CRC) calculation is conducted by issuing a specific command followed by start and end addresses on which CRC is calculated. The flash becomes busy state during calculation so we need to poll status and wait for the completion. The calculated CRC value is stored in Data Integrity Check CRC registers (DCRV) and can be read by Read Any Reg op. We can try with 3- and 4-byte addresses to read DCRV then compare it with expected CRC value calculated by offline. Both CRC should match only when we perform Read Any Reg op with correct number of address bytes. The offline CRC calculation is done by CRC32C algorithm with 0x1edc6f41 polynomial. The data is read by READ_4B (13h) opcode. BFPT DWORD16 is used to determine factory default of address mode, assuming factory default is 3-byte in case power cycle exits 4-byte address mode. Signed-off-by: Takahiro Kuwano --- drivers/mtd/spi-nor/sfdp.h | 1 + drivers/mtd/spi-nor/spansion.c | 130 +++++++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+) diff --git a/drivers/mtd/spi-nor/sfdp.h b/drivers/mtd/spi-nor/sfdp.h index bbf80d2990ab..d7e1620bd870 100644 --- a/drivers/mtd/spi-nor/sfdp.h +++ b/drivers/mtd/spi-nor/sfdp.h @@ -90,6 +90,7 @@ struct sfdp_bfpt { #define BFPT_DWORD15_QER_SR2_BIT1_NO_RD (0x4UL << 20) #define BFPT_DWORD15_QER_SR2_BIT1 (0x5UL << 20) /* Spansion */ +#define BFPT_DWORD16_EX4B_PWRCYC BIT(21) #define BFPT_DWORD16_SWRST_EN_RST BIT(12) #define BFPT_DWORD18_CMD_EXT_MASK GENMASK(30, 29) diff --git a/drivers/mtd/spi-nor/spansion.c b/drivers/mtd/spi-nor/spansion.c index 676ffd6d12ec..8ed4b2d53403 100644 --- a/drivers/mtd/spi-nor/spansion.c +++ b/drivers/mtd/spi-nor/spansion.c @@ -23,7 +23,9 @@ #define SPINOR_REG_CYPRESS_CFR5V 0x00800006 #define SPINOR_REG_CYPRESS_CFR5V_OCT_DTR_EN 0x3 #define SPINOR_REG_CYPRESS_CFR5V_OCT_DTR_DS 0 +#define SPINOR_REG_CYPRESS_DCRV 0x00800095 #define SPINOR_OP_CYPRESS_RD_FAST 0xee +#define SPINOR_OP_CYPRESS_DI_CRC 0x5b /* Cypress SPI NOR flash operations. */ #define CYPRESS_NOR_WR_ANY_REG_OP(naddr, addr, ndata, buf) \ @@ -213,11 +215,139 @@ static int cypress_nor_set_page_size(struct spi_nor *nor) return 0; } +#define CRC32C_POLY 0x1edc6f41 +static u32 cypress_nor_calc_crc32c(u32 len, u8 *buf) +{ + u32 crc = 0; + int i; + + while (len--) { + crc ^= *buf++ << 24; + for (i = 0; i < 8; i++) + crc = (crc << 1) ^ ((crc & 0x80000000) ? CRC32C_POLY : + 0); + } + + return crc; +} + +static int cypress_nor_data_integrity_crc(struct spi_nor *nor, u32 addr, + u32 len) +{ + struct spi_mem_op op = + SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_CYPRESS_DI_CRC, 0), + SPI_MEM_OP_ADDR(4, addr, 0), + SPI_MEM_OP_NO_DUMMY, + SPI_MEM_OP_DATA_OUT(4, nor->bouncebuf, 0)); + u32 end_addr = addr + len - 1; + int ret; + + nor->bouncebuf[0] = (end_addr >> 24) & 0xff; + nor->bouncebuf[1] = (end_addr >> 16) & 0xff; + nor->bouncebuf[2] = (end_addr >> 8) & 0xff; + nor->bouncebuf[3] = end_addr & 0xff; + + spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); + + ret = spi_mem_exec_op(nor->spimem, &op); + if (ret) + return ret; + + return spi_nor_wait_till_ready(nor); +} + +/** + * cypress_nor_verify_crc() - Compare CRC and data integrity CRC registers. + * @nor: pointer to 'struct spi_nor'. + * @addr_nbytes: number of address bytes used in Read Any Reg op + * @crc: CRC value to compare with registers + * + * Return: 1 if match, 0 if not match, -errno on errors. + */ +static int cypress_nor_verify_crc(struct spi_nor *nor, u8 addr_nbytes, u32 crc) +{ + struct spi_mem_op op = + CYPRESS_NOR_RD_ANY_REG_OP(addr_nbytes, + SPINOR_REG_CYPRESS_DCRV, + nor->bouncebuf); + int i, ret; + + for (i = 0; i < 4; i++) { + ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto); + if (ret) + return ret; + + if ((crc & 0xff) != nor->bouncebuf[0]) + return 0; + + crc >>= 8; + op.addr.val++; + } + + return 1; +} + +static int cypress_nor_discover_addr_mode(struct spi_nor *nor) +{ + u32 addr = 0; + u32 len = 4; + u32 crc; + u8 addr_nbytes; + int ret; + + /* Read flash memory array */ + ret = spi_nor_alt_read(nor, addr, len, nor->bouncebuf, + SPINOR_OP_READ_4B, 4, 0); + if (ret) + return ret; + + /* Calculate CRC32C of read data */ + crc = cypress_nor_calc_crc32c(len, nor->bouncebuf); + + /* Perform on-die CRC calculation */ + ret = cypress_nor_data_integrity_crc(nor, addr, len); + if (ret) + return ret; + + /* Read and verify CRC registers with current addr_mode_nbytes */ + ret = cypress_nor_verify_crc(nor, nor->params->addr_mode_nbytes, crc); + if (ret < 0) + return ret; + if (ret) + return 0; + + /* Read and verify CRC registers with another number of address bytes */ + addr_nbytes = nor->params->addr_mode_nbytes == 3 ? 4 : 3; + ret = cypress_nor_verify_crc(nor, addr_nbytes, crc); + if (ret < 0) + return ret; + if (ret) + nor->params->addr_mode_nbytes = addr_nbytes; + else + dev_warn(nor->dev, "Failed to discover current address mode. Assuming default %d-byte.\n", + nor->params->addr_mode_nbytes); + + return 0; +} + static int s25hx_t_post_bfpt_fixup(struct spi_nor *nor, const struct sfdp_parameter_header *bfpt_header, const struct sfdp_bfpt *bfpt) { + int ret; + + /* + * Discover flash's current address mode. Determine factory default + * address mode in advance by checking if power cycle exits 4-byte + * address mode, meaning factory default is 3-byte. + */ + nor->params->addr_mode_nbytes = + bfpt->dwords[BFPT_DWORD(16)] & BFPT_DWORD16_EX4B_PWRCYC ? 3 : 4; + ret = cypress_nor_discover_addr_mode(nor); + if (ret) + return ret; + /* Replace Quad Enable with volatile version */ nor->params->quad_enable = cypress_nor_quad_enable_volatile;