From patchwork Thu May 6 19:18:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 1475232 X-Patchwork-Delegate: vigneshr@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2001:8b0:10b:1:d65d:64ff:fe57:4e05; helo=desiato.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=desiato.20200630 header.b=elulkz2I; dkim=fail reason="signature verification failed" (2048-bit key; secure) header.d=infradead.org header.i=@infradead.org header.a=rsa-sha256 header.s=bombadil.20210309 header.b=wH0e1u8W; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=fXEfgEIO; dkim-atps=neutral Received: from desiato.infradead.org (desiato.infradead.org [IPv6:2001:8b0:10b:1:d65d:64ff:fe57:4e05]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Fbk3w0tc2z9sCD for ; Fri, 7 May 2021 05:22:20 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=desiato.20200630; 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=PIZR/XG8D2P+ZYAq8uy/CxeuqidmLs8wC/44e58ka8g=; b=elulkz2IiVqczmxBWcyX665O1 nC8naagwCfllwpBWuXU0Usi4tbLja51UO28SfkIrnWizcW3Fz+Wq2CC3N2YU73sxj6MvyXAEUA+Je I/P1QcSwHCTukVQ64LGbw3Pqe8wh+44G+CMxt5E9VkNrVYKU50/BTRJKCIyEYWUib5CaFAZdM4N3/ +QQnaC90ZZtZntIxqTjzuYiJUb5LraTTz8i7cStnGQfIl53a8E3meUsBm8377C4QXEodIqa32vHn4 owdPsAMEdgf+qkx4yMlf8lxP4sI54hmT7xunAKK03l1Gsp15Wdv2K4hzwWiwx31XtlymA9m/LBDUM OGAvwixCw==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lejZ5-0058Hv-Jx; Thu, 06 May 2021 19:21:39 +0000 Received: from bombadil.infradead.org ([2607:7c80:54:e::133]) by desiato.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lejWV-0057b9-Pk for linux-mtd@desiato.infradead.org; Thu, 06 May 2021 19:19:00 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Type: Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID:Date :Subject:CC:To:From:Sender:Reply-To:Content-ID:Content-Description; bh=8be/0Af1IpsSbPbMx0rjRmaqUa0F13Ayu7NXc7jIJ5U=; b=wH0e1u8W6iGU4oPZ7vLgYJXwR6 xJ4myjF1jPP2eMcNOgqxsFy2GTaK2MTsmBLZWUPQ3j2tPA9ZoA751y8vcYOOhLJ6RNX19f4Q9OBfx 2Jolc+F5x6FWixLCf1vAB8Hl5izTG9iPQAyQklgj8Xu7FZJM9m3/tCDvI+6WZl4qzMpothvK33FvN ELsC4xRApcwGpAslVpytfaYUrgtdB0AecZfvK0SGUEQHyyfQufNzPy4PQrPDSG3ysTGxVAbzYQ/pc 1rXdLyv2lcsu3FWM72a9PGkcxIqnFJdxim1/ArEXgUQNn1yxBP2l7BqQOelP9uRlQpGwZKqv0bldc IJJ2xh1A==; Received: from fllv0016.ext.ti.com ([198.47.19.142]) by bombadil.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lejWT-006KjC-2U for linux-mtd@lists.infradead.org; Thu, 06 May 2021 19:18:58 +0000 Received: from lelv0266.itg.ti.com ([10.180.67.225]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 146JIrtm095439; Thu, 6 May 2021 14:18:53 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1620328733; bh=8be/0Af1IpsSbPbMx0rjRmaqUa0F13Ayu7NXc7jIJ5U=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=fXEfgEIO/PaTEximsML7s0b3WQLojA5BosbU+/BmtezABdJ1Bd68BZJTkenl6BMWy +Tqiu8duTAJpOimBls2YKZ07yUUP7yS1+Fmr5hrdJp3VGU+Fsd7E4pgkdaG/3ieQQT 2ElzA1nVflaK+EEM7lt78lVe1xXw0vwuwE/rWpIY= Received: from DFLE108.ent.ti.com (dfle108.ent.ti.com [10.64.6.29]) by lelv0266.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 146JIre1016678 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 6 May 2021 14:18:53 -0500 Received: from DFLE110.ent.ti.com (10.64.6.31) by DFLE108.ent.ti.com (10.64.6.29) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2176.2; Thu, 6 May 2021 14:18:53 -0500 Received: from lelv0326.itg.ti.com (10.180.67.84) by DFLE110.ent.ti.com (10.64.6.31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2176.2 via Frontend Transport; Thu, 6 May 2021 14:18:53 -0500 Received: from pratyush-OptiPlex-790.dhcp.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by lelv0326.itg.ti.com (8.15.2/8.15.2) with ESMTP id 146JIUNI026052; Thu, 6 May 2021 14:18:50 -0500 From: Pratyush Yadav To: Tudor Ambarus , Michael Walle , Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Mark Brown , , , CC: Pratyush Yadav Subject: [PATCH 6/6] mtd: spi-nor: core; avoid odd length/address writes in 8D-8D-8D mode Date: Fri, 7 May 2021 00:48:29 +0530 Message-ID: <20210506191829.8271-7-p.yadav@ti.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210506191829.8271-1-p.yadav@ti.com> References: <20210506191829.8271-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210506_121857_218100_B960EEC7 X-CRM114-Status: GOOD ( 19.72 ) X-Spam-Score: -2.8 (--) 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: On Octal DTR capable flashes like Micron Xcella the writes cannot start or end at an odd address in Octal DTR mode. Extra 0xff bytes need to be appended or prepended to make sure the start address and [...] Content analysis details: (-2.8 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [198.47.19.142 listed in list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 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 -0.3 DKIMWL_WL_HIGH DKIMwl.org - High trust sender 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 On Octal DTR capable flashes like Micron Xcella the writes cannot start or end at an odd address in Octal DTR mode. Extra 0xff bytes need to be appended or prepended to make sure the start address and end address are even. 0xff is used because on NOR flashes a program operation can only flip bits from 1 to 0, not the other way round. 0 to 1 flip needs to happen via erases. Signed-off-by: Pratyush Yadav --- drivers/mtd/spi-nor/core.c | 72 +++++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 3d66cc34af4d..265d8b25fc7f 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -2022,6 +2022,71 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len, return ret; } +/* + * On Octal DTR capable flashes like Micron Xcella the writes cannot start or + * end at an odd address in Octal DTR mode. Extra 0xff bytes need to be appended + * or prepended to make sure the start address and end address are even. 0xff is + * used because on NOR flashes a program operation can only flip bits from 1 to + * 0, not the other way round. 0 to 1 flip needs to happen via erases. + */ +static int spi_nor_octal_dtr_write(struct spi_nor *nor, loff_t to, size_t len, + const u8 *buf) +{ + u8 *tmp_buf; + size_t bytes_written; + loff_t start, end; + int ret; + + if (IS_ALIGNED(to, 2) && IS_ALIGNED(len, 2)) + return spi_nor_write_data(nor, to, len, buf); + + tmp_buf = kmalloc(nor->page_size, GFP_KERNEL); + if (!tmp_buf) + return -ENOMEM; + + memset(tmp_buf, 0xff, nor->page_size); + + start = round_down(to, 2); + end = round_up(to + len, 2); + + memcpy(tmp_buf + (to - start), buf, len); + + ret = spi_nor_write_data(nor, start, end - start, tmp_buf); + if (ret == 0) { + ret = -EIO; + goto out; + } + if (ret < 0) + goto out; + + /* + * More bytes are written than actually requested, but that number can't + * be reported to the calling function or it will confuse its + * calculations. Calculate how many of the _requested_ bytes were + * written. + */ + bytes_written = ret; + + if (to != start) + ret -= to - start; + + /* + * Only account for extra bytes at the end if they were actually + * written. For example, if for some reason the controller could only + * complete a partial write then the adjustment for the extra bytes at + * the end is not needed. + */ + if (start + bytes_written == end) + ret -= end - (to + len); + + if (ret < 0) + ret = -EIO; + +out: + kfree(tmp_buf); + return ret; +} + /* * Write an address range to the nor chip. Data must be written in * FLASH_PAGESIZE chunks. The address range may be any size provided @@ -2066,7 +2131,12 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len, if (ret) goto write_err; - ret = spi_nor_write_data(nor, addr, page_remain, buf + i); + if (nor->write_proto == SNOR_PROTO_8_8_8_DTR) + ret = spi_nor_octal_dtr_write(nor, addr, page_remain, + buf + i); + else + ret = spi_nor_write_data(nor, addr, page_remain, + buf + i); if (ret < 0) goto write_err; written = ret;