From patchwork Mon Sep 14 03:01:07 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3314 Return-Path: X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from tor.lore.kernel.org (tor.lore.kernel.org [172.105.105.114]) by mxe881.netcup.net (Postfix) with ESMTPS id B76331C344A for ; Mon, 14 Sep 2026 05:02:12 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=gmail.com; spf=pass (sender IP is 172.105.105.114) smtp.mailfrom=linux-sunxi+bounces-25875-noreply=patchwork.local@lists.linux.dev smtp.helo=tor.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 172.105.105.114 as permitted sender) client-ip=172.105.105.114; envelope-from=linux-sunxi+bounces-25875-noreply=patchwork.local@lists.linux.dev; helo=tor.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by tor.lore.kernel.org (Postfix) with ESMTP id 18B18293C1 for ; Mon, 14 Sep 2026 03:01:49 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 6C7B833B6E8; Mon, 14 Sep 2026 03:01:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="bIhA+XoX" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-oo2-f42.google.com (mail-oo2-f42.google.com [74.125.231.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 82A1333064D for ; Mon, 14 Sep 2026 03:01:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.231.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789354902; cv=none; b=piA6ECjRcdwuxcihvF+sRSOGxoWxq1HdM85vPnxUFLWxl6Hd3CvSgK/gebBTUFtkRmXwTEV5PHxfXea0uQd0s10+Zy1r+6Y1swtp7s3gsDDtKaNmDJIwzjSLGxCP8Beaz8iuAxMgNKEYQKq/UkbPw2A1KsXEC+3wwweP8CDqwHI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789354902; c=relaxed/simple; bh=Lpu8BYiYZNteYXFlDSxlBr4C2CnU/Gx0SiTFgcn6nP0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=TeO6nJpikK9ThOcGxIeTWLmkEmfTm7552Wy4J/P3gIkLPEOfJPCjYNwEZy4J+j85Pw4BTshhu1/eNgT/SOwxqelBZBhsnrBRwcAFMmeXvnwM/SrcthjThJw0hr4ZOtzjg5YkLBZeJ/RJjpCuNBEK/OKIF8THjvIRkW8etPflqLY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=bIhA+XoX; arc=none smtp.client-ip=74.125.231.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-oo2-f42.google.com with SMTP id 46e09a7af769-804e42309a5so401704a34.2 for ; Sun, 13 Sep 2026 20:01:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789354898; x=1789959698; darn=lists.linux.dev; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=EsI+dpw6vMR742jYDR1gddCVyVHs7LTF48bPd8UEx9g=; b=bIhA+XoXMa6uhScm3zhnY14sZm1Gwa4r9eKQH9/oz6BWeA02PTPsSbL/lh9YTuOGT5 E6ovSfJ1Kd4Hnko/8YxZBzqym72zd030BmaRgAWhg7JEltZrIRf3iUFEtgzMZsGi6R/K pzrlZWUpEETm1Y0V/MK+WTzzbzBl/sxPxnGDRJkD+6i5SJ87kgk98POguiDZ19YiOE8w vO/AEQuQAgtKMFrM+X9N41fI2cBwjucgYhuky9HAI+6Jo1eFmmZfLDpgfWG02WGvlbbn YZ0xphmQhbaI05ikFZE0G8k6+kj50oVlpnQt67GAw/UT7auEizlGl8UleBWY+8H5hAk5 zGOg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789354898; x=1789959698; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=EsI+dpw6vMR742jYDR1gddCVyVHs7LTF48bPd8UEx9g=; b=mBI+MHCWmE7FQ/GL9NKxuQWvIDKqBrIB2+lXJ8y9ICRwgqvMzM3NwoybuYVwnZZrj/ lTW1JwIs8g7MvLqTq/JcClv+uNd7IHbsrqGvliFVfc92zxc0vyol9HeZsMbDWmqlWleW UY1q3iQm2kI2Bpe4IX+TDOOz9UBzD0+YFKgkVlucPE2RsdvjlWV/lLKaxszEXXvHZNKI 7Q6OH9wVOCVZykkh0K7fMWwuzG3cwvsX1GgoxUqJfi1CUTuHm9aeGrMwCN3T+sFyJ4v3 skPl2o7ArE4wkzUzhFty6mQKpXyhjUFFqVIv21QWu9FhjG36qM6Sgv44ouVUKpZ6iI/M Me6A== X-Forwarded-Encrypted: i=1; AKwUvBxbBwwvNcmnnqcBW66yno9zRzVHzlY53yzRuDadcq+5gScQHyTalhHML13dQyQWkklXpByUsgYdi/fmtQ==@lists.linux.dev X-Gm-Message-State: AFuF++n9QQ1aSbge4V05pkzWRG5pbe9REdkBGx+5+cABco1rSFjwJbrs SZgEqxHlJkyKlThzoNJOuotjmz7LrdZgOjyaawClLtXw2m4ary4Nnru7 X-Gm-Gg: AYBFou24CFVUhLf8Ndhq3tY1X0zUyy5Kfbf6a0t41Xp3bRNDBhHOKtNSSxKuuZ4I+M+ 0dtxwKKwKoDNRgnT45XSPiha3bSLligzNPEXemPmR+dfj4CbUndOKeg90EnSYKwh2rIoVMfiZEd aCSo9ZyPGeIygigeXr3chq1R8X0VyWQ+0sO45lvSMQ2AmGjq7HqGDfvXr65MBEsVmcpqGSi/wR5 kqS3u1abFEhf9kybson2D2nMa66yIkR0IsuttLcofz/N8U6Jjobx/uRabMFMTWMu4/R+cRpf1MI 1lPMRiB8bYyxRItuSKSlDsyvC2UAX1V+nRdV7LD66GlXeuHNEINe6Ne2nI+neDwzTNQ4Rp7fhye GGi8s8B+HnYRh14BWMLRAi2PeORwpd0np09t90YynomNgv7jFuh+UiZ6i/rHYHUJ5ja3Knwa+vD xCLTt1UEtVGVfHmAEZRdD2RgRalzihXYdAT1+yvxVFG23Wg4443cz9LRN7nfNNeqTDcy+6xI48A 7VG3lzSJOhINZB+4zHpDlI0MvV3XnDuziticYSSNBTh2v47deiyFvQOeUWMJGs5w3DhHsZGlAh5 QPcqKcH+16JbvuUbG+AyMXXgtAmF+xrY++Jjwq8rZB5138JEHfrXQCopWtm7qpj7ukKw9eQ2+Qy MWWrDsb3CA9CUP29z0g7Rmg5K3T/3iwSitE92f9+u X-Received: by 2002:a05:6830:81fb:b0:7fb:547f:98bc with SMTP id 46e09a7af769-80897394cd9mr261168a34.5.1789354898430; Sun, 13 Sep 2026 20:01:38 -0700 (PDT) Received: from [127.0.1.1] (184-96-157-145.hlrn.qwest.net. [184.96.157.145]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-803f60feba1sm10619014a34.13.2026.09.13.20.01.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 13 Sep 2026 20:01:37 -0700 (PDT) From: James Hilliard Date: Sun, 13 Sep 2026 21:01:07 -0600 Subject: [PATCH v5 01/18] mtd: rawnand: sunxi: drain interrupts before reusing the completion Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-1-7d711076a6f7@gmail.com> References: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-0-7d711076a6f7@gmail.com> In-Reply-To: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-0-7d711076a6f7@gmail.com> To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Maxime Ripard , Richard Genoud , Masahiro Yamada , Boris Brezillon , Brian Norris Cc: linux-mtd@lists.infradead.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, James Hilliard , stable@vger.kernel.org X-Mailer: b4 0.15.2 X-Rspamd-Server: rspamd-worker-8404 X-Spamd-Result: default: False [-1.16 / 15.00]; BAYES_HAM(-5.50)[100.00%]; RBL_SENDERSCORE(2.00)[172.105.105.114:from]; SUSPICIOUS_RECIPS(1.50)[]; DMARC_POLICY_SOFTFAIL(1.00)[gmail.com : SPF not aligned (relaxed), No valid DKIM,none]; MAILLIST(-0.15)[generic]; MIME_GOOD(-0.10)[text/plain]; BAD_REP_POLICIES(0.10)[]; HAS_LIST_UNSUB(-0.01)[]; PRECEDENCE_BULK(0.00)[]; FROM_HAS_DN(0.00)[]; DBL_BLOCKED_OPENRESOLVER(0.00)[tor.lore.kernel.org:rdns,tor.lore.kernel.org:helo]; TAGGED_RCPT(0.00)[dt]; FORGED_SENDER_MAILLIST(0.00)[]; FREEMAIL_CC(0.00)[lists.infradead.org,vger.kernel.org,lists.linux.dev,gmail.com]; RCPT_COUNT_TWELVE(0.00)[21]; RCVD_COUNT_FIVE(0.00)[6]; ASN(0.00)[asn:63949, ipnet:172.105.96.0/20, country:SG]; R_SPF_ALLOW(0.00)[+ip4:172.105.105.114]; FREEMAIL_TO(0.00)[bootlin.com,nod.at,ti.com,kernel.org,gmail.com,sholland.org,socionext.com]; FREEMAIL_FROM(0.00)[gmail.com]; TO_DN_SOME(0.00)[]; FROM_NEQ_ENVFROM(0.00)[jameshilliard1@gmail.com,linux-sunxi@lists.linux.dev]; FORGED_RECIPIENTS_MAILLIST(0.00)[]; RCVD_TLS_LAST(0.00)[]; TAGGED_FROM(0.00)[bounces-25875-noreply=patchwork.local]; MIME_TRACE(0.00)[0:+]; MID_RHS_MATCH_FROM(0.00)[]; ARC_ALLOW(0.00)[subspace.kernel.org:s=arc-20240116:i=1]; RCVD_VIA_SMTP_AUTH(0.00)[] X-Rspamd-Queue-Id: B76331C344A X-MORS-Enabled: yes X-MORS-DOMAIN: patchwork.local X-MORS-HOSTING: hosting172546 X-MORS-USER: hosting172546 X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= A timed-out wait can return while the interrupt handler is still using the previous operation's interrupt status and enable mask. Starting the next wait calls init_completion() on the same object, which can reset its waitqueue lock while the old handler calls complete(). The old handler can also complete the new wait or restore an obsolete interrupt mask. Initialize the completion once in probe and use reinit_completion() for each interrupt-driven wait. On timeout, disable and synchronize the IRQ before masking controller interrupts and acknowledging the waited-for events. Draining the handler first also prevents a partial-event handler from rewriting the enable mask after it has been cleared. Flush these register writes before re-enabling the IRQ line, leaving the controller's interrupt sources masked. For successful waits, move complete() after the handler's register updates so that the next operation cannot race with those updates. Keep polling unchanged and leave controller and DMA abort handling to the existing callers. Fixes: 1fef62c1423b ("mtd: nand: add sunxi NAND flash controller support") Cc: stable@vger.kernel.org Signed-off-by: James Hilliard --- drivers/mtd/nand/raw/sunxi_nand.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index f41feebe4257..e50cf5b6a730 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -374,6 +374,7 @@ struct sunxi_nfc_caps { * @chips: a list containing all the NAND chips attached to this NAND * controller * @complete: a completion object used to wait for NAND controller events + * @irq: NAND controller interrupt * @dmac: the DMA channel attached to the NAND controller * @use_mdma: use an internal MBUS DMA backend * @mdma_desc: H6-style MBUS DMA descriptor @@ -393,6 +394,7 @@ struct sunxi_nfc { unsigned long clk_rate; struct list_head chips; struct completion complete; + int irq; struct dma_chan *dmac; bool use_mdma; struct sunxi_nfc_mdma_desc *mdma_desc; @@ -414,12 +416,13 @@ static irqreturn_t sunxi_nfc_interrupt(int irq, void *dev_id) if (!(ien & st)) return IRQ_NONE; - if ((ien & st) == ien) - complete(&nfc->complete); - + /* Finish updating the interrupt state before waking the next operation. */ writel(st & NFC_INT_MASK, nfc->regs + NFC_REG_ST); writel(~st & ien & NFC_INT_MASK, nfc->regs + NFC_REG_INT); + if ((ien & st) == ien) + complete(&nfc->complete); + return IRQ_HANDLED; } @@ -435,16 +438,19 @@ static int sunxi_nfc_wait_events(struct sunxi_nfc *nfc, u32 events, timeout_ms = NFC_DEFAULT_TIMEOUT_MS; if (!use_polling) { - init_completion(&nfc->complete); + reinit_completion(&nfc->complete); writel(events, nfc->regs + NFC_REG_INT); ret = wait_for_completion_timeout(&nfc->complete, msecs_to_jiffies(timeout_ms)); - if (!ret) + if (!ret) { + /* Drain the handler before it can restore an old IRQ mask. */ + disable_irq(nfc->irq); ret = -ETIMEDOUT; - else + } else { ret = 0; + } writel(0, nfc->regs + NFC_REG_INT); } else { @@ -457,6 +463,12 @@ static int sunxi_nfc_wait_events(struct sunxi_nfc *nfc, u32 events, writel(events & NFC_INT_MASK, nfc->regs + NFC_REG_ST); + if (!use_polling && ret) { + /* Flush the mask and acknowledgment before re-enabling the IRQ. */ + readl(nfc->regs + NFC_REG_INT); + enable_irq(nfc->irq); + } + if (ret) dev_err(nfc->dev, "wait interrupt timedout\n"); @@ -2617,6 +2629,7 @@ static int sunxi_nfc_probe(struct platform_device *pdev) nfc->dev = dev; nand_controller_init(&nfc->controller); INIT_LIST_HEAD(&nfc->chips); + init_completion(&nfc->complete); nfc->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &r); if (IS_ERR(nfc->regs)) @@ -2625,6 +2638,7 @@ static int sunxi_nfc_probe(struct platform_device *pdev) irq = platform_get_irq(pdev, 0); if (irq < 0) return irq; + nfc->irq = irq; nfc->caps = of_device_get_match_data(dev); if (!nfc->caps) From patchwork Mon Sep 14 03:01:08 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3315 Return-Path: X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from tor.lore.kernel.org (tor.lore.kernel.org [172.105.105.114]) by mxe881.netcup.net (Postfix) with ESMTPS id 563941C3EF9 for ; Mon, 14 Sep 2026 05:02:18 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=gmail.com; spf=pass (sender IP is 172.105.105.114) smtp.mailfrom=linux-sunxi+bounces-25876-noreply=patchwork.local@lists.linux.dev smtp.helo=tor.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 172.105.105.114 as permitted sender) client-ip=172.105.105.114; envelope-from=linux-sunxi+bounces-25876-noreply=patchwork.local@lists.linux.dev; helo=tor.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by tor.lore.kernel.org (Postfix) with ESMTP id 0CEFC299B9 for ; Mon, 14 Sep 2026 03:01:50 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id C41803346BE; Mon, 14 Sep 2026 03:01:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="GmoS9AJ0" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-oo2-f40.google.com (mail-oo2-f40.google.com [74.125.231.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D6A1230D406 for ; Mon, 14 Sep 2026 03:01:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.231.168 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789354903; cv=none; b=qh29CfCnGnijdYksOTqbQ827uA/A4m4wsXTgr+dgBplmBFyX/c7eEnMswGelTdb+WRMsvrNvEKnJS3xW8FKFUbv/qY2NZbFtK6rs9tU3n9+LfB6AeGZ3kHy3yHX8oS4la4Ga011IFLA2+0LRUiCc/ZHEWFSu9Z7hsafiSscFfrI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789354903; c=relaxed/simple; bh=QNBt+pFeHHzCr6qyz6aRzEV+o3fccMFb5SqOxfos0lA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=aUQgNbIF8Rnaq3S/pj84zTPqGeCElQcxtl2GzTOYNHGf5N4wVULf422xGRRL18rcud1aJ7lfIZ/7zXJIIGh53YMPl/EdyFTrJK5Vkq+FnoLLqcv/cvePXvEufE97GMlGYenV3Sh6wYzhZM1DKxJnwvptRmRpSY68V9KKBeJkgLs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=GmoS9AJ0; arc=none smtp.client-ip=74.125.231.168 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-oo2-f40.google.com with SMTP id 46e09a7af769-805c194bc92so1207136a34.1 for ; Sun, 13 Sep 2026 20:01:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789354900; x=1789959700; darn=lists.linux.dev; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=Z2QJ/YfTCDyKu7jznVj9GPPyAB75HsBI8sl5USMlUvk=; b=GmoS9AJ0gyGX1kNVm/Mp633ZJSzn3Ktd9bW3cRPYcu5SadktR/DTRS5gWtFpqjkgAw 6ecJHxqenaPCnv89aadc4RPty0/pny501Z2cZtQdC8ZXATmZFPrT5NlLmZFPRYCG/Wk6 Dfg7LdBXqvo3TZq7b8OiQpV7G+xZn674Mv5YxjX8X4TrGNKPmBZ3UZ1kg2qE7VXWUG9O 8W5+mcpjMYs4fkzBc2Vg6W17Lt+F7TNfOavlLobP0AseTAn4VZk3Yc+mCTW1EwmyUgnn qKcRppXvNN9h7JIqcmC71NM91iZMXzYD/ISucuIZbfMxws3TxU0eOp20nqzQqpJDMQTm Z03w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789354900; x=1789959700; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=Z2QJ/YfTCDyKu7jznVj9GPPyAB75HsBI8sl5USMlUvk=; b=dOTppKAtTbQb8BzCZsj4t0UH02B5/RG4lzxZqy14KbRG6C7WmrVN6cJ04rOsJFMyEk EhWiQTvD9m4EDtWko65J40dQjVftcyuY5+leQVBoXax634F9I621H7hsIT1Q7fuzodlg S2XyVtiwe/KGIEWBaTSJi1bFjcZ20OFKZrRE++lo7fxjZe2exylQzLFRLGL7lqoPsPS5 lKj4v5I8mal52inmB6j/cVU5i75WQdQ/BvC7ofecx1eyVzh6loMOfnBHJ+nOksV1KrE9 LshmItx5COIn/z1nMBBTi4A/glDOzrxNc+iHujn89D9OTNiHrc6BCjD6NsGpnozwNJks xI/Q== X-Forwarded-Encrypted: i=1; AKwUvBw9K9jlyTQ7syFDkQpFELQLLyPrH2+Qld//L9vPk3jF7R/F+zf05sUBIBu03w84uehxWKm1NVaRZX0e8w==@lists.linux.dev X-Gm-Message-State: AFuF++kkZSzTBrXN8A2DyReWKLXQv0SeAtFHN4Fdc7DkCtoyN1tKN5Li c2OtfqQPwbdN0ZfxHaz2OBss5XYp03ucLEtwQ3vWAJwrqRmpo2KJPSaT X-Gm-Gg: AYBFou1m2Sm7i3DO5dOkmLnJIpVzRddrOJQ97qUqxYdoMlshw6y9d4yEQ7PQ0cYliY1 84pcJjNpwYHEY08DXPAOUKlLWR2nkr0lnhkLKR8BcnuiJPLg1cPy9Tv6CPpKv6Uu6/i3ch8NMdd +VD1uDn8xI2dgGnLzwdtnXa791PjKaYHKwkBBbERCR1NUm2klwGN9PD9nnCZiDLyWRq6Peo9CpE aF1o3b3GhrVPrySyWdPCzWQ5CXUrx9J1QCCgXGkWBWDMnI856suVjXS9Kpq9EOZ0fw5LFTbnD9v tvF+Vk9cJAwFCYUJBYhndTXCU6F1UUFNyYCGcqc6axm9JI4RZ64rJcn9mj8tvQfp/7z3PV9KSGf IyPgJjSmrdzmQjQiuGJvlaWsNn9ppSRSRukV4rKM7ryv4zZxKVtZp4nkAIBZhYd9WtlFvyTvp/R yVVfA4C2/q9NJIMN6xnmtkWeDS+nMDoDlP2wBz3vSku1o1suO48HbyOwyRZuHw6nHfevJRDF19C 8DPLOGRVSacx8APUuSzS/8khnTfaI6fPSkAUi9JcFB+7l6Cicw9Z9+NMEQsR2I74N9q2nemPl6p VsuB3g3ph2MTt3n6PcpNly3XVsxQhi6W4qrbI7TRCm/M2kbAXaXbi6EkBoBdrFP/bBpcujreciJ pvZcaZmhMVEyMC6RmuZFiyVYLfMr0Kt8= X-Received: by 2002:a05:6830:3892:b0:7f8:4ac8:bd2a with SMTP id 46e09a7af769-80899a529a4mr493322a34.12.1789354899758; Sun, 13 Sep 2026 20:01:39 -0700 (PDT) Received: from [127.0.1.1] (184-96-157-145.hlrn.qwest.net. [184.96.157.145]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-803f60feba1sm10619014a34.13.2026.09.13.20.01.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 13 Sep 2026 20:01:39 -0700 (PDT) From: James Hilliard Date: Sun, 13 Sep 2026 21:01:08 -0600 Subject: [PATCH v5 02/18] mtd: rawnand: sunxi: use the logical step's OOB length in PIO Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-2-7d711076a6f7@gmail.com> References: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-0-7d711076a6f7@gmail.com> In-Reply-To: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-0-7d711076a6f7@gmail.com> To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Maxime Ripard , Richard Genoud , Masahiro Yamada , Boris Brezillon , Brian Norris Cc: linux-mtd@lists.infradead.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, James Hilliard , stable@vger.kernel.org X-Mailer: b4 0.15.2 X-MORS-Enabled: yes X-MORS-DOMAIN: patchwork.local X-MORS-HOSTING: hosting172546 X-MORS-USER: hosting172546 X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= PIO transfers always use hardware ECC slot zero, even when transferring a later logical step. The user-data length programmed into that slot can differ from the first step's length on H6/H616 controllers. The ECC correction and protected-OOB write helpers instead derive the length from the hardware slot. Pattern handling can consequently fill beyond the current step's OOB region, including beyond the page's OOB buffer for its last step. Writes can also fetch bytes outside the current step's protected user data. Pass the logical step's user-data length to both helpers, as the protected OOB read helper already does. Keep the hardware slot for register access. DMA callers pass their existing per-step length, without changing the on-flash layout. Fixes: 54dcd6aa69db ("mtd: rawnand: sunxi: introduce maximize variable user data length") Cc: stable@vger.kernel.org Signed-off-by: James Hilliard --- drivers/mtd/nand/raw/sunxi_nand.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index e50cf5b6a730..172c7c4b0ba6 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -1011,11 +1011,11 @@ static void sunxi_nfc_set_user_data_len(struct sunxi_nfc *nfc, static void sunxi_nfc_hw_ecc_set_prot_oob_bytes(struct nand_chip *nand, const u8 *oob, int step, - bool bbm, int page) + bool bbm, int page, + unsigned int user_data_sz) { struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); - unsigned int user_data_sz = sunxi_nfc_user_data_sz(sunxi_nand, step); u8 user_data[SUNXI_NFC_MAX_USER_DATA_SZ] = {}; /* Randomize the Bad Block Marker. */ @@ -1069,11 +1069,9 @@ static void sunxi_nfc_hw_ecc_update_stats(struct nand_chip *nand, static int sunxi_nfc_hw_ecc_correct(struct nand_chip *nand, u8 *data, u8 *oob, int step, u32 status, u32 pattern_found, - bool *erased) + unsigned int user_data_sz, bool *erased) { struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); - struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); - unsigned int user_data_sz = sunxi_nfc_user_data_sz(sunxi_nand, step); struct nand_ecc_ctrl *ecc = &nand->ecc; u32 tmp; @@ -1155,7 +1153,7 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct nand_chip *nand, ret = sunxi_nfc_hw_ecc_correct(nand, data, oob_required ? oob : NULL, nfc_step, readl(nfc->regs + NFC_REG_ECC_ST), - pattern_found, &erased); + pattern_found, user_data_sz, &erased); if (erased) return 1; @@ -1323,7 +1321,7 @@ static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, uint8_t *buf ret = sunxi_nfc_hw_ecc_correct(nand, randomized ? data : NULL, oob_required ? oob : NULL, i, status, pattern_found, - &erased); + user_data_sz, &erased); /* ECC errors are handled in the second loop. */ if (ret < 0) @@ -1420,7 +1418,8 @@ static int sunxi_nfc_hw_ecc_write_chunk(struct nand_chip *nand, sunxi_nfc_randomizer_config(nand, page, false); sunxi_nfc_randomizer_enable(nand); sunxi_nfc_set_user_data_len(nfc, user_data_sz, nfc_step); - sunxi_nfc_hw_ecc_set_prot_oob_bytes(nand, oob, nfc_step, bbm, page); + sunxi_nfc_hw_ecc_set_prot_oob_bytes(nand, oob, nfc_step, bbm, page, + user_data_sz); writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | NFC_ACCESS_DIR | NFC_ECC_OP, @@ -1684,7 +1683,8 @@ static int sunxi_nfc_hw_ecc_write_page_dma(struct nand_chip *nand, int oob_off = sunxi_get_oob_offset(sunxi_nand, ecc, i); const u8 *oob = nand->oob_poi + oob_off; - sunxi_nfc_hw_ecc_set_prot_oob_bytes(nand, oob, i, !i, page); + sunxi_nfc_hw_ecc_set_prot_oob_bytes(nand, oob, i, !i, page, + user_data_sz); sunxi_nfc_set_user_data_len(nfc, user_data_sz, i); } From patchwork Mon Sep 14 03:01:09 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3316 Return-Path: X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from tor.lore.kernel.org (tor.lore.kernel.org [172.105.105.114]) by mxe881.netcup.net (Postfix) with ESMTPS id 3A8281C2BD4 for ; Mon, 14 Sep 2026 05:02:47 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=gmail.com; spf=pass (sender IP is 172.105.105.114) smtp.mailfrom=linux-sunxi+bounces-25877-noreply=patchwork.local@lists.linux.dev smtp.helo=tor.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 172.105.105.114 as permitted sender) client-ip=172.105.105.114; envelope-from=linux-sunxi+bounces-25877-noreply=patchwork.local@lists.linux.dev; helo=tor.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by tor.lore.kernel.org (Postfix) with ESMTP id 430CE2DA02 for ; Mon, 14 Sep 2026 03:01:56 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id E8AAE3403E7; Mon, 14 Sep 2026 03:01:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="c6FcD95I" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-oo2-f42.google.com (mail-oo2-f42.google.com [74.125.231.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 82B70330659 for ; Mon, 14 Sep 2026 03:01:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.231.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789354906; cv=none; b=rNPAnA8JTO4X0vrbgbWt50fa6RGJ4Q82kjl/dBNJI71kqp12I+Q8RURf/8JZvtJhS0+nFVZgZFoebdrQT2RZhmYOimDIX1XrkLZg51HWzKBNJrgl8dwnOci3WyzTSWbXtMLPFwltumx7Uw83073k7zUfz7vi+OksEYr9HhNAnTc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789354906; c=relaxed/simple; bh=sEgsacOGRde9P8OKLBN0PM1Bqnp+ZYDx65EvzcaNGcA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Mm4S0JyLPmaYEiVO1TBYznE4zl8VKjzcCyuXAJ9q2U9QAidsjvmcEpm6gUz69z63G1ABoND2g3ayyoZArj4R0r/QQKYEB1W43Uq5dcy+56k4oZ98COzXDFfN9ZPuUXYxneUMw6kLM4bDNFeAk788EwXsyAYLPSJ4nNQIhQU4pX4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=c6FcD95I; arc=none smtp.client-ip=74.125.231.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-oo2-f42.google.com with SMTP id 46e09a7af769-804f7045f3eso379657a34.2 for ; Sun, 13 Sep 2026 20:01:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789354901; x=1789959701; darn=lists.linux.dev; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=a95pnyMUuTP3EJOQCSW0InToPnlbmRSOMBXnRGDUxFk=; b=c6FcD95Icrt0S6B+MsCZnFysZ64CuTNdtYFVR1Bu4k6Db7oouIEfJqGyfiShLnMF+H 70G/vTlD7t2KzKnauGU/qNGQqCjFYeVBMDh7EHtI6EFNM3H3r8QMwrPQFKWV869zx3WX +wLI7UQtbJ/4OQ635FhcE9tMjDoKYYJgF9JLao1+LCZrXQEL3SQK4Lg2keESBRZtiECw jbYP20nDnadWSC97kY904w3rwiO56V6j358QVjOCrYU1BHWhQ8FjK1/Myv7w2J89Ym6v G5a5xODF51F+Hgi3a6Ie2kmpXrYO4vmVh1+BOpIUtSkh0vvvL/1bld9RlBiARfA8spzJ y4iQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789354901; x=1789959701; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=a95pnyMUuTP3EJOQCSW0InToPnlbmRSOMBXnRGDUxFk=; b=YPuPr0s8Br/GE3+69Ij/O9on46Eef4coKyfM0Abgm2bxHnMNvGjY/oH/mIFYbPsvTy TsIFr813PnimDgdMw3j0kSndo7sIYVov4PyU/5ZXDuZJaDCuXVe1v6K+OJKPSu/J70lF IiuRaIZvOj7SmWwqA8dxVXZTEVq3SSmwEFooimGYsV6lSBCq2cVLey3lbwWiSws+rFIH ZAPZG3byfi+6V2DukrSU+iNCMsVewWE7HckvfBg556zgxLCJnURYoUFtK2wofe5VySFZ 2yBtc6s6U2ZPGN6P1IwxvyjZrI5u8+nynFsgaRXB4rthgc/g09xiEMBo0uMK3XIXJ4qA ouEg== X-Forwarded-Encrypted: i=1; AKwUvBxVzsLd9TA1ppopN631JCZGAElHbbb1dSF0ZfAhorCzg0LoOyd4L77scaJeCdgVojIeka3RvZh+KRc5pg==@lists.linux.dev X-Gm-Message-State: AFuF++n9ZItQNfOMuDIQLI4+mJKXGZYGA8ZBCBmK+8cYYpKhGuTQCqMM 1KzmDjljwJ1zKJLdnT42P28q+9CRl1UyIFaziz67CxC6Pqrt68QPngzZ X-Gm-Gg: AYBFou2p4OQAnGdQJ1p7Da9u+QmaSU02/UXOe1RKJcZZEhEmfjxu+sdF97/x7ibJKdN tyAVEDCrlRkPQ/xResxKcAQ6obBG+XGxj5QHZ+8pib156I7dbwZlHe+SC6cNnC3wCOTOHn/rAJT KwLpejvvGjGT7H91emiKKyilApRKvUFre7jsPY5fgyw58ig70eCXLr5n7UPKI//iWWvJZVqw6hg 6VPda4nd/E24fenoh8w6RtVGvSS/135Hl/0pbm1iBmVzwGjt1MMiEAqp9hcrbuGh1ZLQjW7Tnjg GOA7wm0aDLlUPnmOSWGO4BxmHMOBroc3nzubk/dgXJzGFkdv38gPjvUK+sJGD60bCpf/Z06KBYu GXaWI4KDrXf6SpkLezcj2om0Me8nLj4NqkVw/CDoIsY13NV8Julrf1EdRlL9njh656OA1qNaQ2l O+qlLxmCRsc6zmMDQezEgsxQnkQ8udKXWZihevbx1Yrn1USl3z/jJlVp0deNfT/OmvMtmRqMfop NDIsXZH757yfA6E+TnTnsdP1RE0WVEI0NdoWOXH4IKwwgTR56Pqcrea+2emI83RRNR8ztksClTK 75GGCnmPnQdRUzPqSPoWQJ1bmFxZQh9UVrGw/gvu8bjz5gnvT2ERtCDFDUAsdyCKYnOJC+Lot4/ 4R6x+FqZp+/zNYaq/p1+0HI7WznCgqQ== X-Received: by 2002:a05:6830:2a8f:b0:802:68c:1b51 with SMTP id 46e09a7af769-8089798d600mr284960a34.11.1789354901016; Sun, 13 Sep 2026 20:01:41 -0700 (PDT) Received: from [127.0.1.1] (184-96-157-145.hlrn.qwest.net. [184.96.157.145]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-803f60feba1sm10619014a34.13.2026.09.13.20.01.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 13 Sep 2026 20:01:40 -0700 (PDT) From: James Hilliard Date: Sun, 13 Sep 2026 21:01:09 -0600 Subject: [PATCH v5 03/18] mtd: rawnand: sunxi: propagate page-setup and erased-check errors Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-3-7d711076a6f7@gmail.com> References: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-0-7d711076a6f7@gmail.com> In-Reply-To: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-0-7d711076a6f7@gmail.com> To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Maxime Ripard , Richard Genoud , Masahiro Yamada , Boris Brezillon , Brian Norris Cc: linux-mtd@lists.infradead.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, James Hilliard , stable@vger.kernel.org X-Mailer: b4 0.15.2 X-Rspamd-Server: rspamd-worker-8404 X-Spamd-Result: default: False [4.34 / 15.00]; RBL_SENDERSCORE(2.00)[172.105.105.114:from]; SUSPICIOUS_RECIPS(1.50)[]; DMARC_POLICY_SOFTFAIL(1.00)[gmail.com : SPF not aligned (relaxed), No valid DKIM,none]; MAILLIST(-0.15)[generic]; MIME_GOOD(-0.10)[text/plain]; BAD_REP_POLICIES(0.10)[]; HAS_LIST_UNSUB(-0.01)[]; PRECEDENCE_BULK(0.00)[]; RCPT_COUNT_TWELVE(0.00)[21]; FROM_HAS_DN(0.00)[]; DBL_BLOCKED_OPENRESOLVER(0.00)[tor.lore.kernel.org:rdns,tor.lore.kernel.org:helo]; TAGGED_RCPT(0.00)[dt]; FREEMAIL_CC(0.00)[lists.infradead.org,vger.kernel.org,lists.linux.dev,gmail.com]; FORGED_SENDER_MAILLIST(0.00)[]; RCVD_COUNT_FIVE(0.00)[6]; FROM_NEQ_ENVFROM(0.00)[jameshilliard1@gmail.com,linux-sunxi@lists.linux.dev]; TAGGED_FROM(0.00)[bounces-25877-noreply=patchwork.local]; R_SPF_ALLOW(0.00)[+ip4:172.105.105.114]; FREEMAIL_TO(0.00)[bootlin.com,nod.at,ti.com,kernel.org,gmail.com,sholland.org,socionext.com]; FREEMAIL_FROM(0.00)[gmail.com]; TO_DN_SOME(0.00)[]; ASN(0.00)[asn:63949, ipnet:172.105.96.0/20, country:SG]; FORGED_RECIPIENTS_MAILLIST(0.00)[]; RCVD_TLS_LAST(0.00)[]; MIME_TRACE(0.00)[0:+]; MID_RHS_MATCH_FROM(0.00)[]; ARC_ALLOW(0.00)[subspace.kernel.org:s=arc-20240116:i=1]; RCVD_VIA_SMTP_AUTH(0.00)[] X-Rspamd-Queue-Id: 3A8281C2BD4 X-MORS-Enabled: yes X-MORS-DOMAIN: patchwork.local X-MORS-HOSTING: hosting172546 X-MORS-USER: hosting172546 X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= The hardware-ECC read callbacks ignore errors from nand_read_page_op(). A failed page-setup command can leave the previous page available, so a later successful transfer can return stale data instead of the requested page. Stop before starting the PIO or DMA transfer when page setup fails. The physical rereads used to check an uncorrectable chunk for erased contents also ignore errors from nand_change_read_column_op(). A failed transfer can therefore leave stale data in the buffers used for the erased check and turn an I/O failure into an ECC result. Share the erased-chunk fallback between PIO and DMA and stop before checking the buffers when either reread fails. Preserve the existing erased-chunk test and corrected-bit accounting when both reads succeed. Before retrying a failed DMA read in PIO, restore only its corrected and failed counters so partial results are not counted twice. Leave bad-block and BBT counters alone. Route PIO page and subpage error exits through ECC disable before returning the transfer error. Fixes: 97d90da8a886 ("mtd: nand: provide several helpers to do common NAND operations") Fixes: 25f815f66a14 ("mtd: nand: force drivers to explicitly send READ/PROG commands") Cc: stable@vger.kernel.org Signed-off-by: James Hilliard --- drivers/mtd/nand/raw/sunxi_nand.c | 120 +++++++++++++++++++++++--------------- 1 file changed, 72 insertions(+), 48 deletions(-) diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index 172c7c4b0ba6..d5d8d383b6d1 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -1067,6 +1067,40 @@ static void sunxi_nfc_hw_ecc_update_stats(struct nand_chip *nand, } } +/* + * Return 1 for an erased chunk or 0 for an uncorrectable chunk, with ECC + * statistics updated in either case. Negative values report transport errors. + */ +static int sunxi_nfc_hw_ecc_read_error(struct nand_chip *nand, + u8 *data, int data_off, + u8 *oob, int oob_off, + unsigned int user_data_sz, + unsigned int *max_bitflips) +{ + struct nand_ecc_ctrl *ecc = &nand->ecc; + unsigned int oob_len = ecc->bytes + user_data_sz; + int ret; + + /* Check the physical representation for bitflips in erased pages. */ + if (nand->options & NAND_NEED_SCRAMBLING) { + ret = nand_change_read_column_op(nand, data_off, data, + ecc->size, false); + if (ret) + return ret; + } + + ret = nand_change_read_column_op(nand, oob_off, oob, oob_len, false); + if (ret) + return ret; + + ret = nand_check_erased_ecc_chunk(data, ecc->size, oob, oob_len, NULL, 0, + ecc->strength); + + sunxi_nfc_hw_ecc_update_stats(nand, max_bitflips, ret); + + return ret >= 0; +} + static int sunxi_nfc_hw_ecc_correct(struct nand_chip *nand, u8 *data, u8 *oob, int step, u32 status, u32 pattern_found, unsigned int user_data_sz, bool *erased) @@ -1115,7 +1149,6 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct nand_chip *nand, struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); unsigned int user_data_sz = sunxi_nfc_user_data_sz(sunxi_nand, step); struct nand_ecc_ctrl *ecc = &nand->ecc; - int raw_mode = 0; u32 pattern_found; bool bbm = !step; bool erased; @@ -1158,25 +1191,13 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct nand_chip *nand, return 1; if (ret < 0) { - /* - * Re-read the data with the randomizer disabled to identify - * bitflips in erased pages. - */ - if (nand->options & NAND_NEED_SCRAMBLING) - nand_change_read_column_op(nand, data_off, data, - ecc->size, false); - else + if (!(nand->options & NAND_NEED_SCRAMBLING)) memcpy_fromio(data, nfc->regs + NFC_RAM0_BASE, ecc->size); - nand_change_read_column_op(nand, oob_off, oob, - ecc->bytes + user_data_sz, false); - - ret = nand_check_erased_ecc_chunk(data, ecc->size, oob, - ecc->bytes + user_data_sz, - NULL, 0, ecc->strength); - if (ret >= 0) - raw_mode = 1; + return sunxi_nfc_hw_ecc_read_error(nand, data, data_off, + oob, oob_off, user_data_sz, + max_bitflips); } else { memcpy_fromio(data, nfc->regs + NFC_RAM0_BASE, ecc->size); @@ -1193,7 +1214,7 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct nand_chip *nand, sunxi_nfc_hw_ecc_update_stats(nand, max_bitflips, ret); - return raw_mode; + return 0; } /* @@ -1260,6 +1281,8 @@ static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, uint8_t *buf struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); struct mtd_info *mtd = nand_to_mtd(nand); struct nand_ecc_ctrl *ecc = &nand->ecc; + unsigned int corrected = mtd->ecc_stats.corrected; + unsigned int failed = mtd->ecc_stats.failed; unsigned int max_bitflips = 0; int ret, i, raw_mode = 0; struct scatterlist sg; @@ -1354,29 +1377,18 @@ static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, uint8_t *buf if (!(status & NFC_ECC_ERR(i))) continue; - /* - * Re-read the data with the randomizer disabled to - * identify bitflips in erased pages. - * TODO: use DMA to read page in raw mode - */ - if (randomized) - nand_change_read_column_op(nand, data_off, - data, ecc->size, - false); - - /* TODO: use DMA to retrieve OOB */ - nand_change_read_column_op(nand, - mtd->writesize + oob_off, - oob, ecc->bytes + user_data_sz, false); - - ret = nand_check_erased_ecc_chunk(data, ecc->size, oob, - ecc->bytes + user_data_sz, - NULL, 0, - ecc->strength); - if (ret >= 0) + ret = sunxi_nfc_hw_ecc_read_error(nand, data, data_off, oob, + mtd->writesize + oob_off, + user_data_sz, + &max_bitflips); + if (ret < 0) { + /* The caller retries the whole read in PIO mode. */ + mtd->ecc_stats.corrected = corrected; + mtd->ecc_stats.failed = failed; + return ret; + } + if (ret) raw_mode = 1; - - sunxi_nfc_hw_ecc_update_stats(nand, &max_bitflips, ret); } } @@ -1471,7 +1483,9 @@ static int sunxi_nfc_hw_ecc_read_page(struct nand_chip *nand, uint8_t *buf, sunxi_nfc_select_chip(nand, nand->cur_cs); - nand_read_page_op(nand, page, 0, NULL, 0); + ret = nand_read_page_op(nand, page, 0, NULL, 0); + if (ret) + return ret; sunxi_nfc_hw_ecc_enable(nand); @@ -1487,7 +1501,7 @@ static int sunxi_nfc_hw_ecc_read_page(struct nand_chip *nand, uint8_t *buf, &cur_off, &max_bitflips, i, oob_required, page); if (ret < 0) - return ret; + goto out; else if (ret) raw_mode = true; } @@ -1496,9 +1510,11 @@ static int sunxi_nfc_hw_ecc_read_page(struct nand_chip *nand, uint8_t *buf, sunxi_nfc_hw_ecc_read_extra_oob(nand, nand->oob_poi, &cur_off, !raw_mode, page); + ret = max_bitflips; +out: sunxi_nfc_hw_ecc_disable(nand); - return max_bitflips; + return ret; } static int sunxi_nfc_hw_ecc_read_page_dma(struct nand_chip *nand, u8 *buf, @@ -1508,7 +1524,9 @@ static int sunxi_nfc_hw_ecc_read_page_dma(struct nand_chip *nand, u8 *buf, sunxi_nfc_select_chip(nand, nand->cur_cs); - nand_read_page_op(nand, page, 0, NULL, 0); + ret = nand_read_page_op(nand, page, 0, NULL, 0); + if (ret) + return ret; ret = sunxi_nfc_hw_ecc_read_chunks_dma(nand, buf, oob_required, page, nand->ecc.steps); @@ -1532,7 +1550,9 @@ static int sunxi_nfc_hw_ecc_read_subpage(struct nand_chip *nand, sunxi_nfc_select_chip(nand, nand->cur_cs); - nand_read_page_op(nand, page, 0, NULL, 0); + ret = nand_read_page_op(nand, page, 0, NULL, 0); + if (ret) + return ret; sunxi_nfc_hw_ecc_enable(nand); @@ -1550,12 +1570,14 @@ static int sunxi_nfc_hw_ecc_read_subpage(struct nand_chip *nand, &cur_off, &max_bitflips, i, false, page); if (ret < 0) - return ret; + goto out; } + ret = max_bitflips; +out: sunxi_nfc_hw_ecc_disable(nand); - return max_bitflips; + return ret; } static int sunxi_nfc_hw_ecc_read_subpage_dma(struct nand_chip *nand, @@ -1567,7 +1589,9 @@ static int sunxi_nfc_hw_ecc_read_subpage_dma(struct nand_chip *nand, sunxi_nfc_select_chip(nand, nand->cur_cs); - nand_read_page_op(nand, page, 0, NULL, 0); + ret = nand_read_page_op(nand, page, 0, NULL, 0); + if (ret) + return ret; ret = sunxi_nfc_hw_ecc_read_chunks_dma(nand, buf, false, page, nchunks); if (ret >= 0) From patchwork Mon Sep 14 03:01:10 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3317 Return-Path: X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from tor.lore.kernel.org (tor.lore.kernel.org [172.105.105.114]) by mxe881.netcup.net (Postfix) with ESMTPS id 25E551C2BD4 for ; Mon, 14 Sep 2026 05:03:02 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=gmail.com; spf=pass (sender IP is 172.105.105.114) smtp.mailfrom=linux-sunxi+bounces-25878-noreply=patchwork.local@lists.linux.dev smtp.helo=tor.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 172.105.105.114 as permitted sender) client-ip=172.105.105.114; envelope-from=linux-sunxi+bounces-25878-noreply=patchwork.local@lists.linux.dev; helo=tor.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by tor.lore.kernel.org (Postfix) with ESMTP id EE6442E0FA for ; Mon, 14 Sep 2026 03:01:58 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 88716342CBA; Mon, 14 Sep 2026 03:01:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Crcm955v" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-oo2-f42.google.com (mail-oo2-f42.google.com [74.125.231.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E985125CC74 for ; Mon, 14 Sep 2026 03:01:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.231.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789354907; cv=none; b=juw+yxNrd//K7414iPBcJvSq7ra/HroreNWNZIyf0Ln1O/Moxfqbq1b++AFf2riNSIOfnNivaimWFpfZN7ulWXu4xos+NHGpXRfYzFR83R92WJ4AEGHMTWO05qrDtk3sfpkI227gdrDIUGG76em8cV3Nl7L07tH+1PldWf2whss= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789354907; c=relaxed/simple; bh=NlWMHvWo8eC8a5062ul0UGSwTs8Firq1Hsg3xcZzp2E=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=hkH3bIHs/Amx/Wcy6Cnu2Ql0qkPH4cDnnIltQjGK4IPf87GLt5EAPrKNjInSo2oqpo8o+ZjcwvbgzbnQ1Yp59RoeMVXzjeM1+s7Ih7fl4+i5F6z54SfZ/udkHUva8TvHmCDC25IXjJPUucOHOTpkDlnkE+cxEIJiieMIk3pu+4I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Crcm955v; arc=none smtp.client-ip=74.125.231.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-oo2-f42.google.com with SMTP id 46e09a7af769-8050801d337so1103173a34.2 for ; Sun, 13 Sep 2026 20:01:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789354903; x=1789959703; darn=lists.linux.dev; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=o8noBZbj7C7U90sjdVnrOExXAG4fUCSDlE1zY+ZGE34=; b=Crcm955vNA2ZNIPPzi9D/r/nUlB39usn23JmAnCxhQ9APx0LG+5unbhpuf3BpQvZ2M EaM64kcK5xAMb/NN94Q2Q4J6y2rS9U1pQfKG9fe1IpwjlHKhd499B17hkq5Z5ZR0yWvn v53DE8qauLDWqzy3KMMP5fNBTW2buPHz0dKYuqT12lsbyUDXKvqBMf1rQayUfjbUgSPe 731u/qtMsyDPRi40//ERTBg45L/rj3PZKNC60H4H4zzphk1aAeN7b/BMX7esowjTLjFQ RsGLUX9dkyVCZgACMtIV5XFAS3/HbcMQ9wodsm7VDLxl+vZWpqqby4qmOH4LN3wqvqkN lRXw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789354903; x=1789959703; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=o8noBZbj7C7U90sjdVnrOExXAG4fUCSDlE1zY+ZGE34=; b=f3vOEIfi2ASA/w/a9wLs5oIsuDRkqv5bgAatZ1kw+zeUsDli2dsdFfz5AQCxXPhAEV bwViv7isBeC0Mg0M9JqT+7WW7EJQ0190cctHD3CCqGgV/MSi9k31RZcvUkj+Yk1euO+H Cva1JPXbnmYjGpRiSArcJvBROGdYT25YXnNDCC3VNEmneQds/MhK9HyV3VBBkAKiQPc5 Wb/UxnuhSHPZdLk7ilcswJ+RZEusxsxkJ22H5A2Pez6WRFo7uEjKo30xZCv0WRxeRIwK BaTb2bZOCVcrMvJPtXQ1a0xjIxiFOOzlvR+BhAPW5BRLSJ9pHeVNXKKOswWpP9FLf8Z8 NG0g== X-Forwarded-Encrypted: i=1; AKwUvByCLjozmJiPYs4IhPeUIa1NtnT67kifVp1YVN+90wHcbaqXSARTMHIq/GHOJbElCUGB65LBqC96Yalbvw==@lists.linux.dev X-Gm-Message-State: AFuF++noHg56cMrRcszCo4w4ZHAGgCzhhFBqLzsEouJIbHVpsjJJxa97 IN9oAacZfWSK9EOxT+42IKrHnpfJ6V0w6Iv+Llm8fk8i+pLvKjtJ5e7H X-Gm-Gg: AYBFou2lzSgv22KLZlVXxMLYnxqJOTKBaHqN/l4ZsXIV3E0NFwk5AAsMVvBH3wpV+RC 8qyE8Fbai2nFf/HcuybWG3AwSMqVtXn/c3whHG6QClwopClo/3It8jLfXduWvabX8c4JxmY1Cal g8KaFPAL+5s/FoXEtQ/pR9UQzt664gaqWVydzxn0lLZkDLrJHhgwsQPhgu8wrjlQJdNW5vAU1Ne ojqkUdU/hGtXlaO5vDvakPkd6dT4YmBdq6rPGndGp0kd1e3nhdMUvNe8ucmGbqZbtl/HvhybCEq oEA1ieTI40kcFOVzd364U3jInpBLfKS+wtmkGZYAEKqjxu+qIJlp0INu1YC7qgmMhuucAed855f SF9UPy/rXyyaC0wihpaE0Op2JsbfLFD4Ux/ZpA7KCuHjzLAO23sgy+pBm2nAK4Ih6paRJ6W4dAt fnv5yBUFM0wbCgWLBnXArOJxd+9BX97EwLA0Gmoy+t6sgjxHIfykfjsuINVSG2+Wakoi9Zcgqh4 XXARJtjDshEFibUJKb5ple2kgO2WRVuSCwUXgXE8snIM0dgnNWor6KVWtQ20Q986qzPEAFMXXsd 8ppZgULYFhte8lN6AGHszwZMM5gw6t2lfMNoMdkdktmj1foECCZ+1OJ/HFp6/LDyBzbrsqXagsR 4qTiRXl8YYe+IvFUT/FH1wJFYq16Ckw== X-Received: by 2002:a05:6830:3894:b0:805:9f8b:bef8 with SMTP id 46e09a7af769-8089974baa0mr554382a34.14.1789354902809; Sun, 13 Sep 2026 20:01:42 -0700 (PDT) Received: from [127.0.1.1] (184-96-157-145.hlrn.qwest.net. [184.96.157.145]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-803f60feba1sm10619014a34.13.2026.09.13.20.01.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 13 Sep 2026 20:01:42 -0700 (PDT) From: James Hilliard Date: Sun, 13 Sep 2026 21:01:10 -0600 Subject: [PATCH v5 04/18] mtd: rawnand: sunxi: stop failed program operations and disable ECC Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-4-7d711076a6f7@gmail.com> References: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-0-7d711076a6f7@gmail.com> In-Reply-To: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-0-7d711076a6f7@gmail.com> To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Maxime Ripard , Richard Genoud , Masahiro Yamada , Boris Brezillon , Brian Norris Cc: linux-mtd@lists.infradead.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, James Hilliard , stable@vger.kernel.org X-Mailer: b4 0.15.2 X-MORS-Enabled: yes X-MORS-DOMAIN: patchwork.local X-MORS-HOSTING: hosting172546 X-MORS-USER: hosting172546 X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= The PIO page and subpage write callbacks leave ECC enabled if a chunk transfer fails. They also ignore program-setup errors, as does the DMA page writer, and can continue transferring data and issuing PAGEPROG after the setup command has failed. Check program setup before enabling ECC or transferring data. If DMA preparation has already succeeded, abort the queued operation and unmap its buffer before returning the setup error. Route PIO chunk failures through ECC disable and return the original error. Issue the program-end command only after the transfers succeed, preserving the existing successful-write sequence. Fixes: 1fef62c1423b ("mtd: nand: add sunxi NAND flash controller support") Fixes: 25f815f66a14 ("mtd: nand: force drivers to explicitly send READ/PROG commands") Cc: stable@vger.kernel.org Signed-off-by: James Hilliard --- drivers/mtd/nand/raw/sunxi_nand.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index d5d8d383b6d1..5d88ad3b8f70 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -1610,11 +1610,13 @@ static int sunxi_nfc_hw_ecc_write_page(struct nand_chip *nand, struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); struct mtd_info *mtd = nand_to_mtd(nand); struct nand_ecc_ctrl *ecc = &nand->ecc; - int ret, i, cur_off = 0; + int ret = 0, i, cur_off = 0; sunxi_nfc_select_chip(nand, nand->cur_cs); - nand_prog_page_begin_op(nand, page, 0, NULL, 0); + ret = nand_prog_page_begin_op(nand, page, 0, NULL, 0); + if (ret) + return ret; sunxi_nfc_hw_ecc_enable(nand); @@ -1629,14 +1631,17 @@ static int sunxi_nfc_hw_ecc_write_page(struct nand_chip *nand, oob_off + mtd->writesize, &cur_off, i, page); if (ret) - return ret; + goto out; } if (oob_required || (nand->options & NAND_NEED_SCRAMBLING)) sunxi_nfc_hw_ecc_write_extra_oob(nand, nand->oob_poi, &cur_off, page); +out: sunxi_nfc_hw_ecc_disable(nand); + if (ret) + return ret; return nand_prog_page_end_op(nand); } @@ -1650,11 +1655,13 @@ static int sunxi_nfc_hw_ecc_write_subpage(struct nand_chip *nand, struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); struct mtd_info *mtd = nand_to_mtd(nand); struct nand_ecc_ctrl *ecc = &nand->ecc; - int ret, i, cur_off = 0; + int ret = 0, i, cur_off = 0; sunxi_nfc_select_chip(nand, nand->cur_cs); - nand_prog_page_begin_op(nand, page, 0, NULL, 0); + ret = nand_prog_page_begin_op(nand, page, 0, NULL, 0); + if (ret) + return ret; sunxi_nfc_hw_ecc_enable(nand); @@ -1670,10 +1677,13 @@ static int sunxi_nfc_hw_ecc_write_subpage(struct nand_chip *nand, oob_off + mtd->writesize, &cur_off, i, page); if (ret) - return ret; + goto out; } +out: sunxi_nfc_hw_ecc_disable(nand); + if (ret) + return ret; return nand_prog_page_end_op(nand); } @@ -1712,7 +1722,12 @@ static int sunxi_nfc_hw_ecc_write_page_dma(struct nand_chip *nand, sunxi_nfc_set_user_data_len(nfc, user_data_sz, i); } - nand_prog_page_begin_op(nand, page, 0, NULL, 0); + ret = nand_prog_page_begin_op(nand, page, 0, NULL, 0); + if (ret) { + sunxi_nfc_dma_op_abort(nfc); + sunxi_nfc_dma_op_cleanup(nfc, DMA_TO_DEVICE, &sg); + return ret; + } sunxi_nfc_hw_ecc_enable(nand); sunxi_nfc_randomizer_config(nand, page, false); From patchwork Mon Sep 14 03:01:11 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3313 Return-Path: X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from sto.lore.kernel.org (sto.lore.kernel.org [172.232.135.74]) by mxe881.netcup.net (Postfix) with ESMTPS id 8CFF21C2BD4 for ; Mon, 14 Sep 2026 05:02:14 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=gmail.com; spf=pass (sender IP is 172.232.135.74) smtp.mailfrom=linux-sunxi+bounces-25879-noreply=patchwork.local@lists.linux.dev smtp.helo=sto.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 172.232.135.74 as permitted sender) client-ip=172.232.135.74; envelope-from=linux-sunxi+bounces-25879-noreply=patchwork.local@lists.linux.dev; helo=sto.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by sto.lore.kernel.org (Postfix) with ESMTP id CEFA26027D0 for ; Mon, 14 Sep 2026 03:02:03 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id D2FFB345CCA; Mon, 14 Sep 2026 03:01:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="COy2xpY1" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-oo2-f40.google.com (mail-oo2-f40.google.com [74.125.231.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C1F4833C518 for ; Mon, 14 Sep 2026 03:01:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.231.168 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789354909; cv=none; b=JtsdJ9q1XjLl0qRTQooHq+ECAVs9UIbsutfoNKPkqa3N0mLwasSMbZmSzJScaTquOsxd2odKcfgzHRaCcWwPbD/Ii/F8HFymehgYTNaGmGJJmuqxP4ZvDGke0kdgtfn2N+ZCK9o2ONy/pzEeGNv3QjgCY98bBurenUvaHVe2nnM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789354909; c=relaxed/simple; bh=+EYozN7O+JBkDeCx/hgJ+s4q3FbwEjbXAk835pOjKgM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=poKE8MYrW+yhqDCfz4pwov/piSZhSj3QeyYQilUF/SqQdh3asq73KgqqH/0cn/0/G/l65EAgVk2bDUYW4WbS6ao5wI+jZI+yR6q8wyTgmArwrr9DNzHL6GLw/MImmL7bF/jfE+922xySZaO49pcqviBZimFLSTfO32Z7dHyHxN0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=COy2xpY1; arc=none smtp.client-ip=74.125.231.168 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-oo2-f40.google.com with SMTP id 46e09a7af769-804e42309a5so401742a34.2 for ; Sun, 13 Sep 2026 20:01:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789354904; x=1789959704; darn=lists.linux.dev; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=5tiLR7FZzQsyTOBW2MGeS5ZnHrzID+Jy7EEHyMHP5gI=; b=COy2xpY1po0WKWKtEPyf9LdYYbxk3oW+TOshMKUduqv0j0QncaPv6HEr/HZgNLOUqY mLixXphq1XU7W0sTTJIKAQelbTdZRsmHJLiE6Ifl9PXalzEYF4Ot4elXblvB4Gprw+D3 XNyRUfoo1FvXNOCxsjJ5darDUnZTAjplT53rgqi866hTJv9LfPZgSUCyd/3IVSaAec8h xpkF80eqMlgCHYHO79BdpHv8fsqAkCJtdt9VqkIIzhI2qR+ku9G++sZFo8aOVPvjGdFm O6JBQKkcTr4HRl94+uWZ4aPirCanvSp7CbhVSEW4PS2O3jNaDWJHWcFqKPXm6uP2ssdB HLCQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789354904; x=1789959704; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=5tiLR7FZzQsyTOBW2MGeS5ZnHrzID+Jy7EEHyMHP5gI=; b=U9w3Y3/UCLlpRy2uSHefoewfXQyDAzmA05wjGPZHpn7fEOprd2NQrbYCxtuQYw4VMl nX6AfyKLKeI4lE0eBLo/zuWnZjGAzElVm7pEFvSalvqMnyj8xB75lSKCVtWZJyrTl2W5 4r8O9DtMxNgYtzrUaX/lTyLtIUNckp2v/15Bv4xavQOFKr1IXAk6GYdifS4wU9xJKkVi XQ9yIj+u+GtDk4j566H5NZvKOtWEilkmXGgpNXKMVo751kCDUM/adUaFc/yIZADYag1w L8eXHFYPYcAX1bncI9rXz0GZ01QE4nRXpd8yNI8VHg0hPXsds0T9L0oGzHi2eWIgXyY4 80tg== X-Forwarded-Encrypted: i=1; AKwUvBz2oXOh8YWsSScED7A9qRz2BGS6G5r5oHgVeahSWBk4uRe5lUfVhBKQ9JtM7alt18s7O9hrm+o1NKSacA==@lists.linux.dev X-Gm-Message-State: AFuF++mXU9FrnHheJGPLwbU3FoMlFMARfygO/ev9OIyd8/jkJiv2nI2V 658iMZG4aGnjPHuLgs+TFhYBdRZiP2NWSz6NHQMl5xroFdF+UvlK8YPI X-Gm-Gg: AYBFou0v4gATOeWnFkcFZdZqLVW0pS3Zs+ceJm7k+jI0aHBgnvhiqg9Aq2k/j45nZ22 MBkN1jP5OBhYfVdyp1RZ6xpMC+Ds+jNCeHbAlsnCBVhdzGF2rb45zXyerurbL7srEPTz4XFmi0J s1IOJq9RqNetlhG+tD/WQjT6kBNj4+xuz6PX8+1aWEBkAVcQCg1fnCxhuJSFVPe+cOZ6c/jcyWj zvywfivw99B6He3ehSythBAL0GJGwkQkVBNfGvjyNeRBfq8DGqxuXeGN9FcUJec9l2bC2UPChK9 wWJn8RgYfW+t/OD8CtOoyrXOX7YuBuaZCJKMePgrhVNZuUwW8h/TG1gNz52zqTLVGiThEV5rO/g QwUPz2ncuAoLS1e9aOhkgQ36vhhcy+2eyEhU2WlMIEYSipZod9m5G0l3B64MArNGPBlVI1xGbBH wUdJTJ4df1BW0K1IC117TbFbb31bz5hTRAkb6dugalHZzbYmg+fpt1wPqc19j4q3rPwx5/3KK1B uz3j+ofP0S/O46TUE/QC2FvYDTiDLFN6o2wpzNpHb0dPKCk9w8O20FSCpQ12LkjvEB54539DfvG hGlLhIDvB92kF/BrOZu6KbBs4kcTqcd9oaniuCDwVuKDdC/uwshBY1kPPn+Q/fMilWgZ+6DwVIo +hphv4pTTZ3yRV+O0kY7qNsV1i9U49A== X-Received: by 2002:a05:6830:67d9:b0:7f4:eb76:8820 with SMTP id 46e09a7af769-80897e81b85mr306525a34.13.1789354904353; Sun, 13 Sep 2026 20:01:44 -0700 (PDT) Received: from [127.0.1.1] (184-96-157-145.hlrn.qwest.net. [184.96.157.145]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-803f60feba1sm10619014a34.13.2026.09.13.20.01.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 13 Sep 2026 20:01:43 -0700 (PDT) From: James Hilliard Date: Sun, 13 Sep 2026 21:01:11 -0600 Subject: [PATCH v5 05/18] mtd: rawnand: sunxi: select the pattern ID for the current ECC step Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-5-7d711076a6f7@gmail.com> References: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-0-7d711076a6f7@gmail.com> In-Reply-To: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-0-7d711076a6f7@gmail.com> To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Maxime Ripard , Richard Genoud , Masahiro Yamada , Boris Brezillon , Brian Norris Cc: linux-mtd@lists.infradead.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, James Hilliard , stable@vger.kernel.org X-Mailer: b4 0.15.2 X-MORS-Enabled: yes X-MORS-DOMAIN: patchwork.local X-MORS-HOSTING: hosting172546 X-MORS-USER: hosting172546 X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= The pattern ID register has one bit per hardware ECC step, distinguishing all-zero from all-ones data. The correction helper checks the current step's pattern-found bit but always reads pattern ID bit zero. PIO reuses hardware step zero, so this works there. DMA processes several steps at once: a later all-ones step can be filled with zeros and reported as a successful read if pattern ID bit zero is clear. Conversely, a later all-zero step can be treated as erased when bit zero is set. Use the current hardware step's pattern ID bit, matching the error and pattern-found bits already checked by the helper. Fixes: 614049a8d904 ("mtd: nand: sunxi: add support for DMA assisted operations") Cc: stable@vger.kernel.org Signed-off-by: James Hilliard --- drivers/mtd/nand/raw/sunxi_nand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index 5d88ad3b8f70..3f506d0666a1 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -1117,7 +1117,7 @@ static int sunxi_nfc_hw_ecc_correct(struct nand_chip *nand, u8 *data, u8 *oob, if (pattern_found & BIT(step)) { u8 pattern; - if (unlikely(!(readl(nfc->regs + NFC_REG_PAT_ID(nfc)) & 0x1))) { + if (unlikely(!(readl(nfc->regs + NFC_REG_PAT_ID(nfc)) & BIT(step)))) { pattern = 0x0; } else { pattern = 0xff; From patchwork Mon Sep 14 03:01:12 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3320 Return-Path: X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from tor.lore.kernel.org (tor.lore.kernel.org [172.105.105.114]) by mxe881.netcup.net (Postfix) with ESMTPS id 0B20D1C3F00 for ; Mon, 14 Sep 2026 05:03:46 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=gmail.com; spf=pass (sender IP is 172.105.105.114) smtp.mailfrom=linux-sunxi+bounces-25880-noreply=patchwork.local@lists.linux.dev smtp.helo=tor.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 172.105.105.114 as permitted sender) client-ip=172.105.105.114; envelope-from=linux-sunxi+bounces-25880-noreply=patchwork.local@lists.linux.dev; helo=tor.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by tor.lore.kernel.org (Postfix) with ESMTP id AC7C72F3DA for ; Mon, 14 Sep 2026 03:02:09 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id DDF40349CD6; Mon, 14 Sep 2026 03:01:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="hooqoGlj" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-ot1-f51.google.com (mail-ot1-f51.google.com [209.85.210.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AF9D2334C39 for ; Mon, 14 Sep 2026 03:01:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789354910; cv=none; b=eiV2VjLTRg44+Zfb90GgG4+FWbbM1+W46g2kvkhr0BUoUfuz00DwUpmPjx9RZjaDuNbmZKuN5bJgZopXMjaTUNkg9tlI7hydBoNCaEZgCc/Y//7DUy1jFVaILCrnsAxmgLle2afeDcWzE1dFF+c6NvJ3cW9+8ujlNMrW+w5VZOg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789354910; c=relaxed/simple; bh=QuwwqJoNNeFbRXCees1KSU/os0gxTVKzY6QPcLIi7JU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=EizU83Z5hi0wmsPNmX36h6LkiBC5AMXrMAW0lylzjQZym/UFugsHziRvSE8HDqQIzdKQ30nxa6rfp9qv0MyCjkInjNTrts9jXFxbbd0A2+yEywv7KsoPmiI1/WL31B/YQfxYv7qw8vnEnuJOEZaba/qjZ4CvAshPVDINGqPITps= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=hooqoGlj; arc=none smtp.client-ip=209.85.210.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-ot1-f51.google.com with SMTP id 46e09a7af769-7f4e729368fso2938123a34.0 for ; Sun, 13 Sep 2026 20:01:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789354906; x=1789959706; darn=lists.linux.dev; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=j2vD4BC1COzN8qzLeVpRCLcx09AvVc6YiLKflTDkdf0=; b=hooqoGlj0/NNdb3pNRkNypjDZ6ey3U6u1wIoX582fgeDJlS3oNlX6mL/ZudFHXhmsj Qh/aen5PzBzRmkzKBcevl8zjtlaRf8noJtJZryTlVISQ1igFWN6/zt5YzLnLjcHlf+mW XcTshAEjB4pbzoU+qbb4UAAxeZBt5hKbgm0H8Qg13kWl3IpBOMJe207n6Swi/mpLcuyl cV/DA16qvWDVNx4igUpC1vOxJGR/wnKA8pQp3r+sK12+0kNDLh7R1dm80PhXhzHneU94 j2Nvy70WsuyDCr1EuguQcnOfNV+sdxplq/3wWBG+jn+NwYTLDQAUa6cmSuzx0cE/FE2S cz8g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789354906; x=1789959706; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=j2vD4BC1COzN8qzLeVpRCLcx09AvVc6YiLKflTDkdf0=; b=m9dEh/SHi4Bk8SMx7bXK3dL+yIIf9PZEJNmwyJqFKEH2lrsP5taZV6Nn6XlWlPwsmn jv6h5qwSzPqz7O+c1y6HHy3HuPsKWTrjTygZ6pA1+dtTtEnbBBE2p0KGK5IGR3d5d4hf d49kOXjiMY1z9lP6+eq1eM+X4lY3hvqfhb2tRRzaftcgYYnEHaq5aPvQjsaOcQfDHJy+ hs5qBDvSYPCU1AGgwHb9+dSn3Hri5Jx5aWbT2+w18bbYYxl6/F9RWQPr+JVPteJCMY7f AHmH0vIRXt1kp1i3aGwWvuM9A1baYq7vTwhHPCCfRI8U1t46NcInDkPqtO9DaCbOUZEE tb7g== X-Forwarded-Encrypted: i=1; AKwUvBzqflDPIxWQXAhikRyu+yuF1zd/w6f0vwzT4Y2r4CANuNt/CHS1riF9BwJA4a8bOYbXFBsuumiYOKXphA==@lists.linux.dev X-Gm-Message-State: AFuF++keKGYIomDJxUisyNsF4BepeASBo76VqG+j06/2BlkMNuI8tR03 2dC+gJULw/mRxt3eX+HIs9Is9x+IxFhBfnU8+BjJQktbl8Uyn2YKhvFf2XUCMw== X-Gm-Gg: AYBFou3MV2qVeK+57FG6W25L+UQcmq7qXGKtdzu4FXch82hqWpMVecWYM67OwiO5pvz tv8WlhMupn+MRnrcCaOJUW5OomPTY5rYitSJF1A5CwYNIXdazB40NAfOnCFa6rNpwmLtC9qjR7t oXLyXBT0pUR2KMbNrA/q9QGYLoEFAWah9ZC52ajR+TbquTq2JGiMEOV91fQ4c2HEA3JXiNNLNSf ksecD4jDLzLE3O7NW1hdU4qLL+nJLQkx4BpJXp0iWyqTLkeyFDkzf1uqxtTfKK2l0MKMJ3FRD7P yuPL3JnMPtcx4l9K8iboEYhHXlM/YNYDwNXyxntOFGpy1a/jDIfiZXRcNbF771Gaj0ehJOvXvn+ znflnB1U3FBpgfvogTzowWYjRd8cD7UyMIyu72Xn3eT/N1aA7ky/6pFfWxmPD54mLUYBHMTTzYO 754yhVfhZRHJ43eJR/uECcZgau2maVEmNWwyDuKz/F69ax/sek/XTWFs4UWMxz+qs8JHzqRoxs4 xxn+xiB5Cwzk70MzrdreOR6J9daPZk5K3OPsUq/sTtZNcwskfJ2sujPYiYfs4ryRB/miFhC9pWi g4s0IfXpOEsQqWI88Dgen22ehMRO0ooBf3oagsEW4LNHp2IVoJUlxIXW0dD17QS8hUZHp1pNCRD owdDjWlena65g6Wy75JaRM8SebjZ19A== X-Received: by 2002:a05:6830:3886:b0:7fa:ac4f:790 with SMTP id 46e09a7af769-8089a150dcamr251581a34.28.1789354906207; Sun, 13 Sep 2026 20:01:46 -0700 (PDT) Received: from [127.0.1.1] (184-96-157-145.hlrn.qwest.net. [184.96.157.145]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-803f60feba1sm10619014a34.13.2026.09.13.20.01.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 13 Sep 2026 20:01:45 -0700 (PDT) From: James Hilliard Date: Sun, 13 Sep 2026 21:01:12 -0600 Subject: [PATCH v5 06/18] mtd: rawnand: sunxi: propagate buffer and column transfer errors Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-6-7d711076a6f7@gmail.com> References: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-0-7d711076a6f7@gmail.com> In-Reply-To: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-0-7d711076a6f7@gmail.com> To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Maxime Ripard , Richard Genoud , Masahiro Yamada , Boris Brezillon , Brian Norris Cc: linux-mtd@lists.infradead.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, James Hilliard , stable@vger.kernel.org X-Mailer: b4 0.15.2 X-MORS-Enabled: yes X-MORS-DOMAIN: patchwork.local X-MORS-HOSTING: hosting172546 X-MORS-USER: hosting172546 X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= The PIO buffer helpers stop on a FIFO or completion timeout but return no status. Their hardware-ECC callers also ignore column-change failures, including the extra-OOB paths used after DMA. A read can therefore report success with incomplete data, and a write can issue PAGEPROG after a failed transfer. Return transfer errors through the randomizer and OOB helpers to the page callbacks. Always disable the randomizer after a buffer transfer, and let the existing page error exits disable ECC and skip program-end. Only advance the extra-OOB cursor after a successful transfer. Keep the corrected-bit count separate from transport status so successful OOB reads do not overwrite it. If any legacy DMA OOB read fails, discard the ECC statistics from that attempt before the caller retries in PIO. Leave the successful transfer sequence and OOB representation unchanged. Fixes: 1fef62c1423b ("mtd: nand: add sunxi NAND flash controller support") Cc: stable@vger.kernel.org Signed-off-by: James Hilliard --- drivers/mtd/nand/raw/sunxi_nand.c | 220 ++++++++++++++++++++++++-------------- 1 file changed, 141 insertions(+), 79 deletions(-) diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index 3f506d0666a1..72b79f893e29 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -644,7 +644,7 @@ static void sunxi_nfc_select_chip(struct nand_chip *nand, unsigned int cs) writel(ctl, nfc->regs + NFC_REG_CTL); } -static void sunxi_nfc_read_buf(struct nand_chip *nand, uint8_t *buf, int len) +static int sunxi_nfc_read_buf(struct nand_chip *nand, u8 *buf, int len) { struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); @@ -660,7 +660,7 @@ static void sunxi_nfc_read_buf(struct nand_chip *nand, uint8_t *buf, int len) ret = sunxi_nfc_wait_cmd_fifo_empty(nfc); if (ret) - break; + return ret; writel(cnt, nfc->regs + NFC_REG_CNT); tmp = NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD; @@ -672,17 +672,19 @@ static void sunxi_nfc_read_buf(struct nand_chip *nand, uint8_t *buf, int len) ret = sunxi_nfc_wait_events(nfc, NFC_CMD_INT_FLAG, poll, 0); if (ret) - break; + return ret; if (buf) memcpy_fromio(buf + offs, nfc->regs + NFC_RAM0_BASE, cnt); offs += cnt; } + + return 0; } -static void sunxi_nfc_write_buf(struct nand_chip *nand, const uint8_t *buf, - int len) +static int sunxi_nfc_write_buf(struct nand_chip *nand, const u8 *buf, + int len) { struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); @@ -698,7 +700,7 @@ static void sunxi_nfc_write_buf(struct nand_chip *nand, const uint8_t *buf, ret = sunxi_nfc_wait_cmd_fifo_empty(nfc); if (ret) - break; + return ret; writel(cnt, nfc->regs + NFC_REG_CNT); memcpy_toio(nfc->regs + NFC_RAM0_BASE, buf + offs, cnt); @@ -712,10 +714,12 @@ static void sunxi_nfc_write_buf(struct nand_chip *nand, const uint8_t *buf, ret = sunxi_nfc_wait_events(nfc, NFC_CMD_INT_FLAG, poll, 0); if (ret) - break; + return ret; offs += cnt; } + + return 0; } /* These seed values have been extracted from Allwinner's BSP */ @@ -865,23 +869,31 @@ static void sunxi_nfc_randomize_bbm(struct nand_chip *nand, int page, u8 *bbm) bbm[1] ^= sunxi_nfc_randomizer_step(state, 8); } -static void sunxi_nfc_randomizer_write_buf(struct nand_chip *nand, - const uint8_t *buf, int len, - bool ecc, int page) +static int sunxi_nfc_randomizer_write_buf(struct nand_chip *nand, + const u8 *buf, int len, + bool ecc, int page) { + int ret; + sunxi_nfc_randomizer_config(nand, page, ecc); sunxi_nfc_randomizer_enable(nand); - sunxi_nfc_write_buf(nand, buf, len); + ret = sunxi_nfc_write_buf(nand, buf, len); sunxi_nfc_randomizer_disable(nand); + + return ret; } -static void sunxi_nfc_randomizer_read_buf(struct nand_chip *nand, uint8_t *buf, - int len, bool ecc, int page) +static int sunxi_nfc_randomizer_read_buf(struct nand_chip *nand, u8 *buf, + int len, bool ecc, int page) { + int ret; + sunxi_nfc_randomizer_config(nand, page, ecc); sunxi_nfc_randomizer_enable(nand); - sunxi_nfc_read_buf(nand, buf, len); + ret = sunxi_nfc_read_buf(nand, buf, len); sunxi_nfc_randomizer_disable(nand); + + return ret; } static void sunxi_nfc_hw_ecc_enable(struct nand_chip *nand) @@ -1152,17 +1164,25 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct nand_chip *nand, u32 pattern_found; bool bbm = !step; bool erased; - int ret; + int ret, bitflips; /* From the controller point of view, we are at step 0 */ const int nfc_step = 0; - if (*cur_off != data_off) - nand_change_read_column_op(nand, data_off, NULL, 0, false); + if (*cur_off != data_off) { + ret = nand_change_read_column_op(nand, data_off, NULL, 0, false); + if (ret) + return ret; + } - sunxi_nfc_randomizer_read_buf(nand, NULL, ecc->size, false, page); + ret = sunxi_nfc_randomizer_read_buf(nand, NULL, ecc->size, false, page); + if (ret) + return ret; - if (data_off + ecc->size != oob_off) - nand_change_read_column_op(nand, oob_off, NULL, 0, false); + if (data_off + ecc->size != oob_off) { + ret = nand_change_read_column_op(nand, oob_off, NULL, 0, false); + if (ret) + return ret; + } ret = sunxi_nfc_wait_cmd_fifo_empty(nfc); if (ret) @@ -1184,13 +1204,13 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct nand_chip *nand, pattern_found = readl(nfc->regs + nfc->caps->reg_pat_found); pattern_found = field_get(NFC_ECC_PAT_FOUND_MSK(nfc), pattern_found); - ret = sunxi_nfc_hw_ecc_correct(nand, data, oob_required ? oob : NULL, - nfc_step, readl(nfc->regs + NFC_REG_ECC_ST), - pattern_found, user_data_sz, &erased); + bitflips = sunxi_nfc_hw_ecc_correct(nand, data, oob_required ? oob : NULL, + nfc_step, readl(nfc->regs + NFC_REG_ECC_ST), + pattern_found, user_data_sz, &erased); if (erased) return 1; - if (ret < 0) { + if (bitflips < 0) { if (!(nand->options & NAND_NEED_SCRAMBLING)) memcpy_fromio(data, nfc->regs + NFC_RAM0_BASE, ecc->size); @@ -1202,17 +1222,22 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct nand_chip *nand, memcpy_fromio(data, nfc->regs + NFC_RAM0_BASE, ecc->size); if (oob_required) { - nand_change_read_column_op(nand, oob_off, NULL, 0, - false); - sunxi_nfc_randomizer_read_buf(nand, oob, ecc->bytes + user_data_sz, - true, page); + ret = nand_change_read_column_op(nand, oob_off, NULL, 0, + false); + if (ret) + return ret; + ret = sunxi_nfc_randomizer_read_buf(nand, oob, + ecc->bytes + user_data_sz, + true, page); + if (ret) + return ret; sunxi_nfc_hw_ecc_get_prot_oob_bytes(nand, oob, nfc_step, bbm, page, user_data_sz); } } - sunxi_nfc_hw_ecc_update_stats(nand, max_bitflips, ret); + sunxi_nfc_hw_ecc_update_stats(nand, max_bitflips, bitflips); return 0; } @@ -1245,31 +1270,39 @@ static int sunxi_get_ecc_offset(struct sunxi_nand_chip *sunxi_nand, sunxi_nfc_user_data_sz(sunxi_nand, step); } -static void sunxi_nfc_hw_ecc_read_extra_oob(struct nand_chip *nand, - u8 *oob, int *cur_off, - bool randomize, int page) +static int sunxi_nfc_hw_ecc_read_extra_oob(struct nand_chip *nand, + u8 *oob, int *cur_off, + bool randomize, int page) { struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); struct mtd_info *mtd = nand_to_mtd(nand); struct nand_ecc_ctrl *ecc = &nand->ecc; int offset = sunxi_get_oob_offset(sunxi_nand, ecc, ecc->steps); int len = mtd->oobsize - offset; + int ret; if (len <= 0) - return; + return 0; - if (!cur_off || *cur_off != (offset + mtd->writesize)) - nand_change_read_column_op(nand, mtd->writesize + offset, - NULL, 0, false); + if (!cur_off || *cur_off != (offset + mtd->writesize)) { + ret = nand_change_read_column_op(nand, mtd->writesize + offset, + NULL, 0, false); + if (ret) + return ret; + } if (!randomize) - sunxi_nfc_read_buf(nand, oob + offset, len); + ret = sunxi_nfc_read_buf(nand, oob + offset, len); else - sunxi_nfc_randomizer_read_buf(nand, oob + offset, len, - false, page); + ret = sunxi_nfc_randomizer_read_buf(nand, oob + offset, len, + false, page); + if (ret) + return ret; if (cur_off) *cur_off = mtd->oobsize + mtd->writesize; + + return 0; } static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, uint8_t *buf, @@ -1340,21 +1373,24 @@ static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, uint8_t *buf u8 *data = buf + data_off; u8 *oob = nand->oob_poi + oob_off; bool erased; + int bitflips; - ret = sunxi_nfc_hw_ecc_correct(nand, randomized ? data : NULL, - oob_required ? oob : NULL, - i, status, pattern_found, - user_data_sz, &erased); + bitflips = sunxi_nfc_hw_ecc_correct(nand, randomized ? data : NULL, + oob_required ? oob : NULL, + i, status, pattern_found, + user_data_sz, &erased); /* ECC errors are handled in the second loop. */ - if (ret < 0) + if (bitflips < 0) continue; if (oob_required && !erased) { /* TODO: use DMA to retrieve OOB */ - nand_change_read_column_op(nand, - mtd->writesize + oob_off, - oob, ecc->bytes + user_data_sz, false); + ret = nand_change_read_column_op(nand, mtd->writesize + oob_off, + oob, ecc->bytes + user_data_sz, + false); + if (ret) + goto err_stats; sunxi_nfc_hw_ecc_get_prot_oob_bytes(nand, oob, i, !i, page, user_data_sz); @@ -1363,7 +1399,7 @@ static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, uint8_t *buf if (erased) raw_mode = 1; - sunxi_nfc_hw_ecc_update_stats(nand, &max_bitflips, ret); + sunxi_nfc_hw_ecc_update_stats(nand, &max_bitflips, bitflips); } if (status & NFC_ECC_ERR_MSK(nfc)) { @@ -1381,23 +1417,27 @@ static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, uint8_t *buf mtd->writesize + oob_off, user_data_sz, &max_bitflips); - if (ret < 0) { - /* The caller retries the whole read in PIO mode. */ - mtd->ecc_stats.corrected = corrected; - mtd->ecc_stats.failed = failed; - return ret; - } + if (ret < 0) + goto err_stats; if (ret) raw_mode = 1; } } - if (oob_required) - sunxi_nfc_hw_ecc_read_extra_oob(nand, nand->oob_poi, - NULL, !raw_mode, - page); + if (oob_required) { + ret = sunxi_nfc_hw_ecc_read_extra_oob(nand, nand->oob_poi, + NULL, !raw_mode, page); + if (ret) + goto err_stats; + } return max_bitflips; + +err_stats: + /* The caller retries the whole read in PIO mode. */ + mtd->ecc_stats.corrected = corrected; + mtd->ecc_stats.failed = failed; + return ret; } static int sunxi_nfc_hw_ecc_write_chunk(struct nand_chip *nand, @@ -1415,13 +1455,21 @@ static int sunxi_nfc_hw_ecc_write_chunk(struct nand_chip *nand, /* From the controller point of view, we are at step 0 */ const int nfc_step = 0; - if (data_off != *cur_off) - nand_change_write_column_op(nand, data_off, NULL, 0, false); + if (data_off != *cur_off) { + ret = nand_change_write_column_op(nand, data_off, NULL, 0, false); + if (ret) + return ret; + } - sunxi_nfc_randomizer_write_buf(nand, data, ecc->size, false, page); + ret = sunxi_nfc_randomizer_write_buf(nand, data, ecc->size, false, page); + if (ret) + return ret; - if (data_off + ecc->size != oob_off) - nand_change_write_column_op(nand, oob_off, NULL, 0, false); + if (data_off + ecc->size != oob_off) { + ret = nand_change_write_column_op(nand, oob_off, NULL, 0, false); + if (ret) + return ret; + } ret = sunxi_nfc_wait_cmd_fifo_empty(nfc); if (ret) @@ -1447,27 +1495,35 @@ static int sunxi_nfc_hw_ecc_write_chunk(struct nand_chip *nand, return 0; } -static void sunxi_nfc_hw_ecc_write_extra_oob(struct nand_chip *nand, - u8 *oob, int *cur_off, - int page) +static int sunxi_nfc_hw_ecc_write_extra_oob(struct nand_chip *nand, + u8 *oob, int *cur_off, + int page) { struct mtd_info *mtd = nand_to_mtd(nand); struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); struct nand_ecc_ctrl *ecc = &nand->ecc; int offset = sunxi_get_oob_offset(sunxi_nand, ecc, ecc->steps); int len = mtd->oobsize - offset; + int ret; if (len <= 0) - return; + return 0; - if (!cur_off || *cur_off != offset) - nand_change_write_column_op(nand, offset + mtd->writesize, - NULL, 0, false); + if (!cur_off || *cur_off != offset) { + ret = nand_change_write_column_op(nand, offset + mtd->writesize, + NULL, 0, false); + if (ret) + return ret; + } - sunxi_nfc_randomizer_write_buf(nand, oob + offset, len, false, page); + ret = sunxi_nfc_randomizer_write_buf(nand, oob + offset, len, false, page); + if (ret) + return ret; if (cur_off) *cur_off = mtd->oobsize + mtd->writesize; + + return 0; } static int sunxi_nfc_hw_ecc_read_page(struct nand_chip *nand, uint8_t *buf, @@ -1506,9 +1562,12 @@ static int sunxi_nfc_hw_ecc_read_page(struct nand_chip *nand, uint8_t *buf, raw_mode = true; } - if (oob_required) - sunxi_nfc_hw_ecc_read_extra_oob(nand, nand->oob_poi, &cur_off, - !raw_mode, page); + if (oob_required) { + ret = sunxi_nfc_hw_ecc_read_extra_oob(nand, nand->oob_poi, &cur_off, + !raw_mode, page); + if (ret) + goto out; + } ret = max_bitflips; out: @@ -1635,8 +1694,8 @@ static int sunxi_nfc_hw_ecc_write_page(struct nand_chip *nand, } if (oob_required || (nand->options & NAND_NEED_SCRAMBLING)) - sunxi_nfc_hw_ecc_write_extra_oob(nand, nand->oob_poi, - &cur_off, page); + ret = sunxi_nfc_hw_ecc_write_extra_oob(nand, nand->oob_poi, + &cur_off, page); out: sunxi_nfc_hw_ecc_disable(nand); @@ -1759,10 +1818,13 @@ static int sunxi_nfc_hw_ecc_write_page_dma(struct nand_chip *nand, if (ret) return ret; - if (oob_required || (nand->options & NAND_NEED_SCRAMBLING)) + if (oob_required || (nand->options & NAND_NEED_SCRAMBLING)) { /* TODO: use DMA to transfer extra OOB bytes ? */ - sunxi_nfc_hw_ecc_write_extra_oob(nand, nand->oob_poi, - NULL, page); + ret = sunxi_nfc_hw_ecc_write_extra_oob(nand, nand->oob_poi, + NULL, page); + if (ret) + return ret; + } return nand_prog_page_end_op(nand); From patchwork Mon Sep 14 03:01:13 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3319 Return-Path: X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from sin.lore.kernel.org (sin.lore.kernel.org [104.64.211.4]) by mxe881.netcup.net (Postfix) with ESMTPS id 3F42C1C2BD4 for ; Mon, 14 Sep 2026 05:03:23 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=gmail.com; spf=pass (sender IP is 104.64.211.4) smtp.mailfrom=linux-sunxi+bounces-25881-noreply=patchwork.local@lists.linux.dev smtp.helo=sin.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 104.64.211.4 as permitted sender) client-ip=104.64.211.4; envelope-from=linux-sunxi+bounces-25881-noreply=patchwork.local@lists.linux.dev; helo=sin.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by sin.lore.kernel.org (Postfix) with ESMTP id 1538425F7A for ; Mon, 14 Sep 2026 03:02:14 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id C5421350A18; Mon, 14 Sep 2026 03:01:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="bGO0SGXM" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-oo2-f43.google.com (mail-oo2-f43.google.com [74.125.231.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8517932470E for ; Mon, 14 Sep 2026 03:01:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.231.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789354911; cv=none; b=UAODfh2mi9qzAVb7eeCyzEWSz2UfSymrjYJzL+mfS+onYujpsLMT2A44ecUwGnu3Nb6HSRtwx0Rh5mREFDTJX1XewBvl9rN+4MJIyTDU9OUdmJQszTVppIgiKPclo6uGFHQX1qLlSRRwhkuRrBFlm/paRxi/Zynm9e2FFeM1AuM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789354911; c=relaxed/simple; bh=ovOsliEdUhvhRoeaXGSGPM3LycBRMZNPRXeHkTBG1HM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=tigYZ4WgkB1OettC9Wlnd+v0jNdinWMw4GKg2tMeB//MGG1jwjxOn5DITvEcTFag/l5tjyNxHCHOacxURGUa45I1Vn7G7eESNS/O85gdIRVSjC8qKDwDVzfATnMTLxUWg5s2Utua+5sv0k+s+ISEUGkKaYJgOEUSIVjeLpyuWFE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=bGO0SGXM; arc=none smtp.client-ip=74.125.231.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-oo2-f43.google.com with SMTP id 46e09a7af769-7fccd4c3f36so1513270a34.3 for ; Sun, 13 Sep 2026 20:01:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789354908; x=1789959708; darn=lists.linux.dev; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=b70jsSBwLMejAy7LligcsivCdZpJr/KiRJCHlaFZ8JI=; b=bGO0SGXMn6YAFFhZ5ilitkRkKF8TEZctU/VBuot4Rlz6GHRMJ1sCELc0Wttzxq3/yM mvNjC1V5QlHCnlkJskcDM2H+ESnCdmlt/XlK5Ai2AsrUU6oSFJn4rww7OxXlI0Ztt7md 35sHzacsyqdXy0g/b1UjC5ppD+C5K24eP2w5qSnhmpVV3bvPxFtb+sXdi+WbYxa4Tnqg HA8cTxGB/PtzkiEzZN0ZTf5q8iFMr/k7dnIObsSpkyYQLZtUjWe7yZ3D1ZHlEoZmXZD1 x4HzgCE6TeGpWBGwJn7f2T5O2VjcBhxXohj4dZsNUu0QwN+fRnc8YQM/mNeFyw58VRtx +ltA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789354908; x=1789959708; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=b70jsSBwLMejAy7LligcsivCdZpJr/KiRJCHlaFZ8JI=; b=rQtpa+aT+Wv/sLnDH1DqbDDmAUeRy4V02z37kZ+gQELc/KEtbantY0IGmLq9TC+yCF /EjrhLiqeIF9WfOESiKnQ1Fk34MI6h//X1RpsI8VQZrYVFae3nu/t6WFOkASuzusPB2e pB1CXrhsPySXZRdh6+4ztfnjXXg6On+S5bFpHPDK+vT+2lekD/wCwxk2dAJJwtKbKQ9N 3u0puYK7IC271cPGLJXtoTr1R/FNak8scgJTvlh2H09/+2N+yHT/TRNnpo50J0T4yuM7 gjD5+mkfmf1JPjw/4wDwRXvwt3o4CxKP1HgIqUst0Ksru6KgkYE0QlQaU5OSllbLh1Sq TR8w== X-Forwarded-Encrypted: i=1; AKwUvBzn7SwSPKuA39rpTixLM1aiNAgoM4ICDQWBmA0n1WVM8qlmX3rfXBZbuLlbuzZ8Tbgq6zQBVrWRt+/XiQ==@lists.linux.dev X-Gm-Message-State: AFuF++n2BxY96k/+joLvWGLDL2nCm99fNi+ipZrTxBOIGGyAl3wZm/8m jzHoS9pKdoAfcVlUZzr4LOleuc2PvkEqfPu3siBH1L2eFa896TjIJfwC X-Gm-Gg: AYBFou2YPAHmAe12PdxsSYGTf/jPjUjECkG60fQSU9W1kvFBJ6OnJm1ycz21uW+WGSi EkVE6h50gwTBBGBun+bcdExVEdB71W63N47NFT+4Ph7DkV//CFT+Ol7mc7c1iY4qjOlMm2Mkb/b 6NrSYIvUkz9NNt/cHGKoZrskcFzSbDkc96fHeoWJuFZ212wDU1Uy/9+lqk7qW4beilA3TDEVuOL xjl3PJD7XEZXMTUhbnoDKGMe8GEhZtZYWJOa/gbsBE0cLQYAbewi+28zApnHeb7alSKbOxjEpg8 p/6esuKJyvkEuU0Ss1FIG4hsCYaCgXuesc+TcFXK6MVN/fVhr06JIEkTBdB5uUn5wjWqQ7sqDgG V26WZEJ2tfVCdeuQWNgw65bA3wihFoYQupAx13E1Rl35Mgu4P/fbqIEgqOfzr5gQNghn4kZPv8B RJA7ZVsCmTqvuAaeUB8ZOG/JDxS5CznYOKbLfRaj6KKb9tJYL122uBSToZvVV4Y/bnpU7lp9DRj tlPtd0pmIjoOXxSYSuxRHFqdn8OarehTisVj5Z9cuX9GAKCh+xwOY3EAQM9gAUROZyQwd9u+MK+ QoemYNz/FszDi36VHVVp+TuF67CndYtRMG1Lh3tReLwasx44gkm9czOEjtXRtshP753AuA2nrPN 9owGYPtPgf2qXIw8uaAj/yMJ/VHEGGg== X-Received: by 2002:a05:6830:4c18:b0:7f7:f55a:4bcc with SMTP id 46e09a7af769-80897c868f2mr541126a34.8.1789354908010; Sun, 13 Sep 2026 20:01:48 -0700 (PDT) Received: from [127.0.1.1] (184-96-157-145.hlrn.qwest.net. [184.96.157.145]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-803f60feba1sm10619014a34.13.2026.09.13.20.01.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 13 Sep 2026 20:01:47 -0700 (PDT) From: James Hilliard Date: Sun, 13 Sep 2026 21:01:13 -0600 Subject: [PATCH v5 07/18] mtd: rawnand: sunxi: avoid a second program confirm for OOB writes Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-7-7d711076a6f7@gmail.com> References: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-0-7d711076a6f7@gmail.com> In-Reply-To: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-0-7d711076a6f7@gmail.com> To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Maxime Ripard , Richard Genoud , Masahiro Yamada , Boris Brezillon , Brian Norris Cc: linux-mtd@lists.infradead.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, James Hilliard , stable@vger.kernel.org X-Mailer: b4 0.15.2 X-MORS-Enabled: yes X-MORS-DOMAIN: patchwork.local X-MORS-HOSTING: hosting172546 X-MORS-USER: hosting172546 X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= The hardware-ECC OOB writer delegates to the page writer, which already issues PAGEPROG, waits for completion and checks the NAND status. The OOB wrapper then calls nand_prog_page_end_op() again, sending an extra program confirm without a corresponding program setup. An error on this redundant operation is returned even though the page writer has already succeeded. Return the page writer's result directly. This leaves both PIO and DMA responsible for completing their own program operation and preserves their error results, including for bad-block-marker writes. Fixes: 25f815f66a14 ("mtd: nand: force drivers to explicitly send READ/PROG commands") Cc: stable@vger.kernel.org Signed-off-by: James Hilliard --- drivers/mtd/nand/raw/sunxi_nand.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index 72b79f893e29..41d6560d7df7 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -1843,15 +1843,10 @@ static int sunxi_nfc_hw_ecc_write_oob(struct nand_chip *nand, int page) { struct mtd_info *mtd = nand_to_mtd(nand); u8 *buf = nand_get_data_buf(nand); - int ret; memset(buf, 0xff, mtd->writesize); - ret = nand->ecc.write_page(nand, buf, 1, page); - if (ret) - return ret; - /* Send command to program the OOB data */ - return nand_prog_page_end_op(nand); + return nand->ecc.write_page(nand, buf, 1, page); } static const struct sunxi_nfc_timings sun4i_a10_nfc_timings = { From patchwork Mon Sep 14 03:01:14 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3321 Return-Path: X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from tor.lore.kernel.org (tor.lore.kernel.org [172.105.105.114]) by mxe881.netcup.net (Postfix) with ESMTPS id 8F3F71C3D83 for ; Mon, 14 Sep 2026 05:04:51 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=gmail.com; spf=pass (sender IP is 172.105.105.114) smtp.mailfrom=linux-sunxi+bounces-25882-noreply=patchwork.local@lists.linux.dev smtp.helo=tor.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 172.105.105.114 as permitted sender) client-ip=172.105.105.114; envelope-from=linux-sunxi+bounces-25882-noreply=patchwork.local@lists.linux.dev; helo=tor.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by tor.lore.kernel.org (Postfix) with ESMTP id 1B0EF3042C for ; Mon, 14 Sep 2026 03:02:21 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 347873537E8; Mon, 14 Sep 2026 03:01:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="FhUk+v4A" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-oo2-f41.google.com (mail-oo2-f41.google.com [74.125.231.169]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DFB7F349CE8 for ; Mon, 14 Sep 2026 03:01:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.231.169 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789354913; cv=none; b=YZ/ffR5Cucng2zk0yB1SDP5YqjNGvMOfnZh+a1SWVBxVsZ9cB1JBOKYrDolQT21JZHtNn4LLpnHL+1F63j7Z6Gip73n1a5dXiCL9P2QF/i6FcpYhzeKmtozyqfMrksjNgJlFJZTHaNaRTNjKh+EQG/jZ8/9j++DmzFXackzS50U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789354913; c=relaxed/simple; bh=YbBF9laHAErhZzSaGZGDzYG7q1LarpeBoJ8ap1tchQo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=GoB9a2eDDNDa5apsW6CYTD4UroRClBxu6kS520EQP/k0a4El/RcxdVfpJvGdbasCVTf2HwqYXD5+awXgDQm7beVt2rhx0+xDLdQvZ/vti6dmup52gBLSJVd7nQE/5lsaGGvwM6bUAxcoNjgNrfgwc7MX5eLue36QRV1qtD9d1Ys= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=FhUk+v4A; arc=none smtp.client-ip=74.125.231.169 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-oo2-f41.google.com with SMTP id 006d021491bc7-6b1ae739df5so478226eaf.1 for ; Sun, 13 Sep 2026 20:01:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789354910; x=1789959710; darn=lists.linux.dev; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=A0CrISCG3enxLUNERhlMVwT+4sBOgXXXdTBmRqqtC4g=; b=FhUk+v4A95js4MFPk0NoH1chDGUxzxQ1CxXF8612LS82Pg6CY6PHPrUBszs/qlhEMU bnDzyNwWv1Ik+gUrfWtqr0xGCw7eu3PLHw5hlV5YSrsU58OxK6Mu1wXtOCt7aK0yxGA6 NRb1rY+KQhaI4HwiBL3cb0pAIkXO8jRmnB8Lwr0wjTi4qMPhPI9Fu/E4rr1pBXZKGen3 mt3a4Q1FqJf92gRpxTRxXS68pKf8iAPsXGomNtdNBy5zhRMYNUL7cILeJFk0Hb2GjkRy 7oVLc0kMyY03KytSH6UBuOVVqdRg4NirED2w4k1YEgH9DtWTgj3hQrSUbHrWaX8LJr73 F+lw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789354910; x=1789959710; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=A0CrISCG3enxLUNERhlMVwT+4sBOgXXXdTBmRqqtC4g=; b=a46QTe2bRuaVcB2plzFuBvyS+ajIJxCRc0xzJUucJp2iIs9emTwGN8XLmEFvmwxwKE H7pLvAAX5pTuhsViKlGY0zd/bwYZ8NcV6GtDyZP2sEX59aEXcBmHAtaQCR+9jyBTd7ay 1Lq5m/Qn2T+cLNXgIiTCELzAOBGF39FqMIgXYwy/x/UKxyTqG2QfmZ4CvbCaRk+LV4TP zyVF26e9m2XzrEWCy1faa0KlnHcgjAN29cptiWyOqb8pLiGrIvn47AwuiFyUjHUVABEr q99sNDl+iFhiyQIAiVeeWrlxtOhfnIVOuQIkXZ3BvkqJGJMSSYUm8TuZZyAI+/OGdf9T rNcg== X-Forwarded-Encrypted: i=1; AKwUvBxWRUbPyIRl3njBBbLDvGxXpvlzpovhqmGDltxsaSnkDJg+GIii5Nlm54guSAG3K13sbar45FPbN6B4tA==@lists.linux.dev X-Gm-Message-State: AFuF++kje+DBUN5IKGvknNvU+pUZTEQyQzKAEHwDZDXjwcZYqHy2zSdY 0pdupwS7HxhJhbIqS6QjEnMgQCeYeW9zxvpI21RHeWtzvI2XlNJ5dAud X-Gm-Gg: AYBFou3Zl+i+YB2bEEcBGIZxlsyuohh54q7gS2vxfB/h6Bi3RvbRycPluFLwOGdSzge lUv7VcO7xIocjlkcH5sh2yhjU5LLheOSS93fKGHXAbcpQntN/FfIQ4waeujjL7zyYGY6ZyxcR/R ztTPVKPALQWOBiXRUTjpfBIkuJbiiD8DGZIUgRnLNqsDMVlAD1NN2skUnwl7TnItWnlTxbVnTKg Wm/0IhOjnMZEQLU/JIRrvxLeCIZYZsiJi1KYZ4KiU3i7WGdKqnq283Bgb8Jg1dno6xDK/2q6d17 kG9TYspfkCnLI6TNGPBzjmXmth3eEtAZ/JQF12T/RAaVmV1VJjMNmZmES0gqKobyviG114Wcnn+ JflLdmi5eVu4fX1uWnwz9yt9Dpe/BfQgoGJlkX4wkCU1KwAXj+7XlM4zZJJBkdNCDhRpfiDtl5A 1GRQ5tNz6nep2BEZVzobrau7jBH6qMr0aJqnTNtDVqIDjqqdB/JNZLdfgnzmzGFkjlHpe2xkKN2 D/EpxAXOwF02eIxMclKkfdiRkCT3R6iebm1wlkR/Lzg5bbq4sKvWw/lF3bKv6STbgQ9M02+kUEI ZJyTXmJLhvAZcJSQYRuyKJ3mLeyytl7vypgNh3W6wlYxk/aufRbG8AQ8njINmr9NOGrhrm2N0Yl +idfhZuNK4Irsg0wN59nNnU1BV3LENhA19LQHi79rmw== X-Received: by 2002:a05:6830:4486:b0:7f9:555:1def with SMTP id 46e09a7af769-808863d0ac9mr310838a34.11.1789354909720; Sun, 13 Sep 2026 20:01:49 -0700 (PDT) Received: from [127.0.1.1] (184-96-157-145.hlrn.qwest.net. [184.96.157.145]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-803f60feba1sm10619014a34.13.2026.09.13.20.01.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 13 Sep 2026 20:01:48 -0700 (PDT) From: James Hilliard Date: Sun, 13 Sep 2026 21:01:14 -0600 Subject: [PATCH v5 08/18] mtd: rawnand: sunxi: avoid redundant column changes for extra OOB Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-8-7d711076a6f7@gmail.com> References: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-0-7d711076a6f7@gmail.com> In-Reply-To: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-0-7d711076a6f7@gmail.com> To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Maxime Ripard , Richard Genoud , Masahiro Yamada , Boris Brezillon , Brian Norris Cc: linux-mtd@lists.infradead.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, James Hilliard X-Mailer: b4 0.15.2 X-MORS-Enabled: yes X-MORS-DOMAIN: patchwork.local X-MORS-HOSTING: hosting172546 X-MORS-USER: hosting172546 X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= The PIO write loop tracks the absolute NAND column in cur_off, while the extra-OOB helper computes an offset relative to the start of OOB. Comparing these values directly always requests a column change, even when the last ECC step has already left the cursor at the start of the extra OOB bytes. Include the page size in the comparison, matching the extra-OOB read helper. Keep the explicit column change when the caller does not track the cursor, as in the DMA path, or when the current column differs. Signed-off-by: James Hilliard --- drivers/mtd/nand/raw/sunxi_nand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index 41d6560d7df7..13dc0af56eb3 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -1509,7 +1509,7 @@ static int sunxi_nfc_hw_ecc_write_extra_oob(struct nand_chip *nand, if (len <= 0) return 0; - if (!cur_off || *cur_off != offset) { + if (!cur_off || *cur_off != (offset + mtd->writesize)) { ret = nand_change_write_column_op(nand, offset + mtd->writesize, NULL, 0, false); if (ret) From patchwork Mon Sep 14 03:01:15 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3324 Return-Path: X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from tor.lore.kernel.org (tor.lore.kernel.org [172.105.105.114]) by mxe881.netcup.net (Postfix) with ESMTPS id 934851C2BD4 for ; Mon, 14 Sep 2026 05:06:27 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=gmail.com; spf=pass (sender IP is 172.105.105.114) smtp.mailfrom=linux-sunxi+bounces-25883-noreply=patchwork.local@lists.linux.dev smtp.helo=tor.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 172.105.105.114 as permitted sender) client-ip=172.105.105.114; envelope-from=linux-sunxi+bounces-25883-noreply=patchwork.local@lists.linux.dev; helo=tor.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by tor.lore.kernel.org (Postfix) with ESMTP id 9A1A631325 for ; Mon, 14 Sep 2026 03:02:32 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 3AD22331EA0; Mon, 14 Sep 2026 03:01:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="LMfcqoOn" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-oo2-f42.google.com (mail-oo2-f42.google.com [74.125.231.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 520D935295C for ; Mon, 14 Sep 2026 03:01:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.231.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789354916; cv=none; b=SYO/xDOc7MTBPS7qtORrzOUrcqPkPcW/YpLxrAlc2vQK00FfpyCEHgfhVWHnaYeu5+nsc/WCyoZQXCBeluKEcnUYzubRKKgYANiESeP0emK6LpyqOPJ7WqBjL8RLGRBZV4+3ksjdoPslTVDIcSs58hIssIs0OAjYMHSZgKPgEGM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789354916; c=relaxed/simple; bh=o3NPqjDQtjCU8+r59n9WbZaWXsVSsfQ6oMXDXHHDqIA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=IS+fPojB7jI8Ff9BrV21PD/xYMIp171sqiqAj77C8EO+ApGZupSq1BpJQSTu6L+ldQiS8Pt7WQ5loM1r/kedi0g2nNU2lskhOWhGlUMIhmvLMmIC2VF7TukBB60dLmlM2L8OESKy0tGrtPFHZJPsScCgsprRuuKlcRwP30ccBOI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=LMfcqoOn; arc=none smtp.client-ip=74.125.231.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-oo2-f42.google.com with SMTP id 46e09a7af769-7f4f0c89e35so966499a34.2 for ; Sun, 13 Sep 2026 20:01:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789354911; x=1789959711; darn=lists.linux.dev; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=3gIMuO5LgsmThmwiwqzrGE8ky+825OhMeKFgclE6Udc=; b=LMfcqoOnOrhw4pzyqd7opaCmqbG8jA2V4Bz36P0vyMXOyeEw+syKMGrz132MlnebMi dWkm2efghHAreHpyJ7Oc8yvq7HIxiAw3LqjHHkbhOU3vy7Fk/0NRdQPwBHCxxTUW4hNV kvL2Sv8r6pVwP12fJhkLS3Q5PzwnzluSTEDU7Up4KHBJVpvHx5XOl/B9dsdBtA6QhM+b rB/pRrPsg7IE8NimXrnN5dcGeEmu4TCMoXRUo3hCw9im96O5loB9wdftugG+o3718g1g /oMVt28JHmNKmckTm4NxQSRf/1yzm27+RsqJOxk77Bqoj4iZ60dcwuFVWP8ytSqkEwsq IFgw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789354911; x=1789959711; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=3gIMuO5LgsmThmwiwqzrGE8ky+825OhMeKFgclE6Udc=; b=nmszhxQL1R/ZcWMvs52h5IMXBqYFDH/7T4tsWIzTXnDmMmdIFiA/5BZK7y6XyB7hx/ FXNeJYvmISehR9TKa+UajP2kIPFkUCywo7KWxq/DJoB2OjkJbRXf038Z2hH2Mqwa23ht zaQIrpSTZIHdf9tRJ4/zm8MjZ7llMunY4bNhYitzygSD7RnrYyatWwM7kHAjRFqWzznZ /H9w9XnKSagaOcz8COcryHBQBq5PBmKOlHZa85oujHwAjg+ylrx1/rOdY6ugRgukFf9l h3uS/Z72dvBKNHpTDaCRFPhKUcwYhqPamzWJyUp1ahIhf/fKJ53ug4b1Mc1XCySX0wEZ yxkg== X-Forwarded-Encrypted: i=1; AKwUvBxLvFEFFc/OTNbtfFOnJNngnvUYm6MRIp9NsnmJ9O/715QlUht50p6+Jb/XE1K5+f8BFniiA/E2cYFoIQ==@lists.linux.dev X-Gm-Message-State: AFuF++l75cR8MinrDGDet76FOVlZ+evGWY865WTh5d2St9MYbLQa33aI IMhUkmzvsKvXwzXfwikIZTQnsT1ERqePkRA/moCCVgR9hbopoXmH7Cri X-Gm-Gg: AYBFou1XIL1S6Rh/yxFfzyBy91Z39s3MRQWJS/yITFV9w67tbCnzChmPCbSU1cFdc16 lEoodxSN0xM8ihF5cbjE+fmrR8p13nKES3ZkyKrAoFpYz2ZMJxhruHm/58OeZxCyUzIf/2uhxyJ shSkb23rezo5NZzahRC5gwi5eQlRUVsaocI12x+w6ktild2vdNMa59Epdazssn3Z+Iny+95LjV0 JvmerhPdQV2mMMk60nxFoTWeHlupW3RMJ3GWF9EjwfzrbOBZcy6iWhAT2ehkZkfBXMVfaviSQJ3 zSYCDLdLYywU2rAmLUVtcqEIlJ24wM4fiD02sgkuwVmcJD9oZ+u4/A45pKFp+Ml+kedg2T+xCR7 tl8a9KH/gHrWnC/Y2T6ZnXrsTR/9M39fPFpNBV/a9o7oePNnTDp4Nb5DNbpEw1zva2rbzfND3zw Yupyd32vzey+7whnF/HsaDgoAWgvEkTAvGcCqJXqKZrSmm9abBYHNt2GzuLpfoFCnWPrGERtEMh BM0ZNGEqiU7u7iPcyydcs6SPUe9iiD95Re3mEk8bxi3AmRN4eh/fQEMzZt1tgIkxvaefXBV8lLm 6wJmCLqPmMaX/2IxL39Gc1TG0zfnxOBCzQpau9XclogHoiI3XcQboeBRy5yYatjXasjjW8qfuHc QMLPWFKLThIyc0LGnDxOre7UIevhR4A== X-Received: by 2002:a05:6830:2a8c:b0:7d7:d524:bc88 with SMTP id 46e09a7af769-80897c891b2mr304523a34.10.1789354911083; Sun, 13 Sep 2026 20:01:51 -0700 (PDT) Received: from [127.0.1.1] (184-96-157-145.hlrn.qwest.net. [184.96.157.145]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-803f60feba1sm10619014a34.13.2026.09.13.20.01.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 13 Sep 2026 20:01:50 -0700 (PDT) From: James Hilliard Date: Sun, 13 Sep 2026 21:01:15 -0600 Subject: [PATCH v5 09/18] mtd: rawnand: sunxi: use page reads to reposition small-page NAND Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-9-7d711076a6f7@gmail.com> References: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-0-7d711076a6f7@gmail.com> In-Reply-To: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-0-7d711076a6f7@gmail.com> To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Maxime Ripard , Richard Genoud , Masahiro Yamada , Boris Brezillon , Brian Norris Cc: linux-mtd@lists.infradead.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, James Hilliard X-Mailer: b4 0.15.2 X-Rspamd-Server: rspamd-worker-8404 X-Spamd-Result: default: False [-1.16 / 15.00]; BAYES_HAM(-5.50)[100.00%]; RBL_SENDERSCORE(2.00)[172.105.105.114:from]; SUSPICIOUS_RECIPS(1.50)[]; DMARC_POLICY_SOFTFAIL(1.00)[gmail.com : SPF not aligned (relaxed), No valid DKIM,none]; MAILLIST(-0.15)[generic]; MIME_GOOD(-0.10)[text/plain]; BAD_REP_POLICIES(0.10)[]; HAS_LIST_UNSUB(-0.01)[]; PRECEDENCE_BULK(0.00)[]; FROM_HAS_DN(0.00)[]; DBL_BLOCKED_OPENRESOLVER(0.00)[tor.lore.kernel.org:rdns,tor.lore.kernel.org:helo]; TAGGED_RCPT(0.00)[dt]; FORGED_SENDER_MAILLIST(0.00)[]; FREEMAIL_CC(0.00)[lists.infradead.org,vger.kernel.org,lists.linux.dev,gmail.com]; RCPT_COUNT_TWELVE(0.00)[20]; RCVD_COUNT_FIVE(0.00)[6]; ASN(0.00)[asn:63949, ipnet:172.105.96.0/20, country:SG]; R_SPF_ALLOW(0.00)[+ip4:172.105.105.114]; FREEMAIL_TO(0.00)[bootlin.com,nod.at,ti.com,kernel.org,gmail.com,sholland.org,socionext.com]; FREEMAIL_FROM(0.00)[gmail.com]; TO_DN_SOME(0.00)[]; FROM_NEQ_ENVFROM(0.00)[jameshilliard1@gmail.com,linux-sunxi@lists.linux.dev]; FORGED_RECIPIENTS_MAILLIST(0.00)[]; RCVD_TLS_LAST(0.00)[]; TAGGED_FROM(0.00)[bounces-25883-noreply=patchwork.local]; MIME_TRACE(0.00)[0:+]; MID_RHS_MATCH_FROM(0.00)[]; ARC_ALLOW(0.00)[subspace.kernel.org:s=arc-20240116:i=1]; RCVD_VIA_SMTP_AUTH(0.00)[] X-Rspamd-Queue-Id: 934851C2BD4 X-MORS-Enabled: yes X-MORS-DOMAIN: patchwork.local X-MORS-HOSTING: hosting172546 X-MORS-USER: hosting172546 X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= The hardware-ECC read paths use random-column commands to revisit main data and OOB. Small-page NAND does not support these commands, and nand_change_read_column_op() rejects pages of 512 bytes or less. Ignoring that error does not provide a physical reread: the erased-chunk check can instead inspect stale buffer contents. Introduce a read-column helper which starts a new page read for small-page NAND. Let the NAND core select READ0, READ1 or READOOB and send the row address. Keep random-column commands for large pages. Pass the page number through the erased-chunk fallback and use the helper for normal OOB reads as well. Retain transport errors and only classify a physical chunk after all its rereads succeed. Read exactly the requested region so the tracked column still matches the start of any trailing OOB. Also select PIO callbacks for small-page hardware ECC even when DMA is available. The DMA page sequencer uses large-page random-column commands; PIO can stream the single 512-byte ECC step and its OOB without them. Keep the ECC geometry checks unchanged. In particular, the usual 512+16 geometry still cannot fit the controller's minimum 28 parity bytes and four user-data bytes. This fixes the command handling for small-page geometries that pass those checks, not a demonstrated regression on a previously working 512+16 device. Software-ECC and raw callbacks, large-page DMA eligibility and the on-flash layout are unchanged. Fixes: 1fef62c1423b ("mtd: nand: add sunxi NAND flash controller support") Fixes: 614049a8d904 ("mtd: nand: sunxi: add support for DMA assisted operations") Signed-off-by: James Hilliard --- drivers/mtd/nand/raw/sunxi_nand.c | 40 +++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index 13dc0af56eb3..e29638c828ca 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -1079,6 +1079,16 @@ static void sunxi_nfc_hw_ecc_update_stats(struct nand_chip *nand, } } +static int sunxi_nfc_read_column(struct nand_chip *nand, int page, + unsigned int column, void *buf, unsigned int len) +{ + /* Small-page NAND needs a new READ0/READ1/READOOB and the page address. */ + if (nand_to_mtd(nand)->writesize <= 512) + return nand_read_page_op(nand, page, column, buf, len); + + return nand_change_read_column_op(nand, column, buf, len, false); +} + /* * Return 1 for an erased chunk or 0 for an uncorrectable chunk, with ECC * statistics updated in either case. Negative values report transport errors. @@ -1087,7 +1097,7 @@ static int sunxi_nfc_hw_ecc_read_error(struct nand_chip *nand, u8 *data, int data_off, u8 *oob, int oob_off, unsigned int user_data_sz, - unsigned int *max_bitflips) + unsigned int *max_bitflips, int page) { struct nand_ecc_ctrl *ecc = &nand->ecc; unsigned int oob_len = ecc->bytes + user_data_sz; @@ -1095,13 +1105,12 @@ static int sunxi_nfc_hw_ecc_read_error(struct nand_chip *nand, /* Check the physical representation for bitflips in erased pages. */ if (nand->options & NAND_NEED_SCRAMBLING) { - ret = nand_change_read_column_op(nand, data_off, data, - ecc->size, false); + ret = sunxi_nfc_read_column(nand, page, data_off, data, ecc->size); if (ret) return ret; } - ret = nand_change_read_column_op(nand, oob_off, oob, oob_len, false); + ret = sunxi_nfc_read_column(nand, page, oob_off, oob, oob_len); if (ret) return ret; @@ -1169,7 +1178,7 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct nand_chip *nand, const int nfc_step = 0; if (*cur_off != data_off) { - ret = nand_change_read_column_op(nand, data_off, NULL, 0, false); + ret = sunxi_nfc_read_column(nand, page, data_off, NULL, 0); if (ret) return ret; } @@ -1179,7 +1188,7 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct nand_chip *nand, return ret; if (data_off + ecc->size != oob_off) { - ret = nand_change_read_column_op(nand, oob_off, NULL, 0, false); + ret = sunxi_nfc_read_column(nand, page, oob_off, NULL, 0); if (ret) return ret; } @@ -1217,13 +1226,12 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct nand_chip *nand, return sunxi_nfc_hw_ecc_read_error(nand, data, data_off, oob, oob_off, user_data_sz, - max_bitflips); + max_bitflips, page); } else { memcpy_fromio(data, nfc->regs + NFC_RAM0_BASE, ecc->size); if (oob_required) { - ret = nand_change_read_column_op(nand, oob_off, NULL, 0, - false); + ret = sunxi_nfc_read_column(nand, page, oob_off, NULL, 0); if (ret) return ret; ret = sunxi_nfc_randomizer_read_buf(nand, oob, @@ -1285,8 +1293,8 @@ static int sunxi_nfc_hw_ecc_read_extra_oob(struct nand_chip *nand, return 0; if (!cur_off || *cur_off != (offset + mtd->writesize)) { - ret = nand_change_read_column_op(nand, mtd->writesize + offset, - NULL, 0, false); + ret = sunxi_nfc_read_column(nand, page, mtd->writesize + offset, + NULL, 0); if (ret) return ret; } @@ -1386,9 +1394,8 @@ static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, uint8_t *buf if (oob_required && !erased) { /* TODO: use DMA to retrieve OOB */ - ret = nand_change_read_column_op(nand, mtd->writesize + oob_off, - oob, ecc->bytes + user_data_sz, - false); + ret = sunxi_nfc_read_column(nand, page, mtd->writesize + oob_off, + oob, ecc->bytes + user_data_sz); if (ret) goto err_stats; @@ -1416,7 +1423,7 @@ static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, uint8_t *buf ret = sunxi_nfc_hw_ecc_read_error(nand, data, data_off, oob, mtd->writesize + oob_off, user_data_sz, - &max_bitflips); + &max_bitflips, page); if (ret < 0) goto err_stats; if (ret) @@ -2305,7 +2312,8 @@ static int sunxi_nand_hw_ecc_ctrl_init(struct nand_chip *nand, ecc->write_oob = sunxi_nfc_hw_ecc_write_oob; mtd_set_ooblayout(mtd, &sunxi_nand_ooblayout_ops); - if (nfc->dmac || nfc->use_mdma) { + /* The DMA page sequencer uses large-page random-column commands. */ + if (mtd->writesize > 512 && (nfc->dmac || nfc->use_mdma)) { ecc->read_page = sunxi_nfc_hw_ecc_read_page_dma; ecc->read_subpage = sunxi_nfc_hw_ecc_read_subpage_dma; ecc->write_page = sunxi_nfc_hw_ecc_write_page_dma; From patchwork Mon Sep 14 03:01:16 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3325 Return-Path: X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from tor.lore.kernel.org (tor.lore.kernel.org [172.105.105.114]) by mxe881.netcup.net (Postfix) with ESMTPS id 819C91C2BD4 for ; Mon, 14 Sep 2026 05:06:41 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=gmail.com; spf=pass (sender IP is 172.105.105.114) smtp.mailfrom=linux-sunxi+bounces-25884-noreply=patchwork.local@lists.linux.dev smtp.helo=tor.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 172.105.105.114 as permitted sender) client-ip=172.105.105.114; envelope-from=linux-sunxi+bounces-25884-noreply=patchwork.local@lists.linux.dev; helo=tor.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by tor.lore.kernel.org (Postfix) with ESMTP id CA3AD315B4 for ; Mon, 14 Sep 2026 03:02:34 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id D1B913403E7; Mon, 14 Sep 2026 03:01:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="QHyhyj9i" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-oa2-f12.google.com (mail-oa2-f12.google.com [74.125.231.76]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D4CDA356778 for ; Mon, 14 Sep 2026 03:01:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.231.76 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789354916; cv=none; b=sQSVfuco9uyqedJ5gm5rCBc0zJZecZVgQcI+f6rSSEoxan4thMSHgtCN+g/Me6WA6JXbbIMe//iL1rpOmJLiqFsD8KZ8U99bXeGKNh0nFl38/+1Vlwmc3zQIuicCQc4yt3pfYgNuxj/hHab+AjhyYE5aaB35Kt4hYrfrspjYcbg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789354916; c=relaxed/simple; bh=8iWGfrxZbd83xo/SM/xyg7dUuKcpNxJMOXno5pQpLKA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZxawK5nFtoPxUOMWLEzW4W1gdlvizgl3O14R+MFIUndlpAYlq3RoXj+RYD0K7uGNxGHxH1+fQM+o2z4Jm5oTEXeppH8zQ2v4xeehIs2ofGm+oKSeV7C0L0OCIl0xZ9mHKJ0tMAwFaEx8hO0sy22zpmJWmL79BZO0YdhqCaBdNA0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=QHyhyj9i; arc=none smtp.client-ip=74.125.231.76 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-oa2-f12.google.com with SMTP id 586e51a60fabf-466cc9b2f1dso1214204fac.0 for ; Sun, 13 Sep 2026 20:01:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789354913; x=1789959713; darn=lists.linux.dev; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=+fPDpmxms4ltLqy8HoVcRfs0if/gr5P6/mMAZPDSTxM=; b=QHyhyj9icU0tR8i/1sf0ddt4C/Hz/LCe+FONEoxTe6FzpZWl7Ld9NR9MXfWCQEnP8P tNTjEykcGNqsdOdfRXRZqpJ+j3MYmmxMlU8srLa9uPjkuUuLmhl4BVHuEJ7RKJc+D2W+ Taz0lSOo4XtnvetMjS85OLwxAZ+Jzxq4c8SOxeFkwcJKceo+cZ1UodSpe3LBnrypzegB gOerXEfPyashDlv1/ujshAQe84cQRSwKQllMc4xTlUwryBA7/Vj7cOBB5CYTL82M4evD LA18MH3FHWTm9PEPhBEtXRq6dY8O8Q54RSBx3Qk+re4VEppabP6xcUdtTghfD5hlNW5N arYg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789354913; x=1789959713; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=+fPDpmxms4ltLqy8HoVcRfs0if/gr5P6/mMAZPDSTxM=; b=XaWUJoTLgn9eCyR+IL7uByJb8mSr2euudJoY9t0enSYTk+Jsykc1TWoyLxT3wI26HI lAcmkHVB29yeVo3hvcoKJEWnpzfdiYDxbryqx0/+cxwvWgZ3VGd252oj6+CzaTXZC/23 V5lb4Squzjb8ISIVOoLSuigX1XHntXQh6iQ+Y1IkWshZk7LLxYgwWt4P8Svfdx48y+bB E905ZsENTgrrT/9dNweb+FvfWrAHTGnh+1PJlZjICrh3i9iX/ykDMJ8KZqkGSXauow6C ZXZj/GKSSFyJrhx6bWU20F3L27bktJqDcZYlOqyk00nDjgQRgfg6UnDq5y5KNugV0uAq S5GQ== X-Forwarded-Encrypted: i=1; AKwUvBzGGeb5IgeOCXvG6IXSJPl6S9sRhN66+ex5ckWPfvajRTZ8EQ3nHzBiAdtsJOlP3y3OPGjHskKeC9I6Og==@lists.linux.dev X-Gm-Message-State: AFuF++mDuI+g3GyoCFS7fo+hhBR4d8nxKWZ556A567hv//m/DpIBnw1z V/tZWdFPTRym49X+/Coh+3gJ2JYgo/A/Cn1caUznC7871GTVFCja+JyO X-Gm-Gg: AYBFou1m6+ypADtlykhaJ6kEhL4QRtutRP0Bnl+Ukf7dtSQuOHoewY1hNomwZxJvveL rKO9NZzhnJ8OpGhAi8GZfbag2WuNktxd142UDd7+d8iqDfaTCAK3HD0pyJz+94virc+6kXO6IJK nU6Uhq10ALeRI7nAQL/4Tj+kQFVzcFHX9FI+8J7LmWLsnAKje3owk9tTnpP8Co01DUflx/sACLn 9oy/1zbvx7smxAak2fIHCE29+fAYJB7xfls0qCp3tase9QyLewjEQzfBc8LJFvSSjitAgB9HlyJ 6coXy11w1U2hBfrVRb+43Wc4NntVRK8tRCxQ2gZ9kTLXnIZfruH/YkKUXy+w91fgmzFkID6fdrN /rsFHG3ijl/vSsZp6UJm2MlpjOF9XLJ6yIlJVXSt98lWr388atVSXd0qDd3KyQTDOV9fymb+y7F VUZO2I6Uazrn8MDuDVBBKWGTuwnwF7BN4Zc75h81Zyr126mKzhFnhsvY2GUT9ZtlUV4fUdzEBlS Hrl1npCwonUhjPoSwzyLBJV2NSzWFaIC8NxMnjg6SGbhASTefQlzBCkC5MNKxO+yP9BC14DFMMK P/OjHkFmTJUBPFOMJS92Hqiueebauvcvr4vNCYbQ2/9zr1aFLBdoQD1fqHplx7DaC2a+6nbYqO3 jLl2Uz6Vkiiw6+ikyEPxpXYDv1k4omQ== X-Received: by 2002:a05:6830:2548:b0:805:b4a8:724e with SMTP id 46e09a7af769-80884ad0cb3mr373073a34.6.1789354912706; Sun, 13 Sep 2026 20:01:52 -0700 (PDT) Received: from [127.0.1.1] (184-96-157-145.hlrn.qwest.net. [184.96.157.145]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-803f60feba1sm10619014a34.13.2026.09.13.20.01.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 13 Sep 2026 20:01:52 -0700 (PDT) From: James Hilliard Date: Sun, 13 Sep 2026 21:01:16 -0600 Subject: [PATCH v5 10/18] mtd: rawnand: sunxi: bound DMA batches by the user-data register bank Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-10-7d711076a6f7@gmail.com> References: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-0-7d711076a6f7@gmail.com> In-Reply-To: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-0-7d711076a6f7@gmail.com> To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Maxime Ripard , Richard Genoud , Masahiro Yamada , Boris Brezillon , Brian Norris Cc: linux-mtd@lists.infradead.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, James Hilliard X-Mailer: b4 0.15.2 X-MORS-Enabled: yes X-MORS-DOMAIN: patchwork.local X-MORS-HOSTING: hosting172546 X-MORS-USER: hosting172546 X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= The H6/H616 controller concatenates protected user data in a bank of 32 four-byte registers. The default layout can allocate more than 128 bytes across a page, even though each ECC step fits its individual length limit. DMA transfers then access beyond the user-data register bank. For example, a 16 KiB page with 1280 OOB bytes and BCH40/1024 has 160 user-data bytes, while a 16 KiB page with 1664 OOB bytes can allocate 512 bytes. Do not cap that allocation: changing the lengths would move ECC offsets and make existing pages written through PIO incompatible. Instead, split DMA transfers into batches whose aggregate user data fits the bank. Reuse hardware slots and user-data registers from zero in each batch, retaining the original logical main-data and OOB offsets. Reposition the main column and spare-area base before subsequent batches. Keep pages whose user data already fits on the existing single-batch path. Pass the user-data register index directly to the protected-OOB helpers and program length fields from the batch's logical starting step. Collect each batch's ECC status and protected OOB before reusing the registers. Keep ECC accounting and trailing-OOB handling page-wide, remembering whether any batch found an erased chunk. Discard all partial DMA statistics before a PIO read retry. Use one page-read setup or program-begin command for the whole page. Only issue program-end after every batch and any trailing OOB transfer succeed. Do not retry a write in PIO after a batch has already been transferred. The allocator, free-OOB layout and raw-access callbacks are unchanged. Fixes: 54dcd6aa69db ("mtd: rawnand: sunxi: introduce maximize variable user data length") Signed-off-by: James Hilliard --- drivers/mtd/nand/raw/sunxi_nand.c | 276 +++++++++++++++++++++----------------- 1 file changed, 155 insertions(+), 121 deletions(-) diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index e29638c828ca..fbea6f16ea9d 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -54,6 +54,7 @@ #define NFC_REG_H6_RDATA_1 0x004C #define NFC_REG_A10_USER_DATA 0x0050 #define NFC_REG_H6_USER_DATA 0x0080 +#define NFC_H6_USER_DATA_REGS 32 #define NFC_REG_USER_DATA(nfc, x) (nfc->caps->reg_user_data + ((x) * 4)) #define NFC_REG_H6_USER_DATA_LEN 0x0070 /* A USER_DATA_LEN register can hold the length of 8 USER_DATA registers */ @@ -932,41 +933,39 @@ static u8 sunxi_nfc_user_data_sz(struct sunxi_nand_chip *sunxi_nand, int step) return sunxi_nand->user_data_bytes[step]; } +/* Keep the on-flash layout, but fit each DMA batch in the user-data bank. */ +static int sunxi_nfc_dma_batch_steps(struct nand_chip *nand, + int first_step, int end_step) +{ + struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); + struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); + unsigned int user_data_sz = 0; + int i; + + if (!nfc->caps->reg_user_data_len) + return end_step - first_step; + + for (i = first_step; i < end_step; i++) { + user_data_sz += sunxi_nfc_user_data_sz(sunxi_nand, i); + if (user_data_sz > NFC_H6_USER_DATA_REGS * sizeof(u32)) + break; + } + + return i - first_step; +} + +/* PIO uses register zero; DMA concatenates user data within each batch. */ static void sunxi_nfc_hw_ecc_get_prot_oob_bytes(struct nand_chip *nand, u8 *oob, - int step, bool bbm, int page, + unsigned int reg_index, bool bbm, int page, unsigned int user_data_sz) { - struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); u32 user_data; + unsigned int i; - if (!nfc->caps->reg_user_data_len) { - /* - * For A10, the user data for step n is in the nth - * REG_USER_DATA - */ - user_data = readl(nfc->regs + NFC_REG_USER_DATA(nfc, step)); - sunxi_nfc_user_data_to_buf(user_data, oob); - } else { - /* - * For H6 NAND controller, the user data for all steps is - * contained in 32 user data registers, but not at a specific - * offset for each step, they are just concatenated. - */ - unsigned int user_data_off = 0; - unsigned int reg_off; - u8 *ptr = oob; - unsigned int i; - - for (i = 0; i < step; i++) - user_data_off += sunxi_nfc_user_data_sz(sunxi_nand, i); - - user_data_off /= 4; - for (i = 0; i < user_data_sz / 4; i++, ptr += 4) { - reg_off = NFC_REG_USER_DATA(nfc, user_data_off + i); - user_data = readl(nfc->regs + reg_off); - sunxi_nfc_user_data_to_buf(user_data, ptr); - } + for (i = 0; i < user_data_sz / 4; i++) { + user_data = readl(nfc->regs + NFC_REG_USER_DATA(nfc, reg_index + i)); + sunxi_nfc_user_data_to_buf(user_data, oob + i * 4); } /* De-randomize the Bad Block Marker. */ @@ -1022,13 +1021,13 @@ static void sunxi_nfc_set_user_data_len(struct sunxi_nfc *nfc, } static void sunxi_nfc_hw_ecc_set_prot_oob_bytes(struct nand_chip *nand, - const u8 *oob, int step, + const u8 *oob, unsigned int reg_index, bool bbm, int page, unsigned int user_data_sz) { struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); - struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); u8 user_data[SUNXI_NFC_MAX_USER_DATA_SZ] = {}; + unsigned int i; /* Randomize the Bad Block Marker. */ if (bbm && (nand->options & NAND_NEED_SCRAMBLING)) { @@ -1037,33 +1036,10 @@ static void sunxi_nfc_hw_ecc_set_prot_oob_bytes(struct nand_chip *nand, oob = user_data; } - if (!nfc->caps->reg_user_data_len) { - /* - * For A10, the user data for step n is in the nth - * REG_USER_DATA - */ - writel(sunxi_nfc_buf_to_user_data(oob), - nfc->regs + NFC_REG_USER_DATA(nfc, step)); - } else { - /* - * For H6 NAND controller, the user data for all steps is - * contained in 32 user data registers, but not at a specific - * offset for each step, they are just concatenated. - */ - unsigned int user_data_off = 0; - const u8 *ptr = oob; - unsigned int i; - - for (i = 0; i < step; i++) - user_data_off += sunxi_nfc_user_data_sz(sunxi_nand, i); - - user_data_off /= 4; - for (i = 0; i < user_data_sz / 4; i++, ptr += 4) { - writel(sunxi_nfc_buf_to_user_data(ptr), - nfc->regs + NFC_REG_USER_DATA(nfc, user_data_off + i)); - } + for (i = 0; i < user_data_sz / 4; i++) { + writel(sunxi_nfc_buf_to_user_data(oob + i * 4), + nfc->regs + NFC_REG_USER_DATA(nfc, reg_index + i)); } - } static void sunxi_nfc_hw_ecc_update_stats(struct nand_chip *nand, @@ -1313,27 +1289,35 @@ static int sunxi_nfc_hw_ecc_read_extra_oob(struct nand_chip *nand, return 0; } -static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, uint8_t *buf, - int oob_required, int page, - int nchunks) +static int sunxi_nfc_hw_ecc_read_batch_dma(struct nand_chip *nand, u8 *buf, + int oob_required, int page, + int first_step, int nchunks, + int *raw_mode) { bool randomized = nand->options & NAND_NEED_SCRAMBLING; struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); struct mtd_info *mtd = nand_to_mtd(nand); struct nand_ecc_ctrl *ecc = &nand->ecc; - unsigned int corrected = mtd->ecc_stats.corrected; - unsigned int failed = mtd->ecc_stats.failed; + unsigned int reg_index = 0, user_data_sz; unsigned int max_bitflips = 0; - int ret, i, raw_mode = 0; + int ret, i; struct scatterlist sg; u32 status, pattern_found, wait; + if (first_step) { + ret = sunxi_nfc_read_column(nand, page, first_step * ecc->size, + NULL, 0); + if (ret) + return ret; + } + ret = sunxi_nfc_wait_cmd_fifo_empty(nfc); if (ret) return ret; - ret = sunxi_nfc_dma_op_prepare(nfc, buf, ecc->size, nchunks, + ret = sunxi_nfc_dma_op_prepare(nfc, buf + first_step * ecc->size, + ecc->size, nchunks, DMA_FROM_DEVICE, &sg); if (ret) return ret; @@ -1341,7 +1325,12 @@ static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, uint8_t *buf sunxi_nfc_hw_ecc_enable(nand); sunxi_nfc_reset_user_data_len(nfc); for (i = 0; i < nchunks; i++) - sunxi_nfc_set_user_data_len(nfc, sunxi_nfc_user_data_sz(sunxi_nand, i), i); + sunxi_nfc_set_user_data_len(nfc, + sunxi_nfc_user_data_sz(sunxi_nand, first_step + i), i); + /* exec_op() restores the page's spare base during column changes. */ + if (first_step) + writel(mtd->writesize + sunxi_get_oob_offset(sunxi_nand, ecc, first_step), + nfc->regs + NFC_REG_SPARE_AREA(nfc)); sunxi_nfc_randomizer_config(nand, page, false); sunxi_nfc_randomizer_enable(nand); @@ -1374,15 +1363,17 @@ static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, uint8_t *buf pattern_found = readl(nfc->regs + nfc->caps->reg_pat_found); pattern_found = field_get(NFC_ECC_PAT_FOUND_MSK(nfc), pattern_found); - for (i = 0; i < nchunks; i++) { - int data_off = i * ecc->size; - unsigned int user_data_sz = sunxi_nfc_user_data_sz(sunxi_nand, i); - int oob_off = sunxi_get_oob_offset(sunxi_nand, ecc, i); + for (i = 0; i < nchunks; i++, reg_index += user_data_sz / 4) { + int logical_step = first_step + i; + int data_off = logical_step * ecc->size; + int oob_off = sunxi_get_oob_offset(sunxi_nand, ecc, logical_step); u8 *data = buf + data_off; u8 *oob = nand->oob_poi + oob_off; bool erased; int bitflips; + user_data_sz = sunxi_nfc_user_data_sz(sunxi_nand, logical_step); + bitflips = sunxi_nfc_hw_ecc_correct(nand, randomized ? data : NULL, oob_required ? oob : NULL, i, status, pattern_found, @@ -1397,40 +1388,64 @@ static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, uint8_t *buf ret = sunxi_nfc_read_column(nand, page, mtd->writesize + oob_off, oob, ecc->bytes + user_data_sz); if (ret) - goto err_stats; + return ret; - sunxi_nfc_hw_ecc_get_prot_oob_bytes(nand, oob, i, !i, + sunxi_nfc_hw_ecc_get_prot_oob_bytes(nand, oob, reg_index, !logical_step, page, user_data_sz); } if (erased) - raw_mode = 1; + *raw_mode = 1; sunxi_nfc_hw_ecc_update_stats(nand, &max_bitflips, bitflips); } if (status & NFC_ECC_ERR_MSK(nfc)) { for (i = 0; i < nchunks; i++) { - int data_off = i * ecc->size; - unsigned int user_data_sz = sunxi_nfc_user_data_sz(sunxi_nand, i); - int oob_off = sunxi_get_oob_offset(sunxi_nand, ecc, i); + int logical_step = first_step + i; + int data_off = logical_step * ecc->size; + int oob_off = sunxi_get_oob_offset(sunxi_nand, ecc, logical_step); u8 *data = buf + data_off; u8 *oob = nand->oob_poi + oob_off; if (!(status & NFC_ECC_ERR(i))) continue; + user_data_sz = sunxi_nfc_user_data_sz(sunxi_nand, logical_step); ret = sunxi_nfc_hw_ecc_read_error(nand, data, data_off, oob, mtd->writesize + oob_off, user_data_sz, &max_bitflips, page); if (ret < 0) - goto err_stats; + return ret; if (ret) - raw_mode = 1; + *raw_mode = 1; } } + return max_bitflips; +} + +static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, u8 *buf, + int oob_required, int page, int nchunks) +{ + struct mtd_info *mtd = nand_to_mtd(nand); + unsigned int corrected = mtd->ecc_stats.corrected; + unsigned int failed = mtd->ecc_stats.failed; + unsigned int max_bitflips = 0; + int raw_mode = 0; + int first_step, batch_steps, ret; + + for (first_step = 0; first_step < nchunks; first_step += batch_steps) { + batch_steps = sunxi_nfc_dma_batch_steps(nand, first_step, nchunks); + ret = sunxi_nfc_hw_ecc_read_batch_dma(nand, buf, oob_required, page, + first_step, batch_steps, + &raw_mode); + if (ret < 0) + goto err_stats; + max_bitflips = max_t(unsigned int, max_bitflips, ret); + } + if (oob_required) { ret = sunxi_nfc_hw_ecc_read_extra_oob(nand, nand->oob_poi, NULL, !raw_mode, page); @@ -1761,69 +1776,88 @@ static int sunxi_nfc_hw_ecc_write_page_dma(struct nand_chip *nand, { struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); + struct mtd_info *mtd = nand_to_mtd(nand); struct nand_ecc_ctrl *ecc = &nand->ecc; struct scatterlist sg; u32 wait; - int ret, i; + int first_step, batch_steps, ret, i; sunxi_nfc_select_chip(nand, nand->cur_cs); - ret = sunxi_nfc_wait_cmd_fifo_empty(nfc); - if (ret) - return ret; + for (first_step = 0; first_step < ecc->steps; first_step += batch_steps) { + unsigned int reg_index = 0; - ret = sunxi_nfc_dma_op_prepare(nfc, buf, ecc->size, ecc->steps, - DMA_TO_DEVICE, &sg); - if (ret) - goto pio_fallback; + batch_steps = sunxi_nfc_dma_batch_steps(nand, first_step, ecc->steps); + ret = sunxi_nfc_wait_cmd_fifo_empty(nfc); + if (ret) + return ret; - sunxi_nfc_reset_user_data_len(nfc); - for (i = 0; i < ecc->steps; i++) { - unsigned int user_data_sz = sunxi_nfc_user_data_sz(sunxi_nand, i); - int oob_off = sunxi_get_oob_offset(sunxi_nand, ecc, i); - const u8 *oob = nand->oob_poi + oob_off; + ret = sunxi_nfc_dma_op_prepare(nfc, buf + first_step * ecc->size, + ecc->size, batch_steps, DMA_TO_DEVICE, &sg); + if (ret) { + /* Only retry before any part of the page has been transferred. */ + if (first_step) + return ret; + goto pio_fallback; + } - sunxi_nfc_hw_ecc_set_prot_oob_bytes(nand, oob, i, !i, page, - user_data_sz); - sunxi_nfc_set_user_data_len(nfc, user_data_sz, i); - } + sunxi_nfc_reset_user_data_len(nfc); + for (i = first_step; i < first_step + batch_steps; i++) { + unsigned int user_data_sz = sunxi_nfc_user_data_sz(sunxi_nand, i); + int oob_off = sunxi_get_oob_offset(sunxi_nand, ecc, i); + const u8 *oob = nand->oob_poi + oob_off; - ret = nand_prog_page_begin_op(nand, page, 0, NULL, 0); - if (ret) { - sunxi_nfc_dma_op_abort(nfc); - sunxi_nfc_dma_op_cleanup(nfc, DMA_TO_DEVICE, &sg); - return ret; - } + sunxi_nfc_hw_ecc_set_prot_oob_bytes(nand, oob, reg_index, !i, + page, user_data_sz); + sunxi_nfc_set_user_data_len(nfc, user_data_sz, i - first_step); + reg_index += user_data_sz / 4; + } - sunxi_nfc_hw_ecc_enable(nand); - sunxi_nfc_randomizer_config(nand, page, false); - sunxi_nfc_randomizer_enable(nand); + if (first_step) + ret = nand_change_write_column_op(nand, first_step * ecc->size, + NULL, 0, false); + else + ret = nand_prog_page_begin_op(nand, page, 0, NULL, 0); + if (ret) { + sunxi_nfc_dma_op_abort(nfc); + sunxi_nfc_dma_op_cleanup(nfc, DMA_TO_DEVICE, &sg); + return ret; + } - writel((NAND_CMD_RNDIN << 8) | NAND_CMD_PAGEPROG, - nfc->regs + NFC_REG_WCMD_SET); + /* exec_op() restores the page's spare base during column changes. */ + if (first_step) + writel(mtd->writesize + sunxi_get_oob_offset(sunxi_nand, ecc, first_step), + nfc->regs + NFC_REG_SPARE_AREA(nfc)); + sunxi_nfc_hw_ecc_enable(nand); + sunxi_nfc_randomizer_config(nand, page, false); + sunxi_nfc_randomizer_enable(nand); - wait = NFC_CMD_INT_FLAG; + writel((NAND_CMD_RNDIN << 8) | NAND_CMD_PAGEPROG, + nfc->regs + NFC_REG_WCMD_SET); - if (nfc->use_mdma) - wait |= NFC_DMA_INT_FLAG; - else - dma_async_issue_pending(nfc->dmac); + wait = NFC_CMD_INT_FLAG; - writel(NFC_PAGE_OP | NFC_DATA_SWAP_METHOD | - NFC_DATA_TRANS | NFC_ACCESS_DIR, - nfc->regs + NFC_REG_CMD); + if (nfc->use_mdma) + wait |= NFC_DMA_INT_FLAG; + else + dma_async_issue_pending(nfc->dmac); - ret = sunxi_nfc_wait_events(nfc, wait, false, 0); - if (ret) - sunxi_nfc_dma_op_abort(nfc); + writel(NFC_PAGE_OP | NFC_DATA_SWAP_METHOD | + NFC_DATA_TRANS | NFC_ACCESS_DIR, + nfc->regs + NFC_REG_CMD); - sunxi_nfc_randomizer_disable(nand); - sunxi_nfc_hw_ecc_disable(nand); + ret = sunxi_nfc_wait_events(nfc, wait, false, 0); + if (ret) + sunxi_nfc_dma_op_abort(nfc); - sunxi_nfc_dma_op_cleanup(nfc, DMA_TO_DEVICE, &sg); + sunxi_nfc_randomizer_disable(nand); + sunxi_nfc_hw_ecc_disable(nand); - if (ret) - return ret; + sunxi_nfc_dma_op_cleanup(nfc, DMA_TO_DEVICE, &sg); + + if (ret) + return ret; + } if (oob_required || (nand->options & NAND_NEED_SCRAMBLING)) { /* TODO: use DMA to transfer extra OOB bytes ? */ From patchwork Mon Sep 14 03:01:17 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3318 Return-Path: X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from sto.lore.kernel.org (sto.lore.kernel.org [172.232.135.74]) by mxe881.netcup.net (Postfix) with ESMTPS id EAF9B1C344A for ; Mon, 14 Sep 2026 05:03:18 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=gmail.com; spf=pass (sender IP is 172.232.135.74) smtp.mailfrom=linux-sunxi+bounces-25885-noreply=patchwork.local@lists.linux.dev smtp.helo=sto.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 172.232.135.74 as permitted sender) client-ip=172.232.135.74; envelope-from=linux-sunxi+bounces-25885-noreply=patchwork.local@lists.linux.dev; helo=sto.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by sto.lore.kernel.org (Postfix) with ESMTP id 29AC46033EC for ; Mon, 14 Sep 2026 03:02:40 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 367AB361957; Mon, 14 Sep 2026 03:01:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="SifLoa/b" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-oo2-f42.google.com (mail-oo2-f42.google.com [74.125.231.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8A5D735DA5D for ; Mon, 14 Sep 2026 03:01:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.231.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789354918; cv=none; b=oDUlIlm7xBKpcAl4O6tmIHR3i8w7my0KJtQ3LZfMPA8SC8Mi+NtCNlIEclP6Rn3ebvlqJYM/cod9xQzV7OLYa928Up5u35JRs5Z2rtaJjR09W9q7n8bTgBgbyONAh8hK7jPlAPhwYARjyuayAXb5Ac3Orc73sebweGTNEeBO/jc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789354918; c=relaxed/simple; bh=0vst0CVnlry03ftKyPut9wNxD9SkwAYgr+pMgxkNU28=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Ju44kmsb9RfcKOJ32HAENzWK9FGfbYP1+K4X5brb2DiI0ijJWC6nB7nw/SK0U7RUkHmO2fd+GhuIeKKzpSWgCg2xk76Bf1g7Nl7iocyka1lLl5nK6uby54tCA0M+uJ7XmOymibuaUhuZPpccbZsZVbqD1ppGQnSCQi5pM5WJ9wI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=SifLoa/b; arc=none smtp.client-ip=74.125.231.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-oo2-f42.google.com with SMTP id 46e09a7af769-8050801d337so1103248a34.2 for ; Sun, 13 Sep 2026 20:01:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789354914; x=1789959714; darn=lists.linux.dev; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=+Wt8ZYJ1+YeVWIymrCDD1Zyg4sGrqRQe4OCsHxO3n6g=; b=SifLoa/boS/YTS1X8swMgSsxhLZmNLWMHIsRiBjmC14FqxRpXylyEkSQOp+GpEGMiF ng0SKoq2dTuoR4BpfBdn2XwcnYwUqI2xg5aTZjkei5d5yILzIafsoK8JYFt16K5FIM6y 4cNBZmsgeG0WYy4bXmLXmH8qjqWKhrnV2Lwk2JMfGovcZZRYsjD+Lv6c2k3YXJJ2oua/ UF9ikUPZjk2LhjHZH3kHrSkoOu5wAj0glMDcDvYyNSwguBl04tt83mbbBDclQV5I5+Rh BVSS23QBfRq8vwFykRctLNXzNlraT5f3/wzyzexCIBR4k1nDAGEc/Mbs9GdRq01i5zyb orEQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789354914; x=1789959714; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=+Wt8ZYJ1+YeVWIymrCDD1Zyg4sGrqRQe4OCsHxO3n6g=; b=FdYGvJG+tXuZcmasSnX6pwwMgdmSBrwH1pBulvUylwF3EcYDR9ngJtcAh9baSqG8G1 km2ANlSYoldfPz4+/PbAJss8D2rq7n8wA4QZAFv7FltEIgSGpsXil1DD1KZ5jhBfJLTd 2EgIikHRWAC/n/3YpkFiTfmTsUuEtBCMjtBMT7/mz3hV7/obcDeDVVSutbizOk7Uhu7v R+YGjGuBKRy1eLKl7vkpcDzcstVabHT6f5b7YxYZxeg63DehoLWhoGpmNkzav7PkNX6s sr1Pq17ori7KKDJ2BWjve1/+e9OeFUydhBd8KOOOeUf0KWqCh0ix+bJj2BWvWDYSXbSq i3zA== X-Forwarded-Encrypted: i=1; AKwUvBzIVhLjWOE+Q7AZehJrvCDipfUIqx9ysGT2p+VBHLfZTM//lN841uqqOD1F2z1mgNhyBSDKNA17xGhc/w==@lists.linux.dev X-Gm-Message-State: AFuF++nd4+4qdugpYJc6DJ12maYo/aoNeg7XdhccvrPTWG994635Cw+U mUC82duW3cmtu47utnsNVeTlrCkt4bF8uKoG42h0lvLSFkQxJvj3ghGN X-Gm-Gg: AYBFou3+3uHMd8iV+qG6e0Cbw+Y0IphJLQJRBRHt42o/xu2OhRchy8AkHUH5Ngbam+M Abml1TRN8N1f3x+oc9b1ieh3al3suaSLyRCQU7Hy9H7elSmo1BQD7ORzHdnePclp2Yoni7phbM+ EcJQYK2FnQR0keBNk0LjnH5uU7CNwMQHYAm8ZZnbmhz8vwblOwK0tyLu6Ko7ynvDbq+jF0eOauk QGsnJ9hNvU32UMeIOMA/3R/WBhyAP6tAtHooVX6s05vxkNtkxKnf7Q4RCSyjrC1tfMT+TITG3p9 X+AR4LCXRfL3D83YNkx83Zkwcasz78k9E1U+wilNZE8sZwCel/oD4NZK9zBZfYYATodxXDUnm25 xE0+pwZbjW9yIMSI+VSljUjBbgaJK5MOpfSJlVkwY7rX+KVGvzvZU2M7rxBDP5zWd/QZ0u6dbPP rYyDGS7LgkCQqXvfpl7dyR7e1ALSdvCOj6aVv6RpVBaIozqsxQ2PJWc20s6R+VCX11knB5pVEaJ 7G7BXjO5MTYCsGezE+LSWWaJNeCNlihPtwvjDNslE8lB0wQECYZPdklrmOPczcs0YB7fTYcpn4t 54lfnhTxYX6fTcaCDy1prZhWpcs3/lRkAP7w0jUtC+nVALoPdThRKzl4TlAN9ygHDVJita6+AXs gLzXBE2D8i8R4winEHW2TISBxJ0qw4E38sK1yloj/ X-Received: by 2002:a05:6830:6a98:b0:7e1:cbe3:bb1b with SMTP id 46e09a7af769-808942ffab2mr584784a34.0.1789354914222; Sun, 13 Sep 2026 20:01:54 -0700 (PDT) Received: from [127.0.1.1] (184-96-157-145.hlrn.qwest.net. [184.96.157.145]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-803f60feba1sm10619014a34.13.2026.09.13.20.01.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 13 Sep 2026 20:01:53 -0700 (PDT) From: James Hilliard Date: Sun, 13 Sep 2026 21:01:17 -0600 Subject: [PATCH v5 11/18] mtd: rawnand: sunxi: clarify OOB register and step handling Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-11-7d711076a6f7@gmail.com> References: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-0-7d711076a6f7@gmail.com> In-Reply-To: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-0-7d711076a6f7@gmail.com> To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Maxime Ripard , Richard Genoud , Masahiro Yamada , Boris Brezillon , Brian Norris Cc: linux-mtd@lists.infradead.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, James Hilliard X-Mailer: b4 0.15.2 X-Rspamd-Server: rspamd-worker-8404 X-Spamd-Result: default: False [-1.16 / 15.00]; BAYES_HAM(-5.50)[100.00%]; RBL_SENDERSCORE(2.00)[172.232.135.74:from]; SUSPICIOUS_RECIPS(1.50)[]; DMARC_POLICY_SOFTFAIL(1.00)[gmail.com : SPF not aligned (relaxed), No valid DKIM,none]; MAILLIST(-0.15)[generic]; MIME_GOOD(-0.10)[text/plain]; BAD_REP_POLICIES(0.10)[]; HAS_LIST_UNSUB(-0.01)[]; PRECEDENCE_BULK(0.00)[]; FROM_HAS_DN(0.00)[]; DBL_BLOCKED_OPENRESOLVER(0.00)[sto.lore.kernel.org:rdns,sto.lore.kernel.org:helo]; TAGGED_RCPT(0.00)[dt]; FORGED_SENDER_MAILLIST(0.00)[]; FREEMAIL_CC(0.00)[lists.infradead.org,vger.kernel.org,lists.linux.dev,gmail.com]; RCPT_COUNT_TWELVE(0.00)[20]; RCVD_COUNT_FIVE(0.00)[6]; ASN(0.00)[asn:63949, ipnet:172.232.128.0/19, country:SG]; R_SPF_ALLOW(0.00)[+ip4:172.232.135.74]; FREEMAIL_TO(0.00)[bootlin.com,nod.at,ti.com,kernel.org,gmail.com,sholland.org,socionext.com]; FREEMAIL_FROM(0.00)[gmail.com]; TO_DN_SOME(0.00)[]; FROM_NEQ_ENVFROM(0.00)[jameshilliard1@gmail.com,linux-sunxi@lists.linux.dev]; FORGED_RECIPIENTS_MAILLIST(0.00)[]; RCVD_TLS_LAST(0.00)[]; TAGGED_FROM(0.00)[bounces-25885-noreply=patchwork.local]; MIME_TRACE(0.00)[0:+]; MID_RHS_MATCH_FROM(0.00)[]; ARC_ALLOW(0.00)[subspace.kernel.org:s=arc-20240116:i=1]; RCVD_VIA_SMTP_AUTH(0.00)[] X-Rspamd-Queue-Id: EAF9B1C344A X-MORS-Enabled: yes X-MORS-DOMAIN: patchwork.local X-MORS-HOSTING: hosting172546 X-MORS-USER: hosting172546 X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= PIO reuses hardware slot zero while the user-data length and OOB offset belong to the logical page step. Name the two indices explicitly in the helpers so their different roles are visible at each call site. The protected-OOB helpers already take a batch-local register index separately. Clarify why the plain-marker format compensates the bad-block marker around hardware randomization. Rename raw_mode to erased_chunk_found in the page readers and DMA batch helper, using a boolean in both paths. The flag suppresses randomization of the trailing OOB after an erased chunk; it does not select MTD_OPS_RAW. No on-flash format, register-access sequence or ECC accounting changes. Signed-off-by: James Hilliard --- drivers/mtd/nand/raw/sunxi_nand.c | 87 ++++++++++++++++++++------------------- 1 file changed, 44 insertions(+), 43 deletions(-) diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index fbea6f16ea9d..7cefb4d6951d 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -925,12 +925,13 @@ static inline u32 sunxi_nfc_buf_to_user_data(const u8 *buf) return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); } -static u8 sunxi_nfc_user_data_sz(struct sunxi_nand_chip *sunxi_nand, int step) +static u8 sunxi_nfc_user_data_sz(struct sunxi_nand_chip *sunxi_nand, + int logical_step) { if (!sunxi_nand->user_data_bytes) return USER_DATA_SZ; - return sunxi_nand->user_data_bytes[step]; + return sunxi_nand->user_data_bytes[logical_step]; } /* Keep the on-flash layout, but fit each DMA batch in the user-data bank. */ @@ -968,7 +969,7 @@ static void sunxi_nfc_hw_ecc_get_prot_oob_bytes(struct nand_chip *nand, u8 *oob, sunxi_nfc_user_data_to_buf(user_data, oob + i * 4); } - /* De-randomize the Bad Block Marker. */ + /* Undo hardware de-randomization for a plain on-flash BBM. */ if (bbm && (nand->options & NAND_NEED_SCRAMBLING)) sunxi_nfc_randomize_bbm(nand, page, oob); } @@ -990,7 +991,7 @@ static void sunxi_nfc_reset_user_data_len(struct sunxi_nfc *nfc) } static void sunxi_nfc_set_user_data_len(struct sunxi_nfc *nfc, - int len, int step) + int len, int hw_step) { bool found = false; u32 val; @@ -1013,11 +1014,11 @@ static void sunxi_nfc_set_user_data_len(struct sunxi_nfc *nfc, return; } - val = readl(nfc->regs + NFC_REG_USER_DATA_LEN(nfc, step)); + val = readl(nfc->regs + NFC_REG_USER_DATA_LEN(nfc, hw_step)); - val &= ~NFC_USER_DATA_LEN_MSK(step); - val |= field_prep(NFC_USER_DATA_LEN_MSK(step), i); - writel(val, nfc->regs + NFC_REG_USER_DATA_LEN(nfc, step)); + val &= ~NFC_USER_DATA_LEN_MSK(hw_step); + val |= field_prep(NFC_USER_DATA_LEN_MSK(hw_step), i); + writel(val, nfc->regs + NFC_REG_USER_DATA_LEN(nfc, hw_step)); } static void sunxi_nfc_hw_ecc_set_prot_oob_bytes(struct nand_chip *nand, @@ -1029,7 +1030,7 @@ static void sunxi_nfc_hw_ecc_set_prot_oob_bytes(struct nand_chip *nand, u8 user_data[SUNXI_NFC_MAX_USER_DATA_SZ] = {}; unsigned int i; - /* Randomize the Bad Block Marker. */ + /* Pre-randomize the BBM so the hardware writes it plain on flash. */ if (bbm && (nand->options & NAND_NEED_SCRAMBLING)) { memcpy(user_data, oob, user_data_sz); sunxi_nfc_randomize_bbm(nand, page, user_data); @@ -1099,7 +1100,7 @@ static int sunxi_nfc_hw_ecc_read_error(struct nand_chip *nand, } static int sunxi_nfc_hw_ecc_correct(struct nand_chip *nand, u8 *data, u8 *oob, - int step, u32 status, u32 pattern_found, + int hw_step, u32 status, u32 pattern_found, unsigned int user_data_sz, bool *erased) { struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); @@ -1108,13 +1109,13 @@ static int sunxi_nfc_hw_ecc_correct(struct nand_chip *nand, u8 *data, u8 *oob, *erased = false; - if (status & NFC_ECC_ERR(step)) + if (status & NFC_ECC_ERR(hw_step)) return -EBADMSG; - if (pattern_found & BIT(step)) { + if (pattern_found & BIT(hw_step)) { u8 pattern; - if (unlikely(!(readl(nfc->regs + NFC_REG_PAT_ID(nfc)) & BIT(step)))) { + if (unlikely(!(readl(nfc->regs + NFC_REG_PAT_ID(nfc)) & BIT(hw_step)))) { pattern = 0x0; } else { pattern = 0xff; @@ -1130,9 +1131,9 @@ static int sunxi_nfc_hw_ecc_correct(struct nand_chip *nand, u8 *data, u8 *oob, return 0; } - tmp = readl(nfc->regs + NFC_REG_ECC_ERR_CNT(nfc, step)); + tmp = readl(nfc->regs + NFC_REG_ECC_ERR_CNT(nfc, hw_step)); - return NFC_ECC_ERR_CNT(step, tmp); + return NFC_ECC_ERR_CNT(hw_step, tmp); } static int sunxi_nfc_hw_ecc_read_chunk(struct nand_chip *nand, @@ -1140,18 +1141,18 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct nand_chip *nand, u8 *oob, int oob_off, int *cur_off, unsigned int *max_bitflips, - int step, bool oob_required, int page) + int logical_step, bool oob_required, int page) { struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); - unsigned int user_data_sz = sunxi_nfc_user_data_sz(sunxi_nand, step); + unsigned int user_data_sz = sunxi_nfc_user_data_sz(sunxi_nand, logical_step); struct nand_ecc_ctrl *ecc = &nand->ecc; u32 pattern_found; - bool bbm = !step; + bool bbm = !logical_step; bool erased; int ret, bitflips; /* From the controller point of view, we are at step 0 */ - const int nfc_step = 0; + const int hw_step = 0; if (*cur_off != data_off) { ret = sunxi_nfc_read_column(nand, page, data_off, NULL, 0); @@ -1173,7 +1174,7 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct nand_chip *nand, if (ret) return ret; - sunxi_nfc_set_user_data_len(nfc, user_data_sz, nfc_step); + sunxi_nfc_set_user_data_len(nfc, user_data_sz, hw_step); sunxi_nfc_randomizer_config(nand, page, false); sunxi_nfc_randomizer_enable(nand); writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | NFC_ECC_OP, @@ -1190,7 +1191,7 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct nand_chip *nand, pattern_found = field_get(NFC_ECC_PAT_FOUND_MSK(nfc), pattern_found); bitflips = sunxi_nfc_hw_ecc_correct(nand, data, oob_required ? oob : NULL, - nfc_step, readl(nfc->regs + NFC_REG_ECC_ST), + hw_step, readl(nfc->regs + NFC_REG_ECC_ST), pattern_found, user_data_sz, &erased); if (erased) return 1; @@ -1216,7 +1217,7 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct nand_chip *nand, if (ret) return ret; - sunxi_nfc_hw_ecc_get_prot_oob_bytes(nand, oob, nfc_step, + sunxi_nfc_hw_ecc_get_prot_oob_bytes(nand, oob, hw_step, bbm, page, user_data_sz); } } @@ -1231,12 +1232,12 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct nand_chip *nand, * (it includes the user data before the ECC data.) */ static int sunxi_get_oob_offset(struct sunxi_nand_chip *sunxi_nand, - struct nand_ecc_ctrl *ecc, int step) + struct nand_ecc_ctrl *ecc, int logical_step) { - int ecc_off = step * ecc->bytes; + int ecc_off = logical_step * ecc->bytes; int i; - for (i = 0; i < step; i++) + for (i = 0; i < logical_step; i++) ecc_off += sunxi_nfc_user_data_sz(sunxi_nand, i); return ecc_off; @@ -1248,10 +1249,10 @@ static int sunxi_get_oob_offset(struct sunxi_nand_chip *sunxi_nand, * but it skips the next user data. */ static int sunxi_get_ecc_offset(struct sunxi_nand_chip *sunxi_nand, - struct nand_ecc_ctrl *ecc, int step) + struct nand_ecc_ctrl *ecc, int logical_step) { - return sunxi_get_oob_offset(sunxi_nand, ecc, step) + - sunxi_nfc_user_data_sz(sunxi_nand, step); + return sunxi_get_oob_offset(sunxi_nand, ecc, logical_step) + + sunxi_nfc_user_data_sz(sunxi_nand, logical_step); } static int sunxi_nfc_hw_ecc_read_extra_oob(struct nand_chip *nand, @@ -1292,7 +1293,7 @@ static int sunxi_nfc_hw_ecc_read_extra_oob(struct nand_chip *nand, static int sunxi_nfc_hw_ecc_read_batch_dma(struct nand_chip *nand, u8 *buf, int oob_required, int page, int first_step, int nchunks, - int *raw_mode) + bool *erased_chunk_found) { bool randomized = nand->options & NAND_NEED_SCRAMBLING; struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); @@ -1395,7 +1396,7 @@ static int sunxi_nfc_hw_ecc_read_batch_dma(struct nand_chip *nand, u8 *buf, } if (erased) - *raw_mode = 1; + *erased_chunk_found = true; sunxi_nfc_hw_ecc_update_stats(nand, &max_bitflips, bitflips); } @@ -1419,7 +1420,7 @@ static int sunxi_nfc_hw_ecc_read_batch_dma(struct nand_chip *nand, u8 *buf, if (ret < 0) return ret; if (ret) - *raw_mode = 1; + *erased_chunk_found = true; } } @@ -1433,14 +1434,14 @@ static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, u8 *buf, unsigned int corrected = mtd->ecc_stats.corrected; unsigned int failed = mtd->ecc_stats.failed; unsigned int max_bitflips = 0; - int raw_mode = 0; + bool erased_chunk_found = false; int first_step, batch_steps, ret; for (first_step = 0; first_step < nchunks; first_step += batch_steps) { batch_steps = sunxi_nfc_dma_batch_steps(nand, first_step, nchunks); ret = sunxi_nfc_hw_ecc_read_batch_dma(nand, buf, oob_required, page, first_step, batch_steps, - &raw_mode); + &erased_chunk_found); if (ret < 0) goto err_stats; max_bitflips = max_t(unsigned int, max_bitflips, ret); @@ -1448,7 +1449,7 @@ static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, u8 *buf, if (oob_required) { ret = sunxi_nfc_hw_ecc_read_extra_oob(nand, nand->oob_poi, - NULL, !raw_mode, page); + NULL, !erased_chunk_found, page); if (ret) goto err_stats; } @@ -1465,17 +1466,17 @@ static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, u8 *buf, static int sunxi_nfc_hw_ecc_write_chunk(struct nand_chip *nand, const u8 *data, int data_off, const u8 *oob, int oob_off, - int *cur_off, int step, + int *cur_off, int logical_step, int page) { struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); - unsigned int user_data_sz = sunxi_nfc_user_data_sz(sunxi_nand, step); + unsigned int user_data_sz = sunxi_nfc_user_data_sz(sunxi_nand, logical_step); struct nand_ecc_ctrl *ecc = &nand->ecc; - bool bbm = !step; + bool bbm = !logical_step; int ret; /* From the controller point of view, we are at step 0 */ - const int nfc_step = 0; + const int hw_step = 0; if (data_off != *cur_off) { ret = nand_change_write_column_op(nand, data_off, NULL, 0, false); @@ -1499,8 +1500,8 @@ static int sunxi_nfc_hw_ecc_write_chunk(struct nand_chip *nand, sunxi_nfc_randomizer_config(nand, page, false); sunxi_nfc_randomizer_enable(nand); - sunxi_nfc_set_user_data_len(nfc, user_data_sz, nfc_step); - sunxi_nfc_hw_ecc_set_prot_oob_bytes(nand, oob, nfc_step, bbm, page, + sunxi_nfc_set_user_data_len(nfc, user_data_sz, hw_step); + sunxi_nfc_hw_ecc_set_prot_oob_bytes(nand, oob, hw_step, bbm, page, user_data_sz); writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | @@ -1557,7 +1558,7 @@ static int sunxi_nfc_hw_ecc_read_page(struct nand_chip *nand, uint8_t *buf, struct nand_ecc_ctrl *ecc = &nand->ecc; unsigned int max_bitflips = 0; int ret, i, cur_off = 0; - bool raw_mode = false; + bool erased_chunk_found = false; sunxi_nfc_select_chip(nand, nand->cur_cs); @@ -1581,12 +1582,12 @@ static int sunxi_nfc_hw_ecc_read_page(struct nand_chip *nand, uint8_t *buf, if (ret < 0) goto out; else if (ret) - raw_mode = true; + erased_chunk_found = true; } if (oob_required) { ret = sunxi_nfc_hw_ecc_read_extra_oob(nand, nand->oob_poi, &cur_off, - !raw_mode, page); + !erased_chunk_found, page); if (ret) goto out; } From patchwork Mon Sep 14 03:01:18 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3322 Return-Path: X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from sin.lore.kernel.org (sin.lore.kernel.org [104.64.211.4]) by mxe881.netcup.net (Postfix) with ESMTPS id 9156C1C2BD4 for ; Mon, 14 Sep 2026 05:05:07 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=gmail.com; spf=pass (sender IP is 104.64.211.4) smtp.mailfrom=linux-sunxi+bounces-25886-noreply=patchwork.local@lists.linux.dev smtp.helo=sin.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 104.64.211.4 as permitted sender) client-ip=104.64.211.4; envelope-from=linux-sunxi+bounces-25886-noreply=patchwork.local@lists.linux.dev; helo=sin.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by sin.lore.kernel.org (Postfix) with ESMTP id 72ECA25577 for ; Mon, 14 Sep 2026 03:02:46 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 1C6AE361975; Mon, 14 Sep 2026 03:02:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="e3KZgpaQ" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-oo2-f42.google.com (mail-oo2-f42.google.com [74.125.231.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E108835E1D3 for ; Mon, 14 Sep 2026 03:01:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.231.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789354919; cv=none; b=Wy6PqAvmcmRnoGFtU3Zm6l5D6/CojlS1+98DMoF1tdqq8v/ly+q0HpUye30HYUPjjVsaV4ZqqPeR7dAZC18rizgCTSZ3flvmQ+/iWuwjvzwNhqTmT9gE59iFwn1HhGx6KSKP+zPybAP5Bd09Ii4F1EQzQZlMhfqzhGt4w004fIE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789354919; c=relaxed/simple; bh=TnmhAN7UAS2ynuFEOPQLlzD2wvbIo/yeVWwhOMqNS58=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ksU66hQt3ClyGX1XLQLkBdm1KaTU3yzXtmWjlwljSLDnJnEbeaGM4msUC/KcoPGKeohIFKVvwtXtOkcuuQOq6+LCpVSECa1X4xRY35Kh9TbtrMN8m3wQ5qc05dNz3TG0hu82w+cpI6nbKj25MG1BDETWhEkPP6lUeqVkou3psEQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=e3KZgpaQ; arc=none smtp.client-ip=74.125.231.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-oo2-f42.google.com with SMTP id 46e09a7af769-804f7045f3eso379768a34.2 for ; Sun, 13 Sep 2026 20:01:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789354916; x=1789959716; darn=lists.linux.dev; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=SP5FgDVql885MI97WgCQyPWKLiok3M5jguE0MrKj3qI=; b=e3KZgpaQmsIHDrHGMhgTraFFfD2wi14TOJFkG5QP8hYRt7LquGGXhjkoP8thUSDtvx Q+rFIGktoTaerfNp8wM7GZUoXkGxeOuVuodf5CAXrbz9CvQ3aXHslTml/Sbw9WIuah+r vuHD8X2tQUHe0aQvdJo7fJd0qmSDzvuyV1tdpITdgtE861515LPnc3MvG3tKzEIGIM/p hUMNnDfrMHWPd+s/YgZ7OikBcjlzj2wRDNOaS8h6dqfP2ckR/+9OZ0vEA3hlfsuNz0Bg yLAJTu7HjL3zaJgk7w+IwJ3B28j9MYnLDwaYD61R+Lko0n5UDCBlCdxg1kI54DfqRxtr RzHw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789354916; x=1789959716; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=SP5FgDVql885MI97WgCQyPWKLiok3M5jguE0MrKj3qI=; b=TOdGzzVKxQmcnIzapV7VBlHp+cMKQsizJxbuKQQ3rcPjTh+ye45aC5bbJzRGyvuWeG 9DTgdelsgESx06aM+lGB841wI1/BYJ3VRFzAQOUplo6nM1yOV/v1lD88OUMlj5hiKijx eay2qaT58G1BaJLtaNBHYCzZ3VsCU5pLVSeta9+2M2z2lTgQiGBuH3xILiYNjd/6lLoH S5EnUc178Xh9WQZ9kUuxViz4eb5YmMyUfR8AFO4VHTxZTd1ceoNJjE4Bq0wxiwlKyByW rIIK75wUkJw8/Mb8NiDeVFXnx6sg1KcIRG77tUTb2k2+I4O9DLPKkAD1QRz8FTaO80oI VLDw== X-Forwarded-Encrypted: i=1; AKwUvBwCjBvFWf77RG037OdQ57z15F0jPAg8S4nOare2Ug6tbj4PLeN+LLO+JdAFT2Kcf4cOWyerHVWGI7aSlg==@lists.linux.dev X-Gm-Message-State: AFuF++lDBOHd+qxMHOSuU7PnmPp8FB2mcZn93u+inkeHRq8vxphhAUfV dpK/TJ+lotPJ7Rb/ieLXvUo0JYcjlxbP1isk42ycsBJx0kaZJYs+DNWx X-Gm-Gg: AYBFou3dIyGXJE/AarAoUBId1b+BbT6dPXL8olpQs9W0mlXT0o6rF2ieMKxsnTvrzsl sjn9RKGLjTg1liVRQLrE/rv/oSqfwYn2nhziXyk2hy+OTYB3K/EuTea79T+rwVFxQfYC1aIUvvF zSX93KSc2GWobBz2qCty9uVY8oEOGxE9jpDHq5BpgnPxCr4NBVY4Y/2z4y8zhdplWmPWtL0l+Qe r+ZS16GExiy7nPCXqTWFO1sqYPFRX2I1pZw49gaOiCPJDZiHckR8OUh6T5eE3vRcV72WRBRUy4I pcXFrWF86EQ3SPsv2dWlrrSSLlBPMNYqSmMLk27f6dlr+DWKzu7BihySThUO8iOHQmv3Pl+tD7v vujhDgL6AO6t5Z5dIPH7XWA6uZorW3oNrTGxSKe1keImuk06qqGVnRQGyw/tqmGbncgcaakps0S pO4ARms3pwIssxiErp+jnAvI9F2rQp68ruSX57Y64OupnMRtZaigYCGDvscJBU1Df8LPhpZlnhW I3zNRJDOc0uhSU1SWDw5VKjUbsxOQ7AHjygKSSthWOgBhDU0/42dFEtZiVzhd0/5a024tRO8L0Q oKfEPAB4AzkUUJHScEpwf9vDkfmxY9B5DBjyyLQt5uNqdsHOhViSg5WwIGgrfpfi188fkMkpusm VS8kCrOhY9q3J9GcyR3Eb1eO06IhM3jeCLwPIQmpX X-Received: by 2002:a05:6830:230f:b0:7fa:ab72:9dfe with SMTP id 46e09a7af769-80899b4c24bmr292105a34.22.1789354915667; Sun, 13 Sep 2026 20:01:55 -0700 (PDT) Received: from [127.0.1.1] (184-96-157-145.hlrn.qwest.net. [184.96.157.145]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-803f60feba1sm10619014a34.13.2026.09.13.20.01.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 13 Sep 2026 20:01:55 -0700 (PDT) From: James Hilliard Date: Sun, 13 Sep 2026 21:01:18 -0600 Subject: [PATCH v5 12/18] dt-bindings: mtd: sunxi: Add randomized OOB flag Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-12-7d711076a6f7@gmail.com> References: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-0-7d711076a6f7@gmail.com> In-Reply-To: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-0-7d711076a6f7@gmail.com> To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Maxime Ripard , Richard Genoud , Masahiro Yamada , Boris Brezillon , Brian Norris Cc: linux-mtd@lists.infradead.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, James Hilliard X-Mailer: b4 0.15.2 X-MORS-Enabled: yes X-MORS-DOMAIN: patchwork.local X-MORS-HOSTING: hosting172546 X-MORS-USER: hosting172546 X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= Allwinner NAND firmware stores the bad block marker through the controller randomizer. The mainline driver instead compensates the first two randomized bytes so that the marker remains plain on flash. On H6 and H616, the firmware also uses a fixed protected user-data placement while mainline fills the OOB space left after ECC. Add an opt-in property selecting the firmware's normal-page format for the configured controller hardware-ECC geometry. This covers the vendor-specific randomizer, bad block marker representation and protected user-data placement needed to access BSP-derived images. The property does not change raw-access semantics. Raw operations still bypass ECC and randomization and expose physical main and OOB bytes. Signed-off-by: James Hilliard --- .../devicetree/bindings/mtd/allwinner,sun4i-a10-nand.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Documentation/devicetree/bindings/mtd/allwinner,sun4i-a10-nand.yaml b/Documentation/devicetree/bindings/mtd/allwinner,sun4i-a10-nand.yaml index 9d061e2216cb..8ecafc40ddcb 100644 --- a/Documentation/devicetree/bindings/mtd/allwinner,sun4i-a10-nand.yaml +++ b/Documentation/devicetree/bindings/mtd/allwinner,sun4i-a10-nand.yaml @@ -79,6 +79,16 @@ patternProperties: minimum: 0 maximum: 1 + allwinner,randomized-oob: + type: boolean + description: + Select the normal-page format used by Allwinner NAND firmware for + the configured controller hardware-ECC geometry. Normal page + transfers use the controller randomizer, the bad block marker remains + in its data stream instead of being compensated to stay plain on + flash, and protected user data uses the controller-specific placement + expected by the firmware. + unevaluatedProperties: false required: From patchwork Mon Sep 14 03:01:19 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3327 Return-Path: X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from tor.lore.kernel.org (tor.lore.kernel.org [172.105.105.114]) by mxe881.netcup.net (Postfix) with ESMTPS id 6279B1C0294 for ; Mon, 14 Sep 2026 05:08:15 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=gmail.com; spf=pass (sender IP is 172.105.105.114) smtp.mailfrom=linux-sunxi+bounces-25888-noreply=patchwork.local@lists.linux.dev smtp.helo=tor.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 172.105.105.114 as permitted sender) client-ip=172.105.105.114; envelope-from=linux-sunxi+bounces-25888-noreply=patchwork.local@lists.linux.dev; helo=tor.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by tor.lore.kernel.org (Postfix) with ESMTP id A1CF62DB55 for ; Mon, 14 Sep 2026 03:02:54 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id BD817367B9B; Mon, 14 Sep 2026 03:02:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="DMr879dI" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-oo2-f41.google.com (mail-oo2-f41.google.com [74.125.231.169]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0F9CF333429 for ; Mon, 14 Sep 2026 03:01:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.231.169 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789354922; cv=none; b=uYBiZAM/yP4KN7XETmSm7ThuqpYIofegNYx6xKIh0aMQOrvOX7lVtrkG+IDqQVPb0bC8i71HML1r5Qw8atWapYuzXG+2LOtOART/F5KmQU78NyfWzCbZN6vcf6ZaeGFo6Jd9YZSnXQhmUPDRX4rivB3oxTv6r9EgNAGRi6U/2UA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789354922; c=relaxed/simple; bh=JL832aI7r2nbG2mOmURmKhPmxaM1LefN/qlKvgE7hoE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=h6r4087YegA//PltVWU08SKVyjhpO1uYuu+Md19phMBzcAp6IT8teCx6paDLZ0MXhPTFEaHMieaIVF2/dXFomJSb+7bXxRcIzYpp98Bze5btM8a5woNoYGtmAvIKm9kApWPIypzO/KmHFwWPAogElEfOL6Igw6jz7UmDH8WV2uQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=DMr879dI; arc=none smtp.client-ip=74.125.231.169 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-oo2-f41.google.com with SMTP id 46e09a7af769-7fcb425fc2bso964696a34.3 for ; Sun, 13 Sep 2026 20:01:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789354918; x=1789959718; darn=lists.linux.dev; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=lG5iszPYAhZghbK9DA7AX9OFRia7hTHj4HATLsgwf3M=; b=DMr879dI+0CLS+12JWZc5XMmGS9T0/c87pmdDIRw+hD5rwAa/1LJaz9y45Q+3X33mS Oea0wqAkMDZXc/SfwjjsyiwEsnbxHXVLMe6F0bq9oTUezk5tU0bYJkxkB+76fasIjOHm tNpPevzVCmujvPx6n/uoKty0hmu1bYPLL0eXlgFLZoaSkun99mqMP1PjFgZEgphQ01HT rdb+tS03p56KmkdoVMj5VjeK0RQ9eMtZg0eSnVVkUrCUh+tjIDUenjhg/WiVg46bAyDe UoF1tKZc1tPFAkaLqGqPvJgfBr3sVTNsWVIMvOJVUvRY7OHuVQexJTjU2zh3Y5/dVNAC zGwg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789354918; x=1789959718; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=lG5iszPYAhZghbK9DA7AX9OFRia7hTHj4HATLsgwf3M=; b=Cad0TUNtnHRhRdKafxuKpx+Sk6tkBaVjxI3YpCK34GsztIpeZ2cdAj/CbAL751hm3w 5iMbz5ho82a+LpVMzqS0iXNyzSQVnJLatuM+PT8d0xUnebrpJHtw81NWleZ7CsXYtoOx rZ8onT/w7cAozkt3vqYYRLuXmTdnQ6KwyvWpJScaf0hWfYll6ToJarp/ivBGMZGo59hS pSx9xEKSMqBlV/yZ4JqxeKfZp0pGEunur/lr+f7UDenzYAx6zVH80x0yPfnn8zXTSOuw YThcaTeNQCoVIBpyV4mkSGBASXdenKWReZDvkgSc9JwOQByKq8pl+lepY2Xo3mvh+t5G nuyg== X-Forwarded-Encrypted: i=1; AKwUvBwxiMrqgYRoa6CF/SSNMlGdoI/J1TmJbF9/3fchUdogFyLPamKw3xmzkDWxkvRXzfWyvnpZTWGDv1EuDg==@lists.linux.dev X-Gm-Message-State: AFuF++lDyJ1s5znbBkOCuU8Tou01uavo6Tay8J6jmbExyd6fObIIlW9N tAFC91goV4dIFNI9Y/OO6Z8xnJMlVRD6+9LKgZfh2g+F0jrTMh6k/yd7 X-Gm-Gg: AYBFou3BMGRE76Xru3cqBJlhgV+UL8dFZCuOYlbpZtB8CEfVmK3gy/CJ8nYOtnxPOzT 3RaIEE9DY3Zgi0mwHMJ/eCB+waH75VdTCLRoFSl510BZdAzHKCVo3V/SEgXzyIQi/jCJizAGtE9 OSGAvhghTKk3/c+VgwoLbdHfJSt7p4mghcftobQrbnNxWn/pES8U9P+78ZM/4auG78aBw2zcFnn A04p/W3fUWo4AXisoZ938sG2GjSfaVe63YK+z9xN9Rt/Qun7FqdQFpeKWFsGmhaevVKnC5YrrA3 zXYOR4JPGdUJvYlgzUD0geGqHgBEPY4fYCLmveI7W9KvxovazQQw28ygzMaazvTy96Xllt7oQTE ETLHGXZp+FpT8SwIqOPoRskh5B3zwdP7zXYpD26cghYqHf0v0z33rPeai1Cr+VS/MUpHxQ6FYA7 IK+XjJ5Xt1QHBTkS7B+CZJtc3S6HyB0RQlaTKR/VCPXHDVYcOalQ6PURtjbFYiG7hFLzw3dUBxr QMZDo9LLUh9wmUwZRG3UgPneEToqw3OLnYsO1d9eCPbUz4WzO7JWDzjaUR8lMv1BQ72m8O4d2pV /yeazqKb8fLEywE3i3QSgo4tn+Z+ef7coakUHKBwxAmbN6QC0x6K722BcMF7lPcBZO5L7Y1AseL y1Qwh/VuJQ7tUx1f3pGNMmujHSkfhMg== X-Received: by 2002:a05:6830:8554:20b0:7fa:5c49:524c with SMTP id 46e09a7af769-808991619d0mr147343a34.19.1789354917616; Sun, 13 Sep 2026 20:01:57 -0700 (PDT) Received: from [127.0.1.1] (184-96-157-145.hlrn.qwest.net. [184.96.157.145]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-803f60feba1sm10619014a34.13.2026.09.13.20.01.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 13 Sep 2026 20:01:57 -0700 (PDT) From: James Hilliard Date: Sun, 13 Sep 2026 21:01:19 -0600 Subject: [PATCH v5 13/18] mtd: rawnand: sunxi: support randomized OOB formats Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-13-7d711076a6f7@gmail.com> References: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-0-7d711076a6f7@gmail.com> In-Reply-To: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-0-7d711076a6f7@gmail.com> To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Maxime Ripard , Richard Genoud , Masahiro Yamada , Boris Brezillon , Brian Norris Cc: linux-mtd@lists.infradead.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, James Hilliard X-Mailer: b4 0.15.2 X-Rspamd-Server: rspamd-worker-8404 X-Spamd-Result: default: False [-1.16 / 15.00]; BAYES_HAM(-5.50)[100.00%]; RBL_SENDERSCORE(2.00)[172.105.105.114:from]; SUSPICIOUS_RECIPS(1.50)[]; DMARC_POLICY_SOFTFAIL(1.00)[gmail.com : SPF not aligned (relaxed), No valid DKIM,none]; MAILLIST(-0.15)[generic]; MIME_GOOD(-0.10)[text/plain]; BAD_REP_POLICIES(0.10)[]; HAS_LIST_UNSUB(-0.01)[]; PRECEDENCE_BULK(0.00)[]; FROM_HAS_DN(0.00)[]; DBL_BLOCKED_OPENRESOLVER(0.00)[tor.lore.kernel.org:rdns,tor.lore.kernel.org:helo]; TAGGED_RCPT(0.00)[dt]; FORGED_SENDER_MAILLIST(0.00)[]; FREEMAIL_CC(0.00)[lists.infradead.org,vger.kernel.org,lists.linux.dev,gmail.com]; RCPT_COUNT_TWELVE(0.00)[20]; RCVD_COUNT_FIVE(0.00)[6]; ASN(0.00)[asn:63949, ipnet:172.105.96.0/20, country:SG]; R_SPF_ALLOW(0.00)[+ip4:172.105.105.114]; FREEMAIL_TO(0.00)[bootlin.com,nod.at,ti.com,kernel.org,gmail.com,sholland.org,socionext.com]; FREEMAIL_FROM(0.00)[gmail.com]; TO_DN_SOME(0.00)[]; FROM_NEQ_ENVFROM(0.00)[jameshilliard1@gmail.com,linux-sunxi@lists.linux.dev]; FORGED_RECIPIENTS_MAILLIST(0.00)[]; RCVD_TLS_LAST(0.00)[]; TAGGED_FROM(0.00)[bounces-25888-noreply=patchwork.local]; MIME_TRACE(0.00)[0:+]; MID_RHS_MATCH_FROM(0.00)[]; ARC_ALLOW(0.00)[subspace.kernel.org:s=arc-20240116:i=1]; RCVD_VIA_SMTP_AUTH(0.00)[] X-Rspamd-Queue-Id: 6279B1C0294 X-MORS-Enabled: yes X-MORS-DOMAIN: patchwork.local X-MORS-HOSTING: hosting172546 X-MORS-USER: hosting172546 X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= The controller randomizer covers the bad block marker along with the rest of the OOB data. The driver currently compensates the marker bytes before writes and after reads so that they remain plain on flash. Allwinner NAND firmware instead stores the marker through the randomizer. Media using that format appears to contain bad blocks unless the randomizer is enabled while reading the marker. Honor the allwinner,randomized-oob property by marking the NAND as requiring scrambling during normal hardware-ECC transfers and leaving the marker in the randomizer data stream. Keep the existing plain marker behavior when the property is absent. Reject the property with software or disabled ECC because those paths do not operate the controller randomizer. Also reject an ECC step larger than the page so the NAND core cannot fall back to software ECC after the driver's initial engine-type check. Select the vendor's erased-spare predicate through the SoC capabilities when the randomized format encounters an ECC error. Older controllers require eight exact 0xff spare bytes, with the vendor spare-scan shortcut for four exact bytes on the first page and pages 127 modulo 128 within each eraseblock. Apply that shortcut only with the vendor's 1 KiB ECC steps. H616 requires byte zero and at least nine of ten bytes to be 0xff. Reconstruct the physical spare prefix from the protected user-data registers, padding unavailable bytes with 0xff. Each ECC step restarts its OOB randomizer; account for this when gathering the prefix from fixed four-byte user-data fields. Accepted erased pages return all-0xff main data and OOB without an ECC failure or a raw reread. Also follow the vendor's all-zero-page override: when every ECC step reports an all-zero physical pattern, return zeroed data and OOB with an ECC failure, even if the hardware did not report one. Keep the ECC exception disabled in this mode so uniform data still undergoes decoding. Keep the original hardware-decoded main data and protected OOB on other ECC failures, and report the failure through the ECC statistics. Bad-block and BBT pattern scans inspect these buffers even after an ECC error; they must not see the physical randomized representation. Preserve the normal per-path representation of unprotected OOB bytes when they are requested. Share page classification between PIO and DMA, including subpage reads. Read the whole page for randomized-format subpage requests so that both paths see the same spare prefix and all-zero-page status. Defer statistics until OOB reads have succeeded, so a DMA-to-PIO retry is accounted once. The plain-marker format keeps its existing physical erased-chunk check. MTD_OPS_RAW behavior remains unchanged: raw accesses bypass both ECC and randomization and expose the physical representation. This changes marker handling on all supported controllers; the H6/H616 protected user-data placement is handled separately. Signed-off-by: James Hilliard --- drivers/mtd/nand/raw/sunxi_nand.c | 278 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 268 insertions(+), 10 deletions(-) diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index 7cefb4d6951d..0375930042ef 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -266,6 +266,7 @@ struct sunxi_nfc_timings { * @clk_rate: clk_rate required for this NAND chip * @timing_cfg: TIMING_CFG register value for this NAND chip * @timing_ctl: TIMING_CTL register value for this NAND chip + * @randomized_oob: use the randomized normal-page OOB format * @nsels: number of CS lines required by the NAND chip * @sels: array of CS lines descriptions * @user_data_bytes: array of user data lengths for all ECC steps @@ -278,6 +279,7 @@ struct sunxi_nand_chip { u32 timing_cfg; u32 timing_ctl; u8 *user_data_bytes; + bool randomized_oob; int nsels; struct sunxi_nand_chip_sel sels[] __counted_by(nsels); }; @@ -329,6 +331,7 @@ struct sunxi_nfc_mdma_desc { * @nuser_data_tab: Size of @user_data_len_tab * @sram_size: Size of the NAND controller SRAM * @timings: Controller timing characteristics + * @spare_is_erased: Vendor erased-page check on the physical spare prefix */ struct sunxi_nfc_caps { bool has_mdma; @@ -357,6 +360,7 @@ struct sunxi_nfc_caps { unsigned int max_ecc_steps; int sram_size; const struct sunxi_nfc_timings *timings; + bool (*spare_is_erased)(struct nand_chip *nand, const u8 *spare, int page); }; /** @@ -862,12 +866,18 @@ static void sunxi_nfc_randomizer_disable(struct nand_chip *nand) nfc->regs + NFC_REG_ECC_CTL); } -static void sunxi_nfc_randomize_bbm(struct nand_chip *nand, int page, u8 *bbm) +static void sunxi_nfc_randomize_buf(u16 state, u8 *buf, unsigned int len) { - u16 state = sunxi_nfc_randomizer_state(nand, page, true); + while (len--) { + *buf++ ^= state; + state = sunxi_nfc_randomizer_step(state, 8); + } +} - bbm[0] ^= state; - bbm[1] ^= sunxi_nfc_randomizer_step(state, 8); +static void sunxi_nfc_randomize_bbm(struct nand_chip *nand, int page, u8 *bbm) +{ + sunxi_nfc_randomize_buf(sunxi_nfc_randomizer_state(nand, page, true), + bbm, 2); } static int sunxi_nfc_randomizer_write_buf(struct nand_chip *nand, @@ -960,6 +970,7 @@ static void sunxi_nfc_hw_ecc_get_prot_oob_bytes(struct nand_chip *nand, u8 *oob, unsigned int reg_index, bool bbm, int page, unsigned int user_data_sz) { + struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); u32 user_data; unsigned int i; @@ -970,7 +981,8 @@ static void sunxi_nfc_hw_ecc_get_prot_oob_bytes(struct nand_chip *nand, u8 *oob, } /* Undo hardware de-randomization for a plain on-flash BBM. */ - if (bbm && (nand->options & NAND_NEED_SCRAMBLING)) + if (bbm && (nand->options & NAND_NEED_SCRAMBLING) && + !sunxi_nand->randomized_oob) sunxi_nfc_randomize_bbm(nand, page, oob); } @@ -1027,11 +1039,13 @@ static void sunxi_nfc_hw_ecc_set_prot_oob_bytes(struct nand_chip *nand, unsigned int user_data_sz) { struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); + struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); u8 user_data[SUNXI_NFC_MAX_USER_DATA_SZ] = {}; unsigned int i; /* Pre-randomize the BBM so the hardware writes it plain on flash. */ - if (bbm && (nand->options & NAND_NEED_SCRAMBLING)) { + if (bbm && (nand->options & NAND_NEED_SCRAMBLING) && + !sunxi_nand->randomized_oob) { memcpy(user_data, oob, user_data_sz); sunxi_nfc_randomize_bbm(nand, page, user_data); oob = user_data; @@ -1099,6 +1113,37 @@ static int sunxi_nfc_hw_ecc_read_error(struct nand_chip *nand, return ret >= 0; } +/* Accumulate a whole randomized-OOB page before classifying its spare data. */ +struct sunxi_nfc_ecc_status { + u32 error_steps; + u32 zero_steps; + unsigned int corrected; + unsigned int max_bitflips; +}; + +static void sunxi_nfc_hw_ecc_record_status(struct nand_chip *nand, + struct sunxi_nfc_ecc_status *result, + int logical_step, int hw_step, u32 status, + u32 pattern_found) +{ + struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); + u32 count; + + if ((pattern_found & BIT(hw_step)) && + !(readl(nfc->regs + NFC_REG_PAT_ID(nfc)) & BIT(hw_step))) + result->zero_steps |= BIT(logical_step); + + if (status & NFC_ECC_ERR(hw_step)) { + result->error_steps |= BIT(logical_step); + return; + } + + count = readl(nfc->regs + NFC_REG_ECC_ERR_CNT(nfc, hw_step)); + count = NFC_ECC_ERR_CNT(hw_step, count); + result->corrected += count; + result->max_bitflips = max(result->max_bitflips, count); +} + static int sunxi_nfc_hw_ecc_correct(struct nand_chip *nand, u8 *data, u8 *oob, int hw_step, u32 status, u32 pattern_found, unsigned int user_data_sz, bool *erased) @@ -1141,7 +1186,8 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct nand_chip *nand, u8 *oob, int oob_off, int *cur_off, unsigned int *max_bitflips, - int logical_step, bool oob_required, int page) + int logical_step, bool oob_required, int page, + struct sunxi_nfc_ecc_status *result) { struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); @@ -1190,6 +1236,16 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct nand_chip *nand, pattern_found = readl(nfc->regs + nfc->caps->reg_pat_found); pattern_found = field_get(NFC_ECC_PAT_FOUND_MSK(nfc), pattern_found); + if (sunxi_nand->randomized_oob) { + sunxi_nfc_hw_ecc_record_status(nand, result, logical_step, hw_step, + readl(nfc->regs + NFC_REG_ECC_ST), + pattern_found); + memcpy_fromio(data, nfc->regs + NFC_RAM0_BASE, ecc->size); + sunxi_nfc_hw_ecc_get_prot_oob_bytes(nand, oob, hw_step, bbm, + page, user_data_sz); + return 0; + } + bitflips = sunxi_nfc_hw_ecc_correct(nand, data, oob_required ? oob : NULL, hw_step, readl(nfc->regs + NFC_REG_ECC_ST), pattern_found, user_data_sz, &erased); @@ -1290,9 +1346,156 @@ static int sunxi_nfc_hw_ecc_read_extra_oob(struct nand_chip *nand, return 0; } +static bool sun4i_a10_nfc_spare_is_erased(struct nand_chip *nand, + const u8 *spare, int page) +{ + struct mtd_info *mtd = nand_to_mtd(nand); + unsigned int block_page = page % mtd_div_by_ws(mtd->erasesize, mtd); + + /* + * The older vendor spare scans recognize exact four-byte erased + * signatures on page zero and pages 127 modulo 128. With their + * 1 KiB ECC steps these correspond to four physical 0xff bytes. + * Other pages require all eight spare bytes to be 0xff. + */ + if (nand->ecc.size == 1024 && + (!block_page || block_page % 128 == 127) && + !memchr_inv(spare, 0xff, USER_DATA_SZ)) + return true; + + return !memchr_inv(spare, 0xff, 8); +} + +static bool sun50i_h616_nfc_spare_is_erased(struct nand_chip *nand, + const u8 *spare, int page) +{ + unsigned int erased = 0; + int i; + + /* Byte zero and at least nine of ten bytes must be 0xff. */ + for (i = 0; i < 10; i++) + erased += spare[i] == 0xff; + + return spare[0] == 0xff && erased >= 9; +} + +static bool sunxi_nfc_hw_ecc_spare_is_erased(struct nand_chip *nand, int page) +{ + struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); + struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); + struct nand_ecc_ctrl *ecc = &nand->ecc; + u16 state = sunxi_nfc_randomizer_state(nand, page, true); + u8 spare[10]; + unsigned int len, pos = 0; + int i, off; + + /* + * Reconstruct the physical spare prefix from the hardware's decoded + * user data. Each ECC step restarts the OOB randomizer; H6/H616 pack + * the entire prefix in step zero. Pad unavailable bytes with 0xff. + */ + memset(spare, 0xff, sizeof(spare)); + for (i = 0; i < ecc->steps && pos < sizeof(spare); i++) { + len = min_t(unsigned int, sunxi_nfc_user_data_sz(sunxi_nand, i), + sizeof(spare) - pos); + off = sunxi_get_oob_offset(sunxi_nand, ecc, i); + memcpy(spare + pos, nand->oob_poi + off, len); + sunxi_nfc_randomize_buf(state, spare + pos, len); + pos += len; + } + + return nfc->caps->spare_is_erased(nand, spare, page); +} + +static int sunxi_nfc_hw_ecc_read_unprotected_oob(struct nand_chip *nand, + bool dma, int page) +{ + struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); + struct mtd_info *mtd = nand_to_mtd(nand); + struct nand_ecc_ctrl *ecc = &nand->ecc; + unsigned int len, off; + u16 state; + int ret, i; + + for (i = 0; i < ecc->steps; i++) { + len = sunxi_nfc_user_data_sz(sunxi_nand, i); + off = sunxi_get_ecc_offset(sunxi_nand, ecc, i); + ret = sunxi_nfc_read_column(nand, page, mtd->writesize + off, + nand->oob_poi + off, ecc->bytes); + if (ret) + return ret; + /* Preserve each path's normal representation of ECC bytes. */ + if (!dma) { + state = sunxi_nfc_randomizer_state(nand, page, true); + state = sunxi_nfc_randomizer_step(state, len * 8 + 15); + sunxi_nfc_randomize_buf(state, nand->oob_poi + off, + ecc->bytes); + } + } + + off = sunxi_get_oob_offset(sunxi_nand, ecc, ecc->steps); + len = mtd->oobsize - off; + if (len) { + ret = sunxi_nfc_read_column(nand, page, mtd->writesize + off, + nand->oob_poi + off, len); + if (ret) + return ret; + /* The unprotected tail uses the page seed and its 15-bit advance. */ + state = sunxi_nfc_randomizer_state(nand, page, false); + state = sunxi_nfc_randomizer_step(state, 15); + sunxi_nfc_randomize_buf(state, nand->oob_poi + off, len); + } + + return 0; +} + +static int +sunxi_nfc_hw_ecc_finish_randomized_read(struct nand_chip *nand, u8 *buf, + struct sunxi_nfc_ecc_status *result, + bool oob_required, bool dma, int page) +{ + struct mtd_info *mtd = nand_to_mtd(nand); + struct nand_ecc_ctrl *ecc = &nand->ecc; + int ret; + + /* + * The vendor treats an all-zero physical page as bad, even without + * ECC errors. This takes precedence over the spare-byte heuristic. + */ + if (result->zero_steps == GENMASK(ecc->steps - 1, 0)) { + memset(buf, 0, mtd->writesize); + memset(nand->oob_poi, 0, mtd->oobsize); + mtd->ecc_stats.failed += ecc->steps; + return 0; + } + + if (result->error_steps && sunxi_nfc_hw_ecc_spare_is_erased(nand, page)) { + memset(buf, 0xff, mtd->writesize); + memset(nand->oob_poi, 0xff, mtd->oobsize); + return 0; + } + + /* + * Keep the original decoded main and protected OOB bytes on ECC failure. + * BBT pattern scans inspect them even when an ECC error is reported. + * Read the remaining OOB only when requested, not to classify the page. + */ + if (oob_required) { + ret = sunxi_nfc_hw_ecc_read_unprotected_oob(nand, dma, page); + if (ret) + return ret; + } + + mtd->ecc_stats.corrected += result->corrected; + mtd->ecc_stats.failed += hweight32(result->error_steps); + + return result->max_bitflips; +} + static int sunxi_nfc_hw_ecc_read_batch_dma(struct nand_chip *nand, u8 *buf, int oob_required, int page, int first_step, int nchunks, + struct sunxi_nfc_ecc_status *result, bool *erased_chunk_found) { bool randomized = nand->options & NAND_NEED_SCRAMBLING; @@ -1375,6 +1578,14 @@ static int sunxi_nfc_hw_ecc_read_batch_dma(struct nand_chip *nand, u8 *buf, user_data_sz = sunxi_nfc_user_data_sz(sunxi_nand, logical_step); + if (sunxi_nand->randomized_oob) { + sunxi_nfc_hw_ecc_record_status(nand, result, logical_step, i, status, + pattern_found); + sunxi_nfc_hw_ecc_get_prot_oob_bytes(nand, oob, reg_index, !logical_step, + page, user_data_sz); + continue; + } + bitflips = sunxi_nfc_hw_ecc_correct(nand, randomized ? data : NULL, oob_required ? oob : NULL, i, status, pattern_found, @@ -1401,6 +1612,9 @@ static int sunxi_nfc_hw_ecc_read_batch_dma(struct nand_chip *nand, u8 *buf, sunxi_nfc_hw_ecc_update_stats(nand, &max_bitflips, bitflips); } + if (sunxi_nand->randomized_oob) + return 0; + if (status & NFC_ECC_ERR_MSK(nfc)) { for (i = 0; i < nchunks; i++) { int logical_step = first_step + i; @@ -1430,7 +1644,9 @@ static int sunxi_nfc_hw_ecc_read_batch_dma(struct nand_chip *nand, u8 *buf, static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, u8 *buf, int oob_required, int page, int nchunks) { + struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); struct mtd_info *mtd = nand_to_mtd(nand); + struct sunxi_nfc_ecc_status result = {}; unsigned int corrected = mtd->ecc_stats.corrected; unsigned int failed = mtd->ecc_stats.failed; unsigned int max_bitflips = 0; @@ -1440,13 +1656,17 @@ static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, u8 *buf, for (first_step = 0; first_step < nchunks; first_step += batch_steps) { batch_steps = sunxi_nfc_dma_batch_steps(nand, first_step, nchunks); ret = sunxi_nfc_hw_ecc_read_batch_dma(nand, buf, oob_required, page, - first_step, batch_steps, + first_step, batch_steps, &result, &erased_chunk_found); if (ret < 0) goto err_stats; max_bitflips = max_t(unsigned int, max_bitflips, ret); } + if (sunxi_nand->randomized_oob) + return sunxi_nfc_hw_ecc_finish_randomized_read(nand, buf, &result, + oob_required, true, page); + if (oob_required) { ret = sunxi_nfc_hw_ecc_read_extra_oob(nand, nand->oob_poi, NULL, !erased_chunk_found, page); @@ -1556,6 +1776,7 @@ static int sunxi_nfc_hw_ecc_read_page(struct nand_chip *nand, uint8_t *buf, struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); struct mtd_info *mtd = nand_to_mtd(nand); struct nand_ecc_ctrl *ecc = &nand->ecc; + struct sunxi_nfc_ecc_status result = {}; unsigned int max_bitflips = 0; int ret, i, cur_off = 0; bool erased_chunk_found = false; @@ -1578,13 +1799,19 @@ static int sunxi_nfc_hw_ecc_read_page(struct nand_chip *nand, uint8_t *buf, ret = sunxi_nfc_hw_ecc_read_chunk(nand, data, data_off, oob, oob_off + mtd->writesize, &cur_off, &max_bitflips, - i, oob_required, page); + i, oob_required, page, &result); if (ret < 0) goto out; else if (ret) erased_chunk_found = true; } + if (sunxi_nand->randomized_oob) { + ret = sunxi_nfc_hw_ecc_finish_randomized_read(nand, buf, &result, + oob_required, false, page); + goto out; + } + if (oob_required) { ret = sunxi_nfc_hw_ecc_read_extra_oob(nand, nand->oob_poi, &cur_off, !erased_chunk_found, page); @@ -1630,6 +1857,10 @@ static int sunxi_nfc_hw_ecc_read_subpage(struct nand_chip *nand, int ret, i, cur_off = 0; unsigned int max_bitflips = 0; + /* The vendor spare test and all-zero detection classify a whole page. */ + if (sunxi_nand->randomized_oob) + return sunxi_nfc_hw_ecc_read_page(nand, bufpoi, false, page); + sunxi_nfc_select_chip(nand, nand->cur_cs); ret = nand_read_page_op(nand, page, 0, NULL, 0); @@ -1650,7 +1881,7 @@ static int sunxi_nfc_hw_ecc_read_subpage(struct nand_chip *nand, oob, oob_off + mtd->writesize, &cur_off, &max_bitflips, i, - false, page); + false, page, NULL); if (ret < 0) goto out; } @@ -1669,6 +1900,9 @@ static int sunxi_nfc_hw_ecc_read_subpage_dma(struct nand_chip *nand, int nchunks = DIV_ROUND_UP(data_offs + readlen, nand->ecc.size); int ret; + if (to_sunxi_nand(nand)->randomized_oob) + return sunxi_nfc_hw_ecc_read_page_dma(nand, buf, false, page); + sunxi_nfc_select_chip(nand, nand->cur_cs); ret = nand_read_page_op(nand, page, 0, NULL, 0); @@ -2300,6 +2534,10 @@ static int sunxi_nand_hw_ecc_ctrl_init(struct nand_chip *nand, ecc->strength *= 2; } + /* This format requires an ECC step that fits in the page. */ + if (sunxi_nand->randomized_oob && mtd->writesize < ecc->size) + return -EINVAL; + /* Add ECC info retrieval from DT */ for (ecc_mode = 0; ecc_mode < nfc->caps->nstrengths; ecc_mode++) { if (ecc->strength <= strengths[ecc_mode]) { @@ -2369,6 +2607,10 @@ static int sunxi_nand_hw_ecc_ctrl_init(struct nand_chip *nand, sunxi_nand->ecc.ecc_ctl = NFC_ECC_MODE(nfc, ecc_mode) | NFC_ECC_EXCEPTION | NFC_ECC_PIPELINE | NFC_ECC_EN; + /* Run ECC on uniform data too, so the randomized spare bytes are decoded. */ + if (sunxi_nand->randomized_oob) + sunxi_nand->ecc.ecc_ctl &= ~NFC_ECC_EXCEPTION; + if (ecc->size == 512) { if (nfc->caps->has_ecc_block_512) { sunxi_nand->ecc.ecc_ctl |= NFC_ECC_BLOCK_512; @@ -2383,6 +2625,8 @@ static int sunxi_nand_hw_ecc_ctrl_init(struct nand_chip *nand, static int sunxi_nand_attach_chip(struct nand_chip *nand) { + struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); + struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); const struct nand_ecc_props *requirements = nanddev_get_ecc_requirements(&nand->base); struct nand_ecc_ctrl *ecc = &nand->ecc; @@ -2392,6 +2636,14 @@ static int sunxi_nand_attach_chip(struct nand_chip *nand) if (nand->bbt_options & NAND_BBT_USE_FLASH) nand->bbt_options |= NAND_BBT_NO_OOB; + if (sunxi_nand->randomized_oob && + ecc->engine_type != NAND_ECC_ENGINE_TYPE_ON_HOST) + return dev_err_probe(nfc->dev, -EINVAL, + "Allwinner OOB format requires controller ECC\n"); + + if (sunxi_nand->randomized_oob) + nand->options |= NAND_NEED_SCRAMBLING; + if (nand->options & NAND_NEED_SCRAMBLING) nand->options |= NAND_NO_SUBPAGE_WRITE; @@ -2621,6 +2873,9 @@ static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc, if (!sunxi_nand) return -ENOMEM; + sunxi_nand->randomized_oob = + of_property_read_bool(np, "allwinner,randomized-oob"); + sunxi_nand->nsels = nsels; for (i = 0; i < nsels; i++) { @@ -2899,6 +3154,7 @@ static const struct sunxi_nfc_caps sunxi_nfc_a10_caps = { .max_ecc_steps = 16, .sram_size = 1024, .timings = &sun4i_a10_nfc_timings, + .spare_is_erased = sun4i_a10_nfc_spare_is_erased, }; static const struct sunxi_nfc_caps sunxi_nfc_a23_caps = { @@ -2922,6 +3178,7 @@ static const struct sunxi_nfc_caps sunxi_nfc_a23_caps = { .max_ecc_steps = 16, .sram_size = 1024, .timings = &sun4i_a10_nfc_timings, + .spare_is_erased = sun4i_a10_nfc_spare_is_erased, }; static const struct sunxi_nfc_caps sunxi_nfc_h616_caps = { @@ -2948,6 +3205,7 @@ static const struct sunxi_nfc_caps sunxi_nfc_h616_caps = { .max_ecc_steps = 32, .sram_size = 8192, .timings = &sun50i_h616_nfc_timings, + .spare_is_erased = sun50i_h616_nfc_spare_is_erased, }; static const struct of_device_id sunxi_nfc_ids[] = { From patchwork Mon Sep 14 03:01:20 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3326 Return-Path: X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from tor.lore.kernel.org (tor.lore.kernel.org [172.105.105.114]) by mxe881.netcup.net (Postfix) with ESMTPS id DD89E1C0294 for ; Mon, 14 Sep 2026 05:08:12 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=gmail.com; spf=pass (sender IP is 172.105.105.114) smtp.mailfrom=linux-sunxi+bounces-25887-noreply=patchwork.local@lists.linux.dev smtp.helo=tor.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 172.105.105.114 as permitted sender) client-ip=172.105.105.114; envelope-from=linux-sunxi+bounces-25887-noreply=patchwork.local@lists.linux.dev; helo=tor.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by tor.lore.kernel.org (Postfix) with ESMTP id 26B6132B4F for ; Mon, 14 Sep 2026 03:02:54 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id BB45E367B94; Mon, 14 Sep 2026 03:02:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="V4WQaNzx" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-oo2-f42.google.com (mail-oo2-f42.google.com [74.125.231.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4F4B3364933 for ; Mon, 14 Sep 2026 03:02:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.231.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789354922; cv=none; b=qVkJa/jgaTuGvTWHUNLYphOTf3eZaMR0OTDxziwCzHLOSJnAxlSHr1r6f5uwawHedEKcZhJRsPMA0iHVvz/hwJXRpgokMoXXsfo927saB171WJf4w9J3WNgNGim49SFqUUQpGNrifHPoBkhVMhZS301OQ69vdE/yheH6pTj0EmU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789354922; c=relaxed/simple; bh=InyBxnnGJUHrfGks0KD/ITzfsd5gn5CTfPJ5EvLq/i0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=pKtxXM+LtscGnUU4BVSdKrh8FycKaweLeNZsJs85KEX0FHZcoSDhOePlyPv7JLaGwppLO5+EIx0O399nGkZj7p2BIJT34WHIinnGR6Qtt3A/4wnkf0IjpgGKjKDWWm02ifJJmloYPeQofQI50cDNmKIrWL+hjR0wXTTchwK4Vk8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=V4WQaNzx; arc=none smtp.client-ip=74.125.231.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-oo2-f42.google.com with SMTP id 46e09a7af769-7f4f0dd550aso216253a34.0 for ; Sun, 13 Sep 2026 20:02:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789354919; x=1789959719; darn=lists.linux.dev; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=wD0VAfBnkJ1JCjUlJIh8uFV9v+cdt2HXmo4JRu4mOC0=; b=V4WQaNzxcdbJTIAgBKEVSIGmwSe3Eymj0dAnTI50AMroh2Nupmley3KM+tKAmT9Jhh h+1RV+qIkbkXkgu0gUPPFJAbTrazMY084LXMs/z7FHX6yLPIhGSKbFO93BJJz9qSxeul r3+vkj50J8APbmlAgIgWBOt3gUOHy7gNKOcZSbYlw5oHmMLemAblBIQsDGTKc7NO0NUe EPS+EBtayVHbOmrm7CTGdu8SEkjbMIC9B/bYP/U8WABUYEpTBhhhwBpyaFDPlv5bvgk+ RyUmdtQDWRG0sPCt930/hf8Aaotds3B2VTVoTBhU8HKL4ADFCiWmMWsy0DcSLbn7b/HK 1pzA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789354919; x=1789959719; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=wD0VAfBnkJ1JCjUlJIh8uFV9v+cdt2HXmo4JRu4mOC0=; b=H2C2wRbwQf0Rh6NCNN5YNTzx2KReAIh0+NRrXD9ibU+47lczbCqYjnG4AiNLAzbFi2 UA08MDK7CruWcdfHlZ982OntCmeID4jU8s/9zu5JVuUoDbikeiObWjSTXgkLGaKGQvDt PlpvvJG7nC+ci6H8jNGUbbvpDQ+rfECRAh9gJ5qUtYqwKmH7dvywdKNwMz9JPitPAKgf RXTRHWGRQvD2u+uufT2gY/s4kYTbBxZYrrHk3bFj3/TQNnY7kBBeSA6cEfJWQ5jlGHjL 9tL5yooaSbyY4O4lnNEPCRXkpBp9XmXKLo3bLOqg2ARyAPdmkNxL4V26FhmQ9bG1uL5m EH7A== X-Forwarded-Encrypted: i=1; AKwUvBzfp7RfR6XsWPSt+YzJqsmajpU5/jnEkp5nQU9WQgnNQaAcU2TWYfMPZShR2UGiWobkL+Low0lJQ8VTHA==@lists.linux.dev X-Gm-Message-State: AFuF++mPpgh5juNzU6UlySnlPd27TmTiV6NDe0ymEIEQyHo3sTN0tqgT 1Ijd9UMf0ZfTRvli42ifuDrWXPjsvg+3I8bjgvLW5pgA+3GbfuU0iVon X-Gm-Gg: AYBFou1iNXHaBiZ+TmgAaX6MAu+zWVte+6h6B2KJACgq+3EQ/i7htUHnrd3em4SOHPY nZ60kOXp1OYAzFm+442k/guVeqhlpxcUZN+WwU8HTn9hIAfJ+6wtN7mc1bUwEh+5W85QJUnhJFv Z9M1N70hWiDstDlueIBuOQIJkSvYIyjbdNlaIl5GrM01JdWXQHyMx6Q+dlGeqpXxuKvUY/EYtRg 6D9YD0LAwnGtSSn1fHoDRUjHt3sYjwR2vM/LVEOFK14StsijKr2heJll/Tsps2fMHEWv+kuCIJ2 BQTjaOpPimAEF7yNf2pGWR0LtBcpoD4cT9axtplo73A3Y/xI+XuHtYSlQH0xDmwXP3ed7zTjNv1 zwjFWH8MU3zX6mVFa4MBT1KGI6Ib8nVWA18Z+E3RtZ4pxCX+7eOASCdjuv86ioQgT+pK+ROJbUC AAYmHifVVacMkHwjhjZDuZ0O05NHcPZbHXBcwWcs7A8iQbz5vmkYi/pzLLrAK/Y9646dQ7iNHJ+ jHHnPiSUSF7FCzAHXZJKcY7cEEs9FSDJxnXNEIII/Ool+Q9Rd+V+gh+aA3PbRYlPITaHiardRyY xkqOEYcZYu/ObsRRpIqmUBoQY0R4A7wQheHP5b3F16/xh3xxSAopHKrfsQdIJqkKAS7fzPLCmhP jd09tZNi5WyIEAlH2i18TswDFiG4Gbw== X-Received: by 2002:a05:6830:67ca:b0:800:bca4:5626 with SMTP id 46e09a7af769-80899266b51mr285872a34.19.1789354919239; Sun, 13 Sep 2026 20:01:59 -0700 (PDT) Received: from [127.0.1.1] (184-96-157-145.hlrn.qwest.net. [184.96.157.145]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-803f60feba1sm10619014a34.13.2026.09.13.20.01.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 13 Sep 2026 20:01:58 -0700 (PDT) From: James Hilliard Date: Sun, 13 Sep 2026 21:01:20 -0600 Subject: [PATCH v5 14/18] mtd: rawnand: sunxi: select the packed H6/H616 OOB layout Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-14-7d711076a6f7@gmail.com> References: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-0-7d711076a6f7@gmail.com> In-Reply-To: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-0-7d711076a6f7@gmail.com> To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Maxime Ripard , Richard Genoud , Masahiro Yamada , Boris Brezillon , Brian Norris Cc: linux-mtd@lists.infradead.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, James Hilliard X-Mailer: b4 0.15.2 X-MORS-Enabled: yes X-MORS-DOMAIN: patchwork.local X-MORS-HOSTING: hosting172546 X-MORS-USER: hosting172546 X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= The H6/H616 controller can configure a separate protected user-data length for every ECC step. Mainline fills all space left after ECC with user data. This changes the physical ECC offsets from those used by Allwinner NAND firmware, so pages written by one layout cannot be decoded with the other. The allwinner,randomized-oob property selects the firmware's normal-page format for the configured controller hardware-ECC geometry. Use four protected user-data bytes per 1 KiB ECC step, cap the total at 16 bytes, and assign the entire total to ECC step zero. Reserve the same total before maximizing ECC strength so the selected strength leaves enough room. Keep the existing maximized mainline user-data layout when the property is absent. Older controllers have fixed four-byte user-data registers whose placement already matches the firmware and need no additional change. Signed-off-by: James Hilliard --- drivers/mtd/nand/raw/sunxi_nand.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index 0375930042ef..3fb61a10a441 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -225,6 +225,9 @@ #define USER_DATA_SZ 4 #define SUNXI_NFC_MAX_USER_DATA_SZ 32 +/* The randomized H6/H616 layout packs at most 16 bytes before ECC step 0. */ +#define SUNXI_NFC_H6_MAX_USER_DATA_SZ 16 + /** * struct sunxi_nand_chip_sel - stores information related to NAND Chip Select * @@ -2417,8 +2420,14 @@ static void sunxi_nand_detach_chip(struct nand_chip *nand) sunxi_nand->user_data_bytes = NULL; } -static int sunxi_nfc_maximize_user_data(struct nand_chip *nand, uint32_t oobsize, - int ecc_bytes, int nsectors) +static unsigned int sunxi_nfc_h6_user_data_sz(int nsectors) +{ + return min(nsectors * USER_DATA_SZ, + SUNXI_NFC_H6_MAX_USER_DATA_SZ); +} + +static int sunxi_nfc_init_user_data(struct nand_chip *nand, uint32_t oobsize, + int ecc_bytes, int nsectors) { struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); @@ -2434,6 +2443,12 @@ static int sunxi_nfc_maximize_user_data(struct nand_chip *nand, uint32_t oobsize if (!sunxi_nand->user_data_bytes) return -ENOMEM; + if (sunxi_nand->randomized_oob) { + sunxi_nand->user_data_bytes[0] = + sunxi_nfc_h6_user_data_sz(nsectors); + return 0; + } + for (step = 0; (step < nsectors) && (remaining_bytes > 0); step++) { for (i = 0; i < c->nuser_data_tab; i++) { if (c->user_data_len_tab[i] > remaining_bytes) @@ -2494,6 +2509,10 @@ static int sunxi_nand_hw_ecc_ctrl_init(struct nand_chip *nand, bytes -= 2; bytes -= total_user_data_sz; + } else if (sunxi_nand->randomized_oob) { + total_user_data_sz = + sunxi_nfc_h6_user_data_sz(nsectors); + bytes -= total_user_data_sz; } else { /* * User-data lengths are encoded in four-byte units. Reserve @@ -2564,12 +2583,12 @@ static int sunxi_nand_hw_ecc_ctrl_init(struct nand_chip *nand, nsectors = mtd->writesize / ecc->size; /* - * The rationale for variable data length is to prioritize maximum ECC - * strength, and then use the remaining space for user data. + * The default variable-length layout prioritizes maximum ECC strength, + * then uses the remaining space for user data. */ if (nfc->caps->reg_user_data_len) { - ret = sunxi_nfc_maximize_user_data(nand, mtd->oobsize, - ecc->bytes, nsectors); + ret = sunxi_nfc_init_user_data(nand, mtd->oobsize, + ecc->bytes, nsectors); if (ret) return ret; } From patchwork Mon Sep 14 03:01:21 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3328 Return-Path: X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from tor.lore.kernel.org (tor.lore.kernel.org [172.105.105.114]) by mxe881.netcup.net (Postfix) with ESMTPS id 8C4621C0294 for ; Mon, 14 Sep 2026 05:08:27 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=gmail.com; spf=pass (sender IP is 172.105.105.114) smtp.mailfrom=linux-sunxi+bounces-25889-noreply=patchwork.local@lists.linux.dev smtp.helo=tor.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 172.105.105.114 as permitted sender) client-ip=172.105.105.114; envelope-from=linux-sunxi+bounces-25889-noreply=patchwork.local@lists.linux.dev; helo=tor.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by tor.lore.kernel.org (Postfix) with ESMTP id 7DD9632F7A for ; Mon, 14 Sep 2026 03:02:57 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id A8D62366567; Mon, 14 Sep 2026 03:02:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="siPC4dOL" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-oo2-f42.google.com (mail-oo2-f42.google.com [74.125.231.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DAE98343D8A for ; Mon, 14 Sep 2026 03:02:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.231.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789354923; cv=none; b=cujIpV/TCtPznV7/DnqLPkUYw59mT2V8QmI505yYwj9S/lIng66daHO3kj4h7IE7F63BwwMYRU0I7xE2+aD+ApUAj+TcLdzmJ7nFI2Okdwb8MsbDf2HCko4wNGczUZ8p6qnPgzlJgiNLZ1b/ZqEM5WK+t92MzVrghCnEtm41u88= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789354923; c=relaxed/simple; bh=9yChzot1ui7noQKhTCzhe1/zvJdG1xELLE60VMQMFlo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=AQQhN2xA+34CeqZ+IyTXUrfR0ngv8ITQvsnZEcgxkKkNXUV4wsMP/gisacWzDzpWDaXcJZloTx/VcbWpjWG08ov9sjlPDvl1YzCMS+V0ZwlHNZ/vzd8hKwcet20ZMeWSvK927ExuBoG1itafznkrG/mLPGc61l84EXSDuCLaDOk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=siPC4dOL; arc=none smtp.client-ip=74.125.231.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-oo2-f42.google.com with SMTP id 46e09a7af769-8050801d337so1103287a34.2 for ; Sun, 13 Sep 2026 20:02:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789354921; x=1789959721; darn=lists.linux.dev; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=F7keaBMI7wLNCHL6SSgnL5KT9FmlTHx9tj/k5MQYbvE=; b=siPC4dOL97Q6xq86gQtnDFVxmyZSqe05d3pFfgq8AP0c6lqVPgTvVJ1AaAf1ocr83x a5f6XljA2b40rx22ElV8AIMk+mO70w0PKg0ryLwy8RY/kPLvi2oBKFtPl9jhjN8l2ZA/ HIM5fvTPOEGCxuWsXTA6OLdp+dAAS/VnG/LL4Bzv2uqSjzCnf1H4rY0qwnPCRpkb4SAZ I9MC2sNvzBPRra1WQ5LJyLKdvWbMKPaP7DelqUKGHWkqvflqso+S6D2RhQj+GQADA+9A lXNOdn2Gm3qrfNB/1PsU47OB245b/eIEnOx5iSUClEYyKZLl/MLszLA71v4z6sLJFQVf X0Hw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789354921; x=1789959721; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=F7keaBMI7wLNCHL6SSgnL5KT9FmlTHx9tj/k5MQYbvE=; b=IG7Vw746FY5J2BjXoJ/mCn3glGGn9Wr8F26B611XGnAnkmst+UFsOaZfEtaLLgrxok krSi53jzsOE1uc7RuDutKmK5e8XTI4ZyavNa3aexjEn2sAUbK9Kh3JB+k+lBnOsJmuU6 wn4wf76xlWy06FT5R9ND5h9jEJjL6x4HwGrIVfeMP7dIUZC9ZFMZQ2z+Hy+o8iwIkmQz 1vA78WhJnT7KbGSxzQyZs+WtalMNLEYu/dEDE4qHY0/lLqlvzZ64RMM2aAZf4AMhartJ 390ia8Xoj1AxMpHoFcXEZ3mRr7VuqVP8gl2jdojO+mmXeGdnFUBxjfHjZvC/DORrm53x jOFw== X-Forwarded-Encrypted: i=1; AKwUvBwRwYLphTwKLp9MKVYGouCcDsp0RPnS4KMuKC+PboVj9p4aK0fQviZaYpAzZyedZqfTJv7v88ZfWWPfZQ==@lists.linux.dev X-Gm-Message-State: AFuF++koFc7S209kv53EDuP5TY4WLXyBdoRj4P0L6j5+ynKCZlxuuGss /D3QNpIGPxFO2J2UZdsU4p4zDUedp21N1Y36aMqwonrI+r5SFfk3Nb3N X-Gm-Gg: AYBFou0RZathjgUPuQv6Phdtr2ByUSdqoCXq4+1UG4OzWlHWc9WIS0gHHVRerZCr9Eb icoaOmaIVFhI2byWZeqWvXVgk/4QiKzk8lCAe8L8TKxvne1UySL6pIs9nXE6GIJnEdDVyOPwg8W /ByTZjfgDfWKZNkNfHPoCeILE3FsSM3nJXBQgI5AaV+FUhLu395cRMTD8E7Vd+eJ1h6VHqOc6bz nqNLJ+9vcpa4wt1WxFZ1c5w6Ksx3eoKwLs+TdruPs5nFszemuMvPKnb1qSe3DcMa9qaSKr5Ygup R7yHj5D3iTPJYBqPTv3GuGh8msfPD6OPSSGXO6GknEQzyryKXRMpSH/uDQzq/KA12EU35wrRn+V smm4vo1dDf5PCEkUJa+ZAYJkjxtyj6v/uL5ilmTtpAYYgG0H+COugrnSMctRdx34sdqLP21b/5e bhHvPFeti99Jw3JCAGz4Y0Pk6GAAOTRJSwllKxrg4F6DeskipAXDNwOslKlkUHxLVPuW2LqCCdv qBgGv+qrZz5F+qrrdqBnQLYd4tZ8H8b3XAJAyp5ohH078p0gM9Xxm7z5l5m4ihWeO3dVLI0rC6w 7FTza1jrWNCXsUQkgLQsx4fIcshu+8GKu8TlYbweTU52xpJ2/Uytrw+9EPLUiUhrV3/DUszw5Iw bTo3r06PoBFwD9BCZJ0pZc1FxC/hfsQ== X-Received: by 2002:a05:6830:81fb:b0:7f6:ec23:7956 with SMTP id 46e09a7af769-80897097a7cmr492616a34.2.1789354920841; Sun, 13 Sep 2026 20:02:00 -0700 (PDT) Received: from [127.0.1.1] (184-96-157-145.hlrn.qwest.net. [184.96.157.145]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-803f60feba1sm10619014a34.13.2026.09.13.20.01.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 13 Sep 2026 20:02:00 -0700 (PDT) From: James Hilliard Date: Sun, 13 Sep 2026 21:01:21 -0600 Subject: [PATCH v5 15/18] mtd: rawnand: sunxi: combine contiguous unprotected OOB reads Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-15-7d711076a6f7@gmail.com> References: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-0-7d711076a6f7@gmail.com> In-Reply-To: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-0-7d711076a6f7@gmail.com> To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Maxime Ripard , Richard Genoud , Masahiro Yamada , Boris Brezillon , Brian Norris Cc: linux-mtd@lists.infradead.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, James Hilliard X-Mailer: b4 0.15.2 X-MORS-Enabled: yes X-MORS-DOMAIN: patchwork.local X-MORS-HOSTING: hosting172546 X-MORS-USER: hosting172546 X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= The randomized-format OOB reader fetches each parity region and the unprotected tail separately. H6/H616 pack protected user data before the first ECC step, leaving a contiguous range of parity bytes and tail data. Combine adjacent parity regions without crossing protected user data, and include the tail in the final transfer. Keep software de-randomization separate so each ECC step and the tail retain their existing seed phases and PIO/DMA representations. The NAND operation parser splits transfers which exceed the controller SRAM size. This reduces column commands for OOB reads without changing erased-page classification, data-only reads or the plain-marker paths. Signed-off-by: James Hilliard --- drivers/mtd/nand/raw/sunxi_nand.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index 3fb61a10a441..b7ac8d7b0301 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -1421,14 +1421,28 @@ static int sunxi_nfc_hw_ecc_read_unprotected_oob(struct nand_chip *nand, int ret, i; for (i = 0; i < ecc->steps; i++) { - len = sunxi_nfc_user_data_sz(sunxi_nand, i); off = sunxi_get_ecc_offset(sunxi_nand, ecc, i); + len = ecc->bytes; + /* Keep decoded user data, but combine adjacent parity regions. */ + while (i + 1 < ecc->steps && + !sunxi_nfc_user_data_sz(sunxi_nand, i + 1)) { + len += ecc->bytes; + i++; + } + if (i + 1 == ecc->steps) + len = mtd->oobsize - off; + ret = sunxi_nfc_read_column(nand, page, mtd->writesize + off, - nand->oob_poi + off, ecc->bytes); + nand->oob_poi + off, len); if (ret) return ret; - /* Preserve each path's normal representation of ECC bytes. */ - if (!dma) { + } + + /* Preserve each path's normal representation of ECC bytes. */ + if (!dma) { + for (i = 0; i < ecc->steps; i++) { + len = sunxi_nfc_user_data_sz(sunxi_nand, i); + off = sunxi_get_ecc_offset(sunxi_nand, ecc, i); state = sunxi_nfc_randomizer_state(nand, page, true); state = sunxi_nfc_randomizer_step(state, len * 8 + 15); sunxi_nfc_randomize_buf(state, nand->oob_poi + off, @@ -1439,10 +1453,6 @@ static int sunxi_nfc_hw_ecc_read_unprotected_oob(struct nand_chip *nand, off = sunxi_get_oob_offset(sunxi_nand, ecc, ecc->steps); len = mtd->oobsize - off; if (len) { - ret = sunxi_nfc_read_column(nand, page, mtd->writesize + off, - nand->oob_poi + off, len); - if (ret) - return ret; /* The unprotected tail uses the page seed and its 15-bit advance. */ state = sunxi_nfc_randomizer_state(nand, page, false); state = sunxi_nfc_randomizer_step(state, 15); From patchwork Mon Sep 14 03:01:22 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3329 Return-Path: X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from tor.lore.kernel.org (tor.lore.kernel.org [172.105.105.114]) by mxe881.netcup.net (Postfix) with ESMTPS id 207CD1C344A for ; Mon, 14 Sep 2026 05:08:51 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=gmail.com; spf=pass (sender IP is 172.105.105.114) smtp.mailfrom=linux-sunxi+bounces-25890-noreply=patchwork.local@lists.linux.dev smtp.helo=tor.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 172.105.105.114 as permitted sender) client-ip=172.105.105.114; envelope-from=linux-sunxi+bounces-25890-noreply=patchwork.local@lists.linux.dev; helo=tor.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by tor.lore.kernel.org (Postfix) with ESMTP id 5F4572E299 for ; Mon, 14 Sep 2026 03:03:03 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 4857536B905; Mon, 14 Sep 2026 03:02:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="J3YdMKQ4" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-ot1-f44.google.com (mail-ot1-f44.google.com [209.85.210.44]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 25B3F36212D for ; Mon, 14 Sep 2026 03:02:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.44 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789354924; cv=none; b=fKPLVOLX0Ru3RHEsxCeU1EfbQhkHPk/+8rW4l5oUr04Xnz6y0FRYiapHAIaX5zsrNMU5ui2B8oPpdv7V+x2LNG591aBgeuwN7oZUNUh1lodQ+2/h5Knen9qhdCH/iAF97FG5zLeA780h4SNBrE1RdFhQWKDagBDVika1S/wZPmk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789354924; c=relaxed/simple; bh=NZw8JcFCedJgacAoPkTIc+LEMQt5mQHzie6HVHZKZUM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=jYVGuuu/sCfGVEsVHOj3OCugcNtBov+iGbH7GICGCjUnqnFh/Car1uEK6L5Kqp3Pa3j5sS4vGONWJV57JQMqB0jey6cdZ88zkvA0frIoqJRu21uqcNFvqOqyZARVU29Q1tc89+sHt5S1kFF14E7en889W4JFyX1zoDRtqcomBPE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=J3YdMKQ4; arc=none smtp.client-ip=209.85.210.44 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-ot1-f44.google.com with SMTP id 46e09a7af769-7fccba9c675so2923032a34.0 for ; Sun, 13 Sep 2026 20:02:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789354922; x=1789959722; darn=lists.linux.dev; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=OyRFeG3dg/KDzFyQJutH2zdFtVEXygh+smPcYHYkDoA=; b=J3YdMKQ4Qca6/mtmf0M8InNdOdtpKmXSmfxaAH2pJOxdD9+ZVjfZWa7TDVJLStgQSq T5LXgSyyypugvrn6l/iB/TIlvsi9U5PoN8GIm00FIfjJsSxvkT5b/08pARh1CCT2SpOJ C+FlJG4JtCK2QJNEZo94HCi7oyoFR5qruXVACsce/cFmZw1ZavZfrd5UJFwfBeAEZ4gI xn5xDjMwKlkM9RIxtOP8xvyaL/UW7xGA7CjGlj1URPLO4+YtLAyBdeDA+n281iW7QKMQ Eydt0beR1PtOwYnYW612/37nBkMkxuU1acAFzK3J7otkO6umHhqztSnCE7t8skgXvIoi UwlQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789354922; x=1789959722; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=OyRFeG3dg/KDzFyQJutH2zdFtVEXygh+smPcYHYkDoA=; b=oM8+1aK6FfCUlmz16QdhpLefWm9/dHt3cFXvpcboxllRQYVv29AAnJmZe+kc+o3Ecq rZSeI0f0vDKiecX+4LibG0nujlEhMRXqEGbgtjVJCsoCD0vHdIS+kcnxDv9xQEijxNpG i/O7tCugCnjczlq6yTZi8n6wW20JDSDQM9U7fZ3wWlvaXAr6sPwnqxbJgzNd/pmthTfc Xkr6L3mvecerZKd3P3zjZ76N8BNRt80OLhKlXPsK7K3YFzyyH40Q4ha+MQi5IPkza8RB TlWFykzbX3FSFQ+QEGF1YiMUuyQXmlFM2cif8Wa14MUFlFsp77TEPtC05lCjyeuyMcRc V1/g== X-Forwarded-Encrypted: i=1; AKwUvByz5MPIL7FwD5D5JJanUyd5oCkhDx+21OttOL3gmmDlvkQax1YwBBUc8F1NWHEBsmI4B257bpjG/nZP2w==@lists.linux.dev X-Gm-Message-State: AFuF++nygJ/bkb33rtgl7zRkpMIFaqTdLHaDCBpkORBYfXz2GKOlW549 A+0xbn85APGUFaa5gsMLzZcUTApnxoXCI8YlHwQS9xOdAQp6H3BM9UzO X-Gm-Gg: AYBFou3hODKuK0rCPbRMAnKFSQKFsgSIv3GP5o4iBkMF2vc1H/jyVORzgGTucA/AuPY 9g7OSBiJEToZ+G+4h+Ki2T8ljEgKzX4n7lxlu03oaH2BvkKrv361V4sENKUi5hJ1lXecpswHMp6 hz2fmMDRYzCt4RNu95YS+y7IYWZVhthm7QXgOmaOi1YlHe/Ue8C8zgtE6ISsLOTf1GhJmrSmrHp ER1d42RFbnj66adIEa/oQwwmVkNyjcnT+si7LK67jEwzUuYGBUeQ1kO/sRZrS+1dK4eWPESdD/y MwgQK7hF8B/y8FedF2WSXL/ANfpUBjk8ZqSrGXAQvHi+mFslfHIBMYjWeKA+15Hw1FBD9sAGDTK tUSniDNZ+2kNqoTEW02SgUkEWLYAKEGPvQ/PedReHduD9vBTjS36LM6zr+2784FBV7/R2qSSWMo Zina31WStCRZVU+7krphWwSRRUV3W2NSmD04WHojHP6IPlIED2JsDPFIQDXk9/Mlr9ZgLnLjhPB 88SUUD3uIOkCT5uQBgnx+Lp2p9gM3dL//7dtkHBIa2xJch3koBPCzciRhkoFULuC+0C/1Vy6eNT IeOj6yDzMUk0Q6RWkmnbvRww0UKhx1v8IKbvhS8nUQGqMh5rWXu0pBNdLBIufMFZmUZJnsslTef vQx2gTaR/P0mvI5zYo0n6MvlZmJCSgQ== X-Received: by 2002:a05:6830:6d2a:b0:7de:9b99:a8ee with SMTP id 46e09a7af769-80719632b97mr1941438a34.9.1789354922030; Sun, 13 Sep 2026 20:02:02 -0700 (PDT) Received: from [127.0.1.1] (184-96-157-145.hlrn.qwest.net. [184.96.157.145]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-803f60feba1sm10619014a34.13.2026.09.13.20.02.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 13 Sep 2026 20:02:01 -0700 (PDT) From: James Hilliard Date: Sun, 13 Sep 2026 21:01:22 -0600 Subject: [PATCH v5 16/18] mtd: rawnand: sunxi: avoid duplicate chip setup before page commands Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-16-7d711076a6f7@gmail.com> References: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-0-7d711076a6f7@gmail.com> In-Reply-To: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-0-7d711076a6f7@gmail.com> To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Maxime Ripard , Richard Genoud , Masahiro Yamada , Boris Brezillon , Brian Norris Cc: linux-mtd@lists.infradead.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, James Hilliard X-Mailer: b4 0.15.2 X-MORS-Enabled: yes X-MORS-DOMAIN: patchwork.local X-MORS-HOSTING: hosting172546 X-MORS-USER: hosting172546 X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= The page helpers invoke exec_op(), which selects the chip and programs its timing and spare-area registers. Remove the identical setup directly before those helpers in the read callbacks and PIO write callbacks. Keep explicit selection in the DMA write callback: it accesses controller registers and prepares DMA before issuing the program-begin operation. Do not cache controller state or change selection after a controller reset. Signed-off-by: James Hilliard --- drivers/mtd/nand/raw/sunxi_nand.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index b7ac8d7b0301..4103337f6a07 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -1794,8 +1794,6 @@ static int sunxi_nfc_hw_ecc_read_page(struct nand_chip *nand, uint8_t *buf, int ret, i, cur_off = 0; bool erased_chunk_found = false; - sunxi_nfc_select_chip(nand, nand->cur_cs); - ret = nand_read_page_op(nand, page, 0, NULL, 0); if (ret) return ret; @@ -1844,8 +1842,6 @@ static int sunxi_nfc_hw_ecc_read_page_dma(struct nand_chip *nand, u8 *buf, { int ret; - sunxi_nfc_select_chip(nand, nand->cur_cs); - ret = nand_read_page_op(nand, page, 0, NULL, 0); if (ret) return ret; @@ -1874,8 +1870,6 @@ static int sunxi_nfc_hw_ecc_read_subpage(struct nand_chip *nand, if (sunxi_nand->randomized_oob) return sunxi_nfc_hw_ecc_read_page(nand, bufpoi, false, page); - sunxi_nfc_select_chip(nand, nand->cur_cs); - ret = nand_read_page_op(nand, page, 0, NULL, 0); if (ret) return ret; @@ -1916,8 +1910,6 @@ static int sunxi_nfc_hw_ecc_read_subpage_dma(struct nand_chip *nand, if (to_sunxi_nand(nand)->randomized_oob) return sunxi_nfc_hw_ecc_read_page_dma(nand, buf, false, page); - sunxi_nfc_select_chip(nand, nand->cur_cs); - ret = nand_read_page_op(nand, page, 0, NULL, 0); if (ret) return ret; @@ -1941,8 +1933,6 @@ static int sunxi_nfc_hw_ecc_write_page(struct nand_chip *nand, struct nand_ecc_ctrl *ecc = &nand->ecc; int ret = 0, i, cur_off = 0; - sunxi_nfc_select_chip(nand, nand->cur_cs); - ret = nand_prog_page_begin_op(nand, page, 0, NULL, 0); if (ret) return ret; @@ -1986,8 +1976,6 @@ static int sunxi_nfc_hw_ecc_write_subpage(struct nand_chip *nand, struct nand_ecc_ctrl *ecc = &nand->ecc; int ret = 0, i, cur_off = 0; - sunxi_nfc_select_chip(nand, nand->cur_cs); - ret = nand_prog_page_begin_op(nand, page, 0, NULL, 0); if (ret) return ret; From patchwork Mon Sep 14 03:01:23 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3323 Return-Path: X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from sin.lore.kernel.org (sin.lore.kernel.org [104.64.211.4]) by mxe881.netcup.net (Postfix) with ESMTPS id BF14F1C344A for ; Mon, 14 Sep 2026 05:06:30 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=gmail.com; spf=pass (sender IP is 104.64.211.4) smtp.mailfrom=linux-sunxi+bounces-25891-noreply=patchwork.local@lists.linux.dev smtp.helo=sin.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 104.64.211.4 as permitted sender) client-ip=104.64.211.4; envelope-from=linux-sunxi+bounces-25891-noreply=patchwork.local@lists.linux.dev; helo=sin.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by sin.lore.kernel.org (Postfix) with ESMTP id 063482759B for ; Mon, 14 Sep 2026 03:03:10 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id E117036E47A; Mon, 14 Sep 2026 03:02:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="S5jnI4hN" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-ot1-f46.google.com (mail-ot1-f46.google.com [209.85.210.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D5DE7365A1A for ; Mon, 14 Sep 2026 03:02:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789354926; cv=none; b=JW6Xk8hmTnoqFrOr7PuTLfgM06j62iJrk/Bg501Bq5Xh/CqTFHfUMqtkB1iK05Kv3Oeq6cpuv9p5uZrn/4ZJYMEPB/EzS9K5HRaXbradcJTHVQAYnuU9B6TRwumsXmOy/C90npoUEehKkreo0iSJmbF8HNquUryPzWHqMDFgDss= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789354926; c=relaxed/simple; bh=ySqoYQ1XnzlLitXctoBmkfL5K98OvUxXEwUoBjaPCPg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Haqd0DRN5Yb3A4OyeD09+Ger9yF7p3sGz8O4Mm1xbor++B2SQywi9xc8QYBsEm/WLjyHy8kNpMrzjoJIsuA5b7X8/B8KqfsM1kNMIEv8hCdINGN2/Gn02BwA5jzt1kz89wtxJwKA9phWXuyKBQANoRR7KOYMEK+330nakluRl8Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=S5jnI4hN; arc=none smtp.client-ip=209.85.210.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-ot1-f46.google.com with SMTP id 46e09a7af769-805453b1c0cso1846804a34.1 for ; Sun, 13 Sep 2026 20:02:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789354923; x=1789959723; darn=lists.linux.dev; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=IWbz9jOOwHMkOzJhcyeNlTXZtZx9bja+bTwtbiwOKWk=; b=S5jnI4hNlD/85Pw6EBGylQfP7lOjAUtEReYlFpZkGstqXI4Fs9tGmj++Epx/x+LmGq PXD2Jox6tHkWrh45fas/SLHaFMLpHIsbt0lEAF8IJkGSm0Mfn95KYPPt6bgq6nqxzNOe R16CLXIGeu8Mlv969p+87B0rnfH6Iad6a9jBD/8Bf6bkYeFKQ8W+4VUUVI061Pb398a1 PT8vyU3RghInR34QttUebs6KSHInwTJYaouVajgTwF4CaGjif5n5CoQQZqdeZw1OgMOL NTdlfcfWtiieQ88X9JkNUorSCBcCQUIL8nULtP9Lr6AlqEy/cU8Y7wXffbE3rLX4ndmr h9HA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789354923; x=1789959723; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=IWbz9jOOwHMkOzJhcyeNlTXZtZx9bja+bTwtbiwOKWk=; b=OvNeSSx3qVXRfLo0o+hGtxpj61Ok094miBpU6NyIRhxsGQiDAwoXAmVryXfAvZWjYJ aQdxR9Gcj7VUpbNGUEtC3wJK6YAyQPS5DzYzCHjvX2g9qL/2MdO2b/uz6iQbdR8HQAjA ZHdWpCkswOv387uUU3iTBL6PsrR1CPNcTz1BpZKyGO4pOiLsb2Lis0CilGo9BtgZYO5V Tp+8omocMTakkZDj5ndCDC2z3rPgidr4YaKoaagaZIZEnZOFQ+Ch5srFA1xrB7Oej1gl NvqU3FYYR+PNTrAO6b5kTQ148j9iL9Zl5xcIf4584gUrA964EX7oLcc/id8HTr/RzRje Uz9w== X-Forwarded-Encrypted: i=1; AKwUvBwRMz4gq4hjU63TYI++s2uoGjWSVxujigNQImQIL1jI28buCcmuNe0Rv+Ms0JT4bnMJmsTEOTe/ObFFAg==@lists.linux.dev X-Gm-Message-State: AFuF++lFzJKr5hlHsPFxG4inK9/0odz1ILgn5F089Y8Sy+BAos1J4Oym Mch0aJZcjsQUSTDSXY4WY8sUOwX7+hKElrBYfOtefWaKPkz1KZyUdMQd X-Gm-Gg: AYBFou19Wq6NsyEYEBgPzyHI/ncg6uQAKCvyuS/HUdbMnycm5AAlSLEfuA8Y/SLzReR E+v2zJd0nQNFbpydffe5dBL8BreKyfPRcICr2oFpqzlHFuNO4r8FhK/TQaqByAMkZ4wY2ENRPSz WMuOUJYD/vPtFVBtyJVckC7ymKfXr09Y8RAuaN/XUflgomrHQiLSMjHfv1vMJZxQr4UWR69Vy7p af4OpI4+6Byp7blymIk6GDIJBo6osq0KUTGVLaXmsZmvW7IhF8fSQfU9QwYJsPOIB+H+c/uhWa2 HXFig/1QlZtCDGPq4d1IbxJ2FU8Ny2q49RG7rnimL7U9h9S4U/h29vxRLvK/r5EuM/KPUW09dqQ OnJ0kmtqZ6Rk8OvLaZXwqsoDQPgaJA3pcStomWoZv18rYPpomK0Y+34ghtioxZ4+EuJeiElyOyu 7vlZluGmB5I1WmOPAJ0IGV62ED3AX2Pb2lITi2XjnIWUTgud3ILiGU2qSc/PTi6MzMTdbYNY1+H JlVj8Q6SrJPjSlXx/A+B5v3vA1eLdmIfZiTtqzm/dPaig4GybiU5Dc6UHXQs/R1OND24XtkmqxY aP815e2K8UBQ0u+UtS+Rv/U8Vhf0kujoLtjlm0wTlNkEYjJicrBykGRA4DOM+E7M8ki/FUeDc2v 7aQX4qnQeV1ckb5iGnGgtnewBkK2oI1EnoLkjP9Ji X-Received: by 2002:a05:6830:3888:b0:7e9:ead3:4449 with SMTP id 46e09a7af769-80897489f75mr263437a34.6.1789354923503; Sun, 13 Sep 2026 20:02:03 -0700 (PDT) Received: from [127.0.1.1] (184-96-157-145.hlrn.qwest.net. [184.96.157.145]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-803f60feba1sm10619014a34.13.2026.09.13.20.02.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 13 Sep 2026 20:02:03 -0700 (PDT) From: James Hilliard Date: Sun, 13 Sep 2026 21:01:23 -0600 Subject: [PATCH v5 17/18] mtd: rawnand: sunxi: reduce user-data length register accesses Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-17-7d711076a6f7@gmail.com> References: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-0-7d711076a6f7@gmail.com> In-Reply-To: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-0-7d711076a6f7@gmail.com> To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Maxime Ripard , Richard Genoud , Masahiro Yamada , Boris Brezillon , Brian Norris Cc: linux-mtd@lists.infradead.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, James Hilliard X-Mailer: b4 0.15.2 X-MORS-Enabled: yes X-MORS-DOMAIN: patchwork.local X-MORS-HOSTING: hosting172546 X-MORS-USER: hosting172546 X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= DMA reads and writes clear every user-data length register and then read-modify-write one field at a time. Multiple ECC steps share each register, so this repeats MMIO accesses to the same words. Build each register value in memory and write it once, including zero lengths for unused slots. Reprogram every word for every DMA operation instead of caching hardware state, so controller resets and switches between chips need no special cache invalidation. Share the length encoding with a PIO-specific setter. PIO always uses hardware slot zero, and its page callbacks clear all length registers before the chunk loop. Write the slot-zero value directly instead of reading and modifying the same register for every chunk. Keep the per-operation clearing so other slots remain zero after DMA fallback. Signed-off-by: James Hilliard --- drivers/mtd/nand/raw/sunxi_nand.c | 75 +++++++++++++++++++++++++-------------- 1 file changed, 48 insertions(+), 27 deletions(-) diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index 4103337f6a07..2b8ed142c9bf 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -1005,35 +1005,60 @@ static void sunxi_nfc_reset_user_data_len(struct sunxi_nfc *nfc) writel(0, nfc->regs + NFC_REG_USER_DATA_LEN(nfc, i)); } -static void sunxi_nfc_set_user_data_len(struct sunxi_nfc *nfc, - int len, int hw_step) +static int sunxi_nfc_user_data_len_code(struct sunxi_nfc *nfc, int len) { - bool found = false; - u32 val; int i; + for (i = 0; i < nfc->caps->nuser_data_tab; i++) { + if (len == nfc->caps->user_data_len_tab[i]) + return i; + } + + dev_warn(nfc->dev, "Unsupported length for user data reg: %d\n", len); + return -EINVAL; +} + +static void sunxi_nfc_set_user_data_len_pio(struct sunxi_nfc *nfc, int len) +{ + int code; + /* not all SoCs have this register */ if (!nfc->caps->reg_user_data_len) return; - for (i = 0; i < nfc->caps->nuser_data_tab; i++) { - if (len == nfc->caps->user_data_len_tab[i]) { - found = true; - break; - } - } - - if (!found) { - dev_warn(nfc->dev, - "Unsupported length for user data reg: %d\n", len); + code = sunxi_nfc_user_data_len_code(nfc, len); + if (code < 0) return; - } - val = readl(nfc->regs + NFC_REG_USER_DATA_LEN(nfc, hw_step)); + /* PIO uses slot zero; the page callback clears all other slots. */ + writel(FIELD_PREP(NFC_USER_DATA_LEN_MSK(0), code), + nfc->regs + NFC_REG_USER_DATA_LEN(nfc, 0)); +} + +static void sunxi_nfc_set_user_data_len_dma(struct nand_chip *nand, + int first_step, int nchunks) +{ + struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); + struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); + int first, step, len, code; + u32 val; + + if (!nfc->caps->reg_user_data_len) + return; - val &= ~NFC_USER_DATA_LEN_MSK(hw_step); - val |= field_prep(NFC_USER_DATA_LEN_MSK(hw_step), i); - writel(val, nfc->regs + NFC_REG_USER_DATA_LEN(nfc, hw_step)); + /* Write each packed register once, including zeroes for unused slots. */ + for (first = 0; first < nfc->caps->max_ecc_steps; + first += NFC_REG_USER_DATA_LEN_CAPACITY) { + val = 0; + for (step = first; step < nchunks && + step < first + NFC_REG_USER_DATA_LEN_CAPACITY; step++) { + len = sunxi_nfc_user_data_sz(sunxi_nand, first_step + step); + code = sunxi_nfc_user_data_len_code(nfc, len); + if (code >= 0) + val |= field_prep(NFC_USER_DATA_LEN_MSK(step), code); + } + writel(val, nfc->regs + NFC_REG_USER_DATA_LEN(nfc, first)); + } } static void sunxi_nfc_hw_ecc_set_prot_oob_bytes(struct nand_chip *nand, @@ -1223,7 +1248,7 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct nand_chip *nand, if (ret) return ret; - sunxi_nfc_set_user_data_len(nfc, user_data_sz, hw_step); + sunxi_nfc_set_user_data_len_pio(nfc, user_data_sz); sunxi_nfc_randomizer_config(nand, page, false); sunxi_nfc_randomizer_enable(nand); writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | NFC_ECC_OP, @@ -1540,10 +1565,7 @@ static int sunxi_nfc_hw_ecc_read_batch_dma(struct nand_chip *nand, u8 *buf, return ret; sunxi_nfc_hw_ecc_enable(nand); - sunxi_nfc_reset_user_data_len(nfc); - for (i = 0; i < nchunks; i++) - sunxi_nfc_set_user_data_len(nfc, - sunxi_nfc_user_data_sz(sunxi_nand, first_step + i), i); + sunxi_nfc_set_user_data_len_dma(nand, first_step, nchunks); /* exec_op() restores the page's spare base during column changes. */ if (first_step) writel(mtd->writesize + sunxi_get_oob_offset(sunxi_nand, ecc, first_step), @@ -1733,7 +1755,7 @@ static int sunxi_nfc_hw_ecc_write_chunk(struct nand_chip *nand, sunxi_nfc_randomizer_config(nand, page, false); sunxi_nfc_randomizer_enable(nand); - sunxi_nfc_set_user_data_len(nfc, user_data_sz, hw_step); + sunxi_nfc_set_user_data_len_pio(nfc, user_data_sz); sunxi_nfc_hw_ecc_set_prot_oob_bytes(nand, oob, hw_step, bbm, page, user_data_sz); @@ -2037,7 +2059,7 @@ static int sunxi_nfc_hw_ecc_write_page_dma(struct nand_chip *nand, goto pio_fallback; } - sunxi_nfc_reset_user_data_len(nfc); + sunxi_nfc_set_user_data_len_dma(nand, first_step, batch_steps); for (i = first_step; i < first_step + batch_steps; i++) { unsigned int user_data_sz = sunxi_nfc_user_data_sz(sunxi_nand, i); int oob_off = sunxi_get_oob_offset(sunxi_nand, ecc, i); @@ -2045,7 +2067,6 @@ static int sunxi_nfc_hw_ecc_write_page_dma(struct nand_chip *nand, sunxi_nfc_hw_ecc_set_prot_oob_bytes(nand, oob, reg_index, !i, page, user_data_sz); - sunxi_nfc_set_user_data_len(nfc, user_data_sz, i - first_step); reg_index += user_data_sz / 4; } From patchwork Mon Sep 14 03:01:24 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3330 Return-Path: X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from tor.lore.kernel.org (tor.lore.kernel.org [172.105.105.114]) by mxe881.netcup.net (Postfix) with ESMTPS id 6E98F1C344A for ; Mon, 14 Sep 2026 05:10:00 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=gmail.com; spf=pass (sender IP is 172.105.105.114) smtp.mailfrom=linux-sunxi+bounces-25892-noreply=patchwork.local@lists.linux.dev smtp.helo=tor.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 172.105.105.114 as permitted sender) client-ip=172.105.105.114; envelope-from=linux-sunxi+bounces-25892-noreply=patchwork.local@lists.linux.dev; helo=tor.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by tor.lore.kernel.org (Postfix) with ESMTP id 675DD347C1 for ; Mon, 14 Sep 2026 03:03:19 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 805F1367F45; Mon, 14 Sep 2026 03:02:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="BEblQq1L" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-oo2-f42.google.com (mail-oo2-f42.google.com [74.125.231.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1D40333C518 for ; Mon, 14 Sep 2026 03:02:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.231.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789354929; cv=none; b=NHn7DRanc39DFnOei+ZVtLEEeXxI5EKnQrb9Xa1DA3rla6TeAzX+cpPTMyIOIhPeDTpl+IIlADjL8+mXrZ24mqqOgvnjm0KNqUhO5S9VJ+b0HXGwXR5Yn2tkaYq3ucr3RhRfUQXu1CjqLziDTtfEdxW38A6yFYVco/G+jFIHrlM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789354929; c=relaxed/simple; bh=kb1Gsrib9J7X5Iu1bioEkSbneNLgmuqapwHKJriwhEA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ohMBNpk7sHxouU/7kJASgEcCI9cn7WBP4D+1I87puorlXX8w/2uUqlnJIo5RLhosUepzYuZM8BrImK3qCbeVJOBISRf99uZP5fY0gfe5j9f9niphPFwM4PDO2h/xi6zF7lvYH4BBm5Mpsw6AZQxT7zt4fWHI1b7+rm0armxsYw8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=BEblQq1L; arc=none smtp.client-ip=74.125.231.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-oo2-f42.google.com with SMTP id 46e09a7af769-7f4f0c89e35so966587a34.2 for ; Sun, 13 Sep 2026 20:02:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789354925; x=1789959725; darn=lists.linux.dev; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=gbdzTooPdY+KDhtZ/QzGrAlPMdYJpYAben39hMkDMIQ=; b=BEblQq1Lkvx+ddB+CqZ3Q478RG4ncJSGfqZ+iiDVhDWV7k4JcJRLyheyh+bSZg2dxJ xnLu1E1U3nHma2CI3uJuKwalz2ZNkjGpajWqujuj3Ffb7fdyxJ2Vi7LaznV5BwJudE3P qTLtwAywhON5Bsqlrsx0jZqs0zwblX6j57w0USCN63ATueVLBPy9bPjMNocpfMQmE8LB PxBxuo017UXfKPpA/dJkk2DlD/Lu/CraHV3XnvO4Qcwo3nkcpwpCgxeTrJ88OosztHPd +Bc1NISMne6s2g1tN1TBhZF84OZ3mrWwPgs3+/dEzHXbfyR4SfLAcVCyw5/h0P6y/gFN fnKA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789354925; x=1789959725; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=gbdzTooPdY+KDhtZ/QzGrAlPMdYJpYAben39hMkDMIQ=; b=Qv6TAxO+94LowqBylOUbtKWkM5sO9JX7ac1UMJqYOL3XAU2LgBgQ9d4Tq2xiTGqwy/ ycLDPtKyyNIBhyFuLTvOyhT6F5lICSYxLF9Oae/5Onaq3bdX2WKOb5I/4VM6zoPzA9e0 j+OSeyIPUgVf5UxRfaf03ljKPv8nB4wI7KHKNti7WKcGRv8xnVTrBmbfnE67ImGMuqhd YqjKEiqbvMZqmscWv2c4WJoWaw3luChpDFjt40LXldbGj5jBaKg2gzLvKOTxFPXGvlKG pGKkGuJjjJs1XNLE44xcblaaX46ugmWUFDK9CN4Dj0HFDAkx8PZJwt/c9nhlwJI0LBau 5xIA== X-Forwarded-Encrypted: i=1; AKwUvBz4Hy9GoNDjNQnyApWoPMGY0rrG2OOhw6bdVhHR3gFymanKa4Z+zk1FtuaESBtSOPwWccSwiPuX/WksHA==@lists.linux.dev X-Gm-Message-State: AFuF++mr+2wO49wPnoGT+4JBNkN0XRf8LpO4ksorZftGrGA9L6CbZqWV ET5ae+rDx9dD+Z5jGEQOAWPlbIEOvTfS1YCUtw5n+oLELsCeOw6Y+o4e X-Gm-Gg: AYBFou0zumr4aWHQMR+JpPsHLURvnp9YA25twEV465Q+YmJJF0jfjIhGDKlxd7vly6D PHfw9pv4zEsWvN3G3TOIjICapR2RX7HsHACr8mpF+WM8Iq4vkdpMgLL1hCdUoMNS4XXKf/TKhBw iQzNrjfN3Q7Ub6wSjWpH4lgGmk8l2sI3bZ4nZC7BHlUOxdeD83I22AdERW+w6qGw1+QqtHCncjN YmpYo3VRZ5uJbYJLNwayFk1gazs0LFtUAFUNrgIKDsHGMI1j8dl02xQ6vKdGfV6Be37hANskwoE i/PLQIQXIY1I6pTs31W2debQdhCOgO0OfUoG/5122Z5fUM6Ho7BNxmg6qTT2zPoKJxK+GK5IjvR DiSM9NcvAMFU0jtvdvU4qC0xvvJ9FcmHbN/8R+Zgj5I5wM8Mlrsjhc+BSNjMRRsAqng4VbwmZ+t hjbaR0kW19wsjTBRLBXX2P0iVdWTyDNK0AdBQD9NuWPc9/q1q5R/nfp7aK5sZfdWyN++Ehk69VT tNoF5iw+CsLgRKrzVL4rqoWSgy4XwzOBXTSyOZe/y0pkWS97jWyoNP+9+TEo++qvo76f9zKfBAt cnGt+iH3llsTAvKfuBWP2cneaYqakHESri25b6pbDX9Epiblf0YNPSqjpmtSPZ/PzvzOgV7ADZA uqcaa55UMeCol5bfiKtvF1Lot/ZaKFw== X-Received: by 2002:a05:6830:719a:b0:7eb:3af8:8c09 with SMTP id 46e09a7af769-808972915a8mr274412a34.3.1789354924870; Sun, 13 Sep 2026 20:02:04 -0700 (PDT) Received: from [127.0.1.1] (184-96-157-145.hlrn.qwest.net. [184.96.157.145]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-803f60feba1sm10619014a34.13.2026.09.13.20.02.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 13 Sep 2026 20:02:04 -0700 (PDT) From: James Hilliard Date: Sun, 13 Sep 2026 21:01:24 -0600 Subject: [PATCH v5 18/18] mtd: rawnand: sunxi: reuse ECC status within each DMA read Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-18-7d711076a6f7@gmail.com> References: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-0-7d711076a6f7@gmail.com> In-Reply-To: <20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-0-7d711076a6f7@gmail.com> To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Maxime Ripard , Richard Genoud , Masahiro Yamada , Boris Brezillon , Brian Norris Cc: linux-mtd@lists.infradead.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, James Hilliard X-Mailer: b4 0.15.2 X-MORS-Enabled: yes X-MORS-DOMAIN: patchwork.local X-MORS-HOSTING: hosting172546 X-MORS-USER: hosting172546 X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= The DMA completion loop reads the pattern ID repeatedly and reads the same packed error-counter word for each of its four ECC steps. Snapshot the completed operation status and pattern ID, and retain the last counter word while visiting consecutive DMA steps. Read counters only for steps which use them. Reuse the shared status register value on older controllers which place the pattern flags in its upper half. Keep the existing error and pattern priority in both the plain-marker and randomized-format paths. Start a fresh snapshot after every PIO ECC operation so reuse of hardware slot zero cannot reuse status from a previous step. The snapshot is local to one callback and does not survive controller resets or DMA-to-PIO retries. Signed-off-by: James Hilliard --- drivers/mtd/nand/raw/sunxi_nand.c | 101 +++++++++++++++++++++++++------------- 1 file changed, 68 insertions(+), 33 deletions(-) diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index 2b8ed142c9bf..4af2a4f36d2e 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -1149,46 +1149,87 @@ struct sunxi_nfc_ecc_status { unsigned int max_bitflips; }; +struct sunxi_nfc_ecc_snapshot { + u32 status; + u32 pattern_found; + u32 pattern_id; + u32 count_reg; + u32 count; +}; + +static void sunxi_nfc_hw_ecc_read_status(struct nand_chip *nand, + struct sunxi_nfc_ecc_snapshot *snapshot) +{ + struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); + u32 pattern_found; + + pattern_found = readl(nfc->regs + nfc->caps->reg_pat_found); + snapshot->pattern_found = field_get(NFC_ECC_PAT_FOUND_MSK(nfc), pattern_found); + if (nfc->caps->reg_pat_found == NFC_REG_ECC_ST) + snapshot->status = pattern_found; + else + snapshot->status = readl(nfc->regs + NFC_REG_ECC_ST); + snapshot->pattern_id = 0; + if (snapshot->pattern_found && + (to_sunxi_nand(nand)->randomized_oob || + (snapshot->pattern_found & ~snapshot->status))) + snapshot->pattern_id = readl(nfc->regs + NFC_REG_PAT_ID(nfc)); + /* A new operation, including every PIO step, invalidates the count word. */ + snapshot->count_reg = ~0U; +} + +static unsigned int +sunxi_nfc_hw_ecc_read_count(struct nand_chip *nand, + struct sunxi_nfc_ecc_snapshot *snapshot, int hw_step) +{ + struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); + u32 reg = NFC_REG_ECC_ERR_CNT(nfc, hw_step); + + /* Four consecutive DMA steps share one error-counter register. */ + if (snapshot->count_reg != reg) { + snapshot->count = readl(nfc->regs + reg); + snapshot->count_reg = reg; + } + + return NFC_ECC_ERR_CNT(hw_step, snapshot->count); +} + static void sunxi_nfc_hw_ecc_record_status(struct nand_chip *nand, struct sunxi_nfc_ecc_status *result, - int logical_step, int hw_step, u32 status, - u32 pattern_found) + int logical_step, int hw_step, + struct sunxi_nfc_ecc_snapshot *snapshot) { - struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); u32 count; - if ((pattern_found & BIT(hw_step)) && - !(readl(nfc->regs + NFC_REG_PAT_ID(nfc)) & BIT(hw_step))) + if ((snapshot->pattern_found & BIT(hw_step)) && + !(snapshot->pattern_id & BIT(hw_step))) result->zero_steps |= BIT(logical_step); - if (status & NFC_ECC_ERR(hw_step)) { + if (snapshot->status & NFC_ECC_ERR(hw_step)) { result->error_steps |= BIT(logical_step); return; } - count = readl(nfc->regs + NFC_REG_ECC_ERR_CNT(nfc, hw_step)); - count = NFC_ECC_ERR_CNT(hw_step, count); + count = sunxi_nfc_hw_ecc_read_count(nand, snapshot, hw_step); result->corrected += count; result->max_bitflips = max(result->max_bitflips, count); } static int sunxi_nfc_hw_ecc_correct(struct nand_chip *nand, u8 *data, u8 *oob, - int hw_step, u32 status, u32 pattern_found, + int hw_step, struct sunxi_nfc_ecc_snapshot *snapshot, unsigned int user_data_sz, bool *erased) { - struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); struct nand_ecc_ctrl *ecc = &nand->ecc; - u32 tmp; *erased = false; - if (status & NFC_ECC_ERR(hw_step)) + if (snapshot->status & NFC_ECC_ERR(hw_step)) return -EBADMSG; - if (pattern_found & BIT(hw_step)) { + if (snapshot->pattern_found & BIT(hw_step)) { u8 pattern; - if (unlikely(!(readl(nfc->regs + NFC_REG_PAT_ID(nfc)) & BIT(hw_step)))) { + if (unlikely(!(snapshot->pattern_id & BIT(hw_step)))) { pattern = 0x0; } else { pattern = 0xff; @@ -1204,9 +1245,7 @@ static int sunxi_nfc_hw_ecc_correct(struct nand_chip *nand, u8 *data, u8 *oob, return 0; } - tmp = readl(nfc->regs + NFC_REG_ECC_ERR_CNT(nfc, hw_step)); - - return NFC_ECC_ERR_CNT(hw_step, tmp); + return sunxi_nfc_hw_ecc_read_count(nand, snapshot, hw_step); } static int sunxi_nfc_hw_ecc_read_chunk(struct nand_chip *nand, @@ -1221,7 +1260,7 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct nand_chip *nand, struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); unsigned int user_data_sz = sunxi_nfc_user_data_sz(sunxi_nand, logical_step); struct nand_ecc_ctrl *ecc = &nand->ecc; - u32 pattern_found; + struct sunxi_nfc_ecc_snapshot snapshot; bool bbm = !logical_step; bool erased; int ret, bitflips; @@ -1261,13 +1300,11 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct nand_chip *nand, *cur_off = oob_off + ecc->bytes + user_data_sz; - pattern_found = readl(nfc->regs + nfc->caps->reg_pat_found); - pattern_found = field_get(NFC_ECC_PAT_FOUND_MSK(nfc), pattern_found); + sunxi_nfc_hw_ecc_read_status(nand, &snapshot); if (sunxi_nand->randomized_oob) { sunxi_nfc_hw_ecc_record_status(nand, result, logical_step, hw_step, - readl(nfc->regs + NFC_REG_ECC_ST), - pattern_found); + &snapshot); memcpy_fromio(data, nfc->regs + NFC_RAM0_BASE, ecc->size); sunxi_nfc_hw_ecc_get_prot_oob_bytes(nand, oob, hw_step, bbm, page, user_data_sz); @@ -1275,8 +1312,7 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct nand_chip *nand, } bitflips = sunxi_nfc_hw_ecc_correct(nand, data, oob_required ? oob : NULL, - hw_step, readl(nfc->regs + NFC_REG_ECC_ST), - pattern_found, user_data_sz, &erased); + hw_step, &snapshot, user_data_sz, &erased); if (erased) return 1; @@ -1541,11 +1577,12 @@ static int sunxi_nfc_hw_ecc_read_batch_dma(struct nand_chip *nand, u8 *buf, struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); struct mtd_info *mtd = nand_to_mtd(nand); struct nand_ecc_ctrl *ecc = &nand->ecc; + struct sunxi_nfc_ecc_snapshot snapshot; unsigned int reg_index = 0, user_data_sz; unsigned int max_bitflips = 0; int ret, i; struct scatterlist sg; - u32 status, pattern_found, wait; + u32 wait; if (first_step) { ret = sunxi_nfc_read_column(nand, page, first_step * ecc->size, @@ -1598,9 +1635,7 @@ static int sunxi_nfc_hw_ecc_read_batch_dma(struct nand_chip *nand, u8 *buf, if (ret) return ret; - status = readl(nfc->regs + NFC_REG_ECC_ST); - pattern_found = readl(nfc->regs + nfc->caps->reg_pat_found); - pattern_found = field_get(NFC_ECC_PAT_FOUND_MSK(nfc), pattern_found); + sunxi_nfc_hw_ecc_read_status(nand, &snapshot); for (i = 0; i < nchunks; i++, reg_index += user_data_sz / 4) { int logical_step = first_step + i; @@ -1614,8 +1649,8 @@ static int sunxi_nfc_hw_ecc_read_batch_dma(struct nand_chip *nand, u8 *buf, user_data_sz = sunxi_nfc_user_data_sz(sunxi_nand, logical_step); if (sunxi_nand->randomized_oob) { - sunxi_nfc_hw_ecc_record_status(nand, result, logical_step, i, status, - pattern_found); + sunxi_nfc_hw_ecc_record_status(nand, result, logical_step, i, + &snapshot); sunxi_nfc_hw_ecc_get_prot_oob_bytes(nand, oob, reg_index, !logical_step, page, user_data_sz); continue; @@ -1623,7 +1658,7 @@ static int sunxi_nfc_hw_ecc_read_batch_dma(struct nand_chip *nand, u8 *buf, bitflips = sunxi_nfc_hw_ecc_correct(nand, randomized ? data : NULL, oob_required ? oob : NULL, - i, status, pattern_found, + i, &snapshot, user_data_sz, &erased); /* ECC errors are handled in the second loop. */ @@ -1650,7 +1685,7 @@ static int sunxi_nfc_hw_ecc_read_batch_dma(struct nand_chip *nand, u8 *buf, if (sunxi_nand->randomized_oob) return 0; - if (status & NFC_ECC_ERR_MSK(nfc)) { + if (snapshot.status & NFC_ECC_ERR_MSK(nfc)) { for (i = 0; i < nchunks; i++) { int logical_step = first_step + i; int data_off = logical_step * ecc->size; @@ -1658,7 +1693,7 @@ static int sunxi_nfc_hw_ecc_read_batch_dma(struct nand_chip *nand, u8 *buf, u8 *data = buf + data_off; u8 *oob = nand->oob_poi + oob_off; - if (!(status & NFC_ECC_ERR(i))) + if (!(snapshot.status & NFC_ECC_ERR(i))) continue; user_data_sz = sunxi_nfc_user_data_sz(sunxi_nand, logical_step);