From patchwork Mon Sep 14 21:09:47 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3341 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 B7CD31C4D1B for ; Mon, 14 Sep 2026 23:10:15 +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-25915-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-25915-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 EC5F560190E for ; Mon, 14 Sep 2026 21:10:06 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 195694A0906; Mon, 14 Sep 2026 21:10:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="VtGDTa5J" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-oo2-f39.google.com (mail-oo2-f39.google.com [74.125.231.167]) (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 8A04041167F for ; Mon, 14 Sep 2026 21:09:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.231.167 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789420201; cv=none; b=oPZpOycOIQMqw2e9ph2/XJsW0N2MbLgkCE3wJ7TcTiXLUoZfI+/IApZ/Vgve2xvLfu/OrdJG6Iucip5G3Y0xeNucHKSLOg/+77scvEaYeYp+a8wDiSDjLIklmj4On2CEpCjrVgQJoJHqPuM8nX5oJR5mZ674x3Owgt2O4yEmHvk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789420201; c=relaxed/simple; bh=Lpu8BYiYZNteYXFlDSxlBr4C2CnU/Gx0SiTFgcn6nP0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=aI80agxcCk6aVj+9BfyvgXPYahEmVSegH/YktD4P1GGu0kDRIJRiu5pD+GxXNzGqDO20MqqUM4AKlpLVMuvI2DO2z4YZY0YF7EtgZCG64PGbUsBw5hSziUFdDdGWSpmawbcMg4oglG7JiWCvWN3w/xC1GRkDoiPkRLtfPm7VzW4= 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=VtGDTa5J; arc=none smtp.client-ip=74.125.231.167 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-f39.google.com with SMTP id 006d021491bc7-6b4bff33ceaso1582199eaf.0 for ; Mon, 14 Sep 2026 14:09:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789420196; x=1790024996; 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=VtGDTa5J295aWfN1DnKXCxPfig+w9Fz5JsrSd+BwtkeL6WMLkzRJhQkyeCIwVY117/ q89PgW8pwsk4K/9ldm8Q64eBB5tSaEauAGwkjVUZDzBw/7sz9PZzneJ6pXHtn7qgH0cW MThUFXjefE5CJZpfGNsQexMQk6Nn4Ci4a/+yvjUo+mwEkc2E0oHUc3U1/VlYZDLBhwmq 7Z3YMBNbCS7Iy8eE7MPkWvV18sxweaIZJTONr/833HSJ82dmqx0pi1GtE4WCc6/ISnC6 sbFPp5b5K7DLOuGiNt/G0NLhdkCkLLo1C58j4Hl6sN8ggAyegE/za1v05p/+iWE5sxJF rQVA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789420196; x=1790024996; 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=RFW60dPH2uTf/2qdMFeyPWg6AFuVg+BTb2oK77IkZuMZmM+ZfUcW93xdg4OHqNXgW4 gXsiwZj2FeB+p6FRGR6QxGCxKIMGLnH/JmcNr7GupUnFdi+TW1d6eOIZqerFRpttGI9E YzCeoCW7AvL8iEDFHHjDxmBzm1jpG8bU6/ebTviOlAPPRrQJIL02Jk52fmFAydbPiLtF g7NFHIU24+jUZNPC3GdS8Ueb8R8aVdAnKfWmEc0o7xpm61bUZwqt9x3bVcgXC+SgHM/v UzsOK1KsKjCeXemHgbxZlDa3a08QaI7O93wYRBap8viKhj+LyWkwZYcgBPq92UO2XEIC Wvpg== X-Forwarded-Encrypted: i=1; AKwUvBxpk+ej1Tv+THJK6sTKa5/wVo5RVB+gZCU0klx/JFGpqo2gVFibAXDxgYpsvxjLEGhJOywpJWePyS7a4Q==@lists.linux.dev X-Gm-Message-State: AFuF++m4XBjPxF9FUQ2p3WUY9BXt57bPiDX4VHOMxPmqZd3dgDAPL8X/ lhvRDv7+MbXwMC/rQVvde/jWIy3eQGhnoY5bdQF59OzLYzd5rMDu6eAc X-Gm-Gg: AYBFou0u1uB0FRud1YQpBcQcMsEZBt0Um/nRlc66gQFW756cDuIKsmYAGsyZJxPmXag MzskXKtUxqkpFX2s3iwSUnrfzXL8nYwdRdeUsKaXtZuFomhobkTvrjvo3N3+Z7cNeIQJf2XEs96 u4Iu70wfFAooP93yy/zDXlZL5ryLRO9mixNtn1k+ChV4OyZMdfuVEepGJMh5pd3wGIcjZMgT5wO W4i7FMX1ClrbWuD7l1N+tbGncfPDBBrDqJ2l01ejeGVRgLxLMtFd+sAR0KVfzI5Our7I1u7Zg/V Z1I3XDrwzGIsx3sAni6inRvfFMbG861BNCKhxpefQi5Jtbyuuut0Os/xQq1R1plb3Qb63gIUIf9 DP7EYFpt1oB+PEDxQxxRnKJSKbU7eAq5jvIf/XgJnniWN86peKTFWInJD6iB5unO4MK7DR85jKS S7SSnVuVaZ9MGjJaojj4/9PcePXtLOVb0VKfMDwCFQkdX9Ig6xRGNu4NvrzkWzUqN8kKYf4GIaB 7xCh183eHBrqzVCKoFAYqqgpB/gphGuLjeeSBTatLpvRHwymoS/2cdQKsTzJuGXa+tKWc6MdTpl YVHDcc4qg13FBF/FI1agp/cMITYcZ9YAl81Ax7mzeBI7TyApTCv7j8eofDy6u94i17K0feO5jJo sQFVy7KEYq38k7Ch4UxreOLSH3n4E X-Received: by 2002:a05:6820:4d01:b0:6a1:4507:3544 with SMTP id 006d021491bc7-6c540d62bbfmr2624632eaf.28.1789420196428; Mon, 14 Sep 2026 14:09:56 -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 006d021491bc7-6c45bfc3fe9sm4698544eaf.15.2026.09.14.14.09.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Sep 2026 14:09:55 -0700 (PDT) From: James Hilliard Date: Mon, 14 Sep 2026 15:09:47 -0600 Subject: [PATCH v6 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: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-1-2fb084fe0751@gmail.com> References: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-0-2fb084fe0751@gmail.com> In-Reply-To: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-0-2fb084fe0751@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.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]; BAD_REP_POLICIES(0.10)[]; MIME_GOOD(-0.10)[text/plain]; HAS_LIST_UNSUB(-0.01)[]; TAGGED_RCPT(0.00)[dt]; PRECEDENCE_BULK(0.00)[]; RCPT_COUNT_TWELVE(0.00)[21]; TO_DN_SOME(0.00)[]; DBL_BLOCKED_OPENRESOLVER(0.00)[sto.lore.kernel.org:rdns,sto.lore.kernel.org:helo]; FORGED_SENDER_MAILLIST(0.00)[]; FREEMAIL_CC(0.00)[lists.infradead.org,vger.kernel.org,lists.linux.dev,gmail.com]; FREEMAIL_FROM(0.00)[gmail.com]; ARC_ALLOW(0.00)[subspace.kernel.org:s=arc-20240116:i=1]; R_SPF_ALLOW(0.00)[+ip4:172.232.135.74:c]; MIME_TRACE(0.00)[0:+]; RCVD_TLS_LAST(0.00)[]; FORGED_RECIPIENTS_MAILLIST(0.00)[]; FREEMAIL_TO(0.00)[bootlin.com,nod.at,ti.com,kernel.org,gmail.com,sholland.org,socionext.com]; FROM_HAS_DN(0.00)[]; MID_RHS_MATCH_FROM(0.00)[]; ASN(0.00)[asn:63949, ipnet:172.232.128.0/19, country:SG]; TAGGED_FROM(0.00)[bounces-25915-noreply=patchwork.local]; RCVD_COUNT_FIVE(0.00)[6]; FROM_NEQ_ENVFROM(0.00)[jameshilliard1@gmail.com,linux-sunxi@lists.linux.dev]; RCVD_VIA_SMTP_AUTH(0.00)[] X-Rspamd-Queue-Id: B7CD31C4D1B 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 21:09:48 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3342 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 F22DB1C4D1B for ; Mon, 14 Sep 2026 23:10:25 +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-25916-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-25916-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 CD91C6022F1 for ; Mon, 14 Sep 2026 21:10:11 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 1D9604749FA; Mon, 14 Sep 2026 21:10:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="pk0GyBxb" 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 DD440415F06 for ; Mon, 14 Sep 2026 21:10:00 +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=1789420203; cv=none; b=tT+P2H8tDdHIlzRlQ5QzOWP/CEUuBtOdGfZYwUWjL+r+7VdS8H0U/rZK7gP/JHBGplWfKshR/SodHYpM66cZmuUtOnyDMn7PVJjvzfNjIPDkq/dz/lOcnRaNbYokeXONfawMQyj6gK+6HCcQAbenbwBsuJZSZWr5tznxLhxJ6Pw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789420203; c=relaxed/simple; bh=QNBt+pFeHHzCr6qyz6aRzEV+o3fccMFb5SqOxfos0lA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=jERwC2Ne6bZ/quhMsd6QQeIixdvKFex2qs+LnPY+l1Esu75w+ghULcQKz5TQoZ0nRIUa53VFqWcwHLZT9S3urSHDP5PRWyL/LUXUwzJPeOjpNIYy6akUyVjTgwysHRT96HYoz9eyqj7zlW1bbLDw/fKjBumHZJjzR21DfkWwjQA= 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=pk0GyBxb; 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-478cbd5b48aso2313769fac.2 for ; Mon, 14 Sep 2026 14:09:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789420198; x=1790024998; 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=pk0GyBxbXAv1R9iHpJleiXblfLP5ft90lydI3AfWEHNFtSFnzQc0u9B+8xVYBjTa+p ZdMZ+iNysCm7PrrIBBVfsLvVN1zrfG6uja8osgMgOaD//YspQdXLZoBOeuoOeCAFzqw/ orJKMcBPOqRZyqUq3AKjR899aVxbn10Y2u5XfPqn0FIuemZeeG9dcIZhDQ0QsrTVKD4F Fy5kHhnTT8dSIVU5z1acSwxKEO9ix3PYv6kSUEIE8Xv4vsR8aTsRduaqwwkGpwRcPxj4 ifb3RnQDowK9rv5rAV6baDwYYUl/IdxOy19Uhq3vcRZeRw8rK1ttCJcfqTbeV7+63KEh 0txg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789420198; x=1790024998; 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=snS7zflFAkM6RDjbk5l6SxhjhgoxgG59zVLyRF0JoCOB6+7t4q4iV9wiRGHbqtL7tR zmN+Onyh4DI+B8vxgaLbOI+nroZR5KJPMIT6bQ97FpNpX1GNQK5mY7p0GG8BAJduHtTz 0DVDlVfBAJCKqXH4w3Xnm6z+KOX+weoM0V0R3yIwyPCEbdKp1IIGF+Wi1BhURHCFqOkU VZAcZXCsSxQS9VLiuAaF+/HxM7XQK2TByLJvtkJEnuCDH4+8ybdjX/PVajMRxOOXb6r1 SXN4nDrHP3692tbBfor/5iLaNNPOGMAIzkHZ5Zm35QKzlyApWQt8EYMG7/CQw0uwVu18 TQkA== X-Forwarded-Encrypted: i=1; AKwUvBziDieKYHjUDWCc/Luo6OWhneWYE+quFH/FrBrycL2jLuImq7V4BAako+nDEeReZ562SvCS9IZE9ASP8Q==@lists.linux.dev X-Gm-Message-State: AFuF++m15K0P+ImyLSmRiTui/2M5TxT3cpUcbCmnWWtxJnW40vhXr3E+ AS+n7rO4zLOP7pcz0z6M9Ty6rdJd//NKaeA4ZLh4OFXvxnwAdN9s9l3c X-Gm-Gg: AYBFou0OTsyRsedbFdnn7fS8ma22TnYF1LeXl8D68CxmvsQaPZHvNGwIcXCkR2KDA7I bKyt3OfyEj/l68SbQzNn6V3hQgVTWgKbHSqQSk7U2Ff2XVc2nzjp9dpMpv0fBtaliqtwFT5YTj/ 6CjJnm0fTBOS+56OuCDOGzX4Hu6m4IpxCp1VZypo/ZDwBOP/7tdDN13ynICCNPGFZNpp6cbU7oA 05qP4TR0GsBiO0N8RUsGKwGMp3z4AuCOR9nLaXmX0vPfGv9IEvkWL3nalw+W747vQ8SAyyPcZiY VtVB2ZC8ZWdxTmA7tv3P4FEjlD8OFkw5t9dxlUDWxsgo0zrpcQY4fQvXsQxbrU5ASD68v5K0o6Y Sjxt6+RlC5TMJN1wIL14GOiE0eY1jyfnfaMDE8mo4x37rEX9FBr64PQ2PmkZOz6jKAlWJf9BtB/ f5cCaZnab1C+TKEUuGhj0hKjuNOUtFfbrYNnbbbYBZzEk5e7VDgGixyraGpTvfKHxR4vSHcIXFa QztPtlNPRawUmkbdo5tiSZNS9P1IqYNrf7gUrHMZKvzUPWqnHvAxtgYaD4RPHePMbtqvjnziTgE XkluCz63+WdbqQihrG1GNXaBOaHwpLfAsMnKUjlj0LS5gwB7GzKmzZPWzMyw7PMCmyUoXduzBK4 vJ3o9iCfloeN/0Hk1vE10KO9cO9v+ X-Received: by 2002:a05:6820:98e:b0:6c1:c628:b0bf with SMTP id 006d021491bc7-6c53f44bc19mr2434309eaf.13.1789420197732; Mon, 14 Sep 2026 14:09: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 006d021491bc7-6c45bfc3fe9sm4698544eaf.15.2026.09.14.14.09.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Sep 2026 14:09:57 -0700 (PDT) From: James Hilliard Date: Mon, 14 Sep 2026 15:09:48 -0600 Subject: [PATCH v6 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: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-2-2fb084fe0751@gmail.com> References: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-0-2fb084fe0751@gmail.com> In-Reply-To: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-0-2fb084fe0751@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.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]; BAD_REP_POLICIES(0.10)[]; MIME_GOOD(-0.10)[text/plain]; HAS_LIST_UNSUB(-0.01)[]; TAGGED_RCPT(0.00)[dt]; PRECEDENCE_BULK(0.00)[]; RCPT_COUNT_TWELVE(0.00)[21]; TO_DN_SOME(0.00)[]; DBL_BLOCKED_OPENRESOLVER(0.00)[sto.lore.kernel.org:rdns,sto.lore.kernel.org:helo]; FORGED_SENDER_MAILLIST(0.00)[]; FREEMAIL_CC(0.00)[lists.infradead.org,vger.kernel.org,lists.linux.dev,gmail.com]; FREEMAIL_FROM(0.00)[gmail.com]; ARC_ALLOW(0.00)[subspace.kernel.org:s=arc-20240116:i=1]; R_SPF_ALLOW(0.00)[+ip4:172.232.135.74:c]; MIME_TRACE(0.00)[0:+]; RCVD_TLS_LAST(0.00)[]; FORGED_RECIPIENTS_MAILLIST(0.00)[]; FREEMAIL_TO(0.00)[bootlin.com,nod.at,ti.com,kernel.org,gmail.com,sholland.org,socionext.com]; FROM_HAS_DN(0.00)[]; MID_RHS_MATCH_FROM(0.00)[]; ASN(0.00)[asn:63949, ipnet:172.232.128.0/19, country:SG]; TAGGED_FROM(0.00)[bounces-25916-noreply=patchwork.local]; RCVD_COUNT_FIVE(0.00)[6]; FROM_NEQ_ENVFROM(0.00)[jameshilliard1@gmail.com,linux-sunxi@lists.linux.dev]; RCVD_VIA_SMTP_AUTH(0.00)[] X-Rspamd-Queue-Id: F22DB1C4D1B 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 21:09:49 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3344 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 8A7441C4D1B for ; Mon, 14 Sep 2026 23:10:42 +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-25917-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-25917-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 7A0B9609E99 for ; Mon, 14 Sep 2026 21:10:17 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 731D048F848; Mon, 14 Sep 2026 21:10:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="QckbJEjQ" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-oo1-f53.google.com (mail-oo1-f53.google.com [209.85.161.53]) (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 53DAC4A0137 for ; Mon, 14 Sep 2026 21:10:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.161.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789420205; cv=none; b=nnNXNPAstDP1xrqNSM+9cisuilu6RYBR0CpAFwE8LAcgrPcNTSjZKdDvJg9NZjmTfwsFyj8hPpG8JqCJhymu+jEe1SoRnZ0AV21fJ6Y+Zg+QpQGZ+CcrbCtiifKWmCwdbjcgmbo9kmUgicqJ/T9ghvJFvtMO0jRepjDdevFuZJ8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789420205; c=relaxed/simple; bh=sEgsacOGRde9P8OKLBN0PM1Bqnp+ZYDx65EvzcaNGcA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=gQYtYY72dDdUSPc3VoCv52yhjieqZn0BoIuPhRJqjzaeFubRQsylkB+RbQ9jmUIMinK+fjHEN1bmhSSVxwa08Qo0SbW1ZzHG62cb6IzViyIRdu6P4tTG92IqSkddt22ZIQOeADeTHUxsin52lXs5XcCuxIOZp9Ax8A8FjReNV7c= 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=QckbJEjQ; arc=none smtp.client-ip=209.85.161.53 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-oo1-f53.google.com with SMTP id 006d021491bc7-6c20a9c464fso2483939eaf.0 for ; Mon, 14 Sep 2026 14:10:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789420200; x=1790025000; 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=QckbJEjQPLSIw4LXq//KSix+jA85i8rPD+8q08AaX5yDt54zmYL9kOXiehResVBaxo 9K5m+W1hAzeEOHWoRfWq0DQn20bjSQ/5hjnT3I/DphV6HEZ8mvezRlGVDX5QmMn0fO18 kL5NOmOJ+3yfMXvq7HHCgpWMDGM8WH4eaH15R0SeeQS/y89dGvu3iPz9VSK4NFxX/pTf oRYMfSU94iokfbPfTE2R65v9CEMaoEvd728Al3UdmxfgjiyjP0elzQufjQLasiZ4YCQn LJjP6ljs3SB/A2D4fjMU9PEKkdbrpauLms4J5Oc2Tp5Rem2mDVlOZVHnu2eSIaEaAN9u wx0Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789420200; x=1790025000; 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=zUx4EhHkChHSTTS2JmcNIE3xA4PXBvVKkdScIRCxuW2GxkPveMWXYMkznouyaA61Ky eArp11lUPSw3OuaVl5xTXVH0XoByF/wi63FYCMmZHez2oreCm9B48ujjLDM/c+aa76H8 FEEpTvRTGtt18obzk7Cm8ALgkRvhJVYCxPNRd3767e5ZOlfj8Q84BcLL8H6xxkoGRT7I xsIV4rloaaEnDmqNk6VV7P7JVZ1hAtxqxb72Be0mZqddo3E71WwYqiDOt0BTrBKulyD1 QEeVikrrMsGjI3BvzDbsY69V556UI7dNS52cQnv6LndL7IS/CexSnGAJKMzfa8zHfsF7 Z6VA== X-Forwarded-Encrypted: i=1; AKwUvBzy0amU0VkCDPIRBfpC/g/1aLYiVTejk+MU+FcGVx4Z+lz0Cw0qjiuxwCUhqYfTyFKWnYIwbfbm5Nk8VA==@lists.linux.dev X-Gm-Message-State: AFuF++mrelMLLJYyulE9JI9W47+frGr81gB/MpVo/Alk0jEKA11BBL3o BS1Pi9TVjnc54Wgvf8rxuBOfMoUm5E9+73BTo81Wc2H34jfqppn83EBs X-Gm-Gg: AYBFou2lhEJ4bhGWQN+zQxCUBt4I2NbSVqE9p23Afhg0sSEu6K+RyuqkmVIjNH/OFlv 5OyIYDUiNuRZ4/EDuakyq83SncZpodN4R3CktutR/+H7slwvqaY0wRRQJ8VyZo7z9nhoaZMkxob kOUYbZO1kpDKeBypWrfupta0Lk2yNBpjCVi2g42ifRB5EMz2Wk+9uVvhetsuPGQ2sfcM7p0xL4s i2pPoHz1cH3IjxbiFrweOUx24JpRtNWvJMiIRHaq7NkKoeFHPvJ5qRC2cfTr6W5Ty/qaojk4Bi5 aLKCQhmzosWtJ6OCJhL3F8FUzu/qGo/qu/lklfXjW76x4h10Y+FoCyJttysZaVRH9qlbFZmS+Ra uO5u15UKLSM46AXetLPBQUG7YwBHjIYWSvbebytx9bt54voOgbZeqtixDC+dKItw8y0O7el0FEz ojQtBhip1GXpOo1YvnZv+1pT/WxSXeA5jI7xt3ppNV3/cAK+YmE1NPRp4NBSEZjNSfBnmig77Gk JJgNbw9J+QEm/X0ZxhjoGsjNUglOmli27Yw7C6qfKeLYlHglKoWjszZ/uX0za8Ow4/cGvqB0uY0 20JzL63OJiQm3sleOLxbhJ3m7VWAkoFZY/RmNwzJku/CrTaJ1G81K6tTKXSHVtVlbTPJYwn8R80 pjEhaEc4yxX7DtBPLBM1Ap1u6ZvqI X-Received: by 2002:a05:6820:810:b0:6be:6f42:3a86 with SMTP id 006d021491bc7-6c544ca9f68mr2776984eaf.47.1789420199333; Mon, 14 Sep 2026 14:09: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 006d021491bc7-6c45bfc3fe9sm4698544eaf.15.2026.09.14.14.09.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Sep 2026 14:09:58 -0700 (PDT) From: James Hilliard Date: Mon, 14 Sep 2026 15:09:49 -0600 Subject: [PATCH v6 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: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-3-2fb084fe0751@gmail.com> References: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-0-2fb084fe0751@gmail.com> In-Reply-To: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-0-2fb084fe0751@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.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)[]; RCPT_COUNT_TWELVE(0.00)[21]; 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]; 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-25917-noreply=patchwork.local]; 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)[]; ASN(0.00)[asn:63949, ipnet:172.232.128.0/19, 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: 8A7441C4D1B 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 21:09:50 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3343 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 31AA31C4D1B for ; Mon, 14 Sep 2026 23:10:35 +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-25918-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-25918-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 3E2FA2952B for ; Mon, 14 Sep 2026 21:10:21 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id EE2214A0906; Mon, 14 Sep 2026 21:10:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="iU9/iQ2H" 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 3D4D44A090E for ; Mon, 14 Sep 2026 21:10:03 +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=1789420207; cv=none; b=k77osW6j37FjWkbrdb71/rpDIFihweI1QCAC9wUiahGcxAf3HM/65ddXs4czODcbVNhVdqYsgRWltkIvaQrROoyypK2pqWR02zwCUpyFpWAD5qxvCVm+6wMkbg/O16V1LB5JlyNoeH0pDI5EgRW/znHCaEqaDK0wTKac8LQ42dQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789420207; c=relaxed/simple; bh=NlWMHvWo8eC8a5062ul0UGSwTs8Firq1Hsg3xcZzp2E=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=gjbwSwLH7NK4bnGyXG5mzmpGvnCTXtJLqGU9PccKg4ofoUENtKUWIdElpzaO3k5fWMs5aX92T/gN6n5bqnl7QplRlnXPqjvcOEeoZFH5pDYRdVnAOYarNLY7bTgIv+ukOPVmBkF1cuYgzTisCCPUKNP+IKy5iRgm5YHYvYUmaAA= 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=iU9/iQ2H; 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-46ac6e5d8f7so1446897fac.1 for ; Mon, 14 Sep 2026 14:10:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789420200; x=1790025000; 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=iU9/iQ2H2ja8lPortm1P6zraF5UYMxb6866tZoMtbh3rMRk2f3IvrxK2Vx1KlLkOJj 3FasraN9Jar6YnCNLnpgclxBJE67Z7V1LYi6yy+L/TGYQYoGwbQYwp7eRM92Mdzudx8f Y6yFb9ZvqLpR8/Mk6+ElYOdmZPwDkVxSPX+whuqECHmtkugxAiB0/5DQnIr8yn9j1AL/ VE8qF6tww00qlHVoAB1d2G9neLTkqBXXkMI0jzBkSnl/hzS9lazAYtXs4rDomw4YBeWv PB4iMN5mzxWX0l4A7ySiE0FG9TO4YjLUtWXNs9/6g7UdWPb4dt/fVEgtZuNAzeX6Jx56 fDpQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789420200; x=1790025000; 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=SvqTERmFWmEsSNKO1GemT5TeqfQA8+OI8TNJVr1B+ZEt6liVFq28vDPbo/+gUuvSAl uQgqhVIHEWbs5zNH//DZU9P8muc8gdOUJGwGrPrU3GfIF7m2BKnjxcSKwx7Bxqbj0EwM CFRSICShfvgnU/QxPvxa5Opl7guYApsx10rdLmg1BriZL+lHyifbNPf69QYIzB3wYVnN 3d+ENdPqS90qN4DOvqnUPVleAT4mw3C8VQ3xmfDxOF1wWD3JYthQdqO3/5+ZYmrVjU8s yK68NPv/BKBg+Onsl+Y2w8yHhBgfIQ75c9ffupe3sGo6hH7tMTTR2nyxEY3rSMB3dvE4 atVg== X-Forwarded-Encrypted: i=1; AKwUvByX+4cZKVEIsJs5YmXPqe/AoPw97r4wV7HoAbPxi30JWkzV5TI/YKu9U5pjvQm+8/RgOQOaSc6wSLMmpg==@lists.linux.dev X-Gm-Message-State: AFuF++nq/apwKhGTWOGd+djMueTx1SdMFEJBGf8djdWS+Zes5aeJ5MYD ATMwIupBjk8Pc36Hw+ZoyUZ1fGRgo1GVz+o+km4iKUwcQOS+Iuk1DbDk X-Gm-Gg: AYBFou0xtz+UicPlOhAgqXhLcU3+LGW2gdXzkymg6gIw2JYWkGNKXJ9Cux2iJwXLWnG vzXeh39ysE5Se10AcUseoLQAVKJCYJ1AbXwM7mYmE6I6sUCvIxl1R4tiYV2u+J3RMi7TOrTNDNP JdNWafxuQCwTyvhutHBzftwmdXKrttw5PIktN3RsBCFiXzeHrvB+dcj2sB/ZalGkNjtMA1fndMZ VVhYjzJBjBn8DzFAsdVZNYJeFddFUJh3inpBQ0Sn3wFwx0b6Dwz4U5gSM16n9eP0yHgderWIe9Z eSNc0wq60/nMZbvhi/eMbaAtSiukWmhEK8omXs3ZYpBZZ669C0MqIEzmh+Gp1FiTYNe8fQCZX69 f/yKHOhpIBWVTLKGBJfTxomHHnlF/DhbAtfcuqkVN5ib35dLZQuBHBMWYeB1E6BEhaMd4z9zjXI f+4MDQFGWs4z2fd4eWtZeuyDvVzP66Wguh29tJgFhomOpXf+YEiF4L9dMyXS62YevrqY4UcZycc Pico3UH5r4AufoWMDnIV4CItenuaL0o6nB5cO2ctlEL7/mkODYJ2sIIyW1bYlFm3p5/8ZtByH6K L1COY9JtC81X//RwzzHukI+MuJrZ4jCKzX4YrLgx4zfCi08jqBYOeHDPzxXkz3F0faIxM9l4Z7r kliN3hc2qzEvAz9XibYnkQNaz+J88 X-Received: by 2002:a05:6820:217:b0:6aa:ed21:6c95 with SMTP id 006d021491bc7-6c53c6f60abmr2434425eaf.0.1789420200643; Mon, 14 Sep 2026 14:10: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 006d021491bc7-6c45bfc3fe9sm4698544eaf.15.2026.09.14.14.09.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Sep 2026 14:10:00 -0700 (PDT) From: James Hilliard Date: Mon, 14 Sep 2026 15:09:50 -0600 Subject: [PATCH v6 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: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-4-2fb084fe0751@gmail.com> References: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-0-2fb084fe0751@gmail.com> In-Reply-To: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-0-2fb084fe0751@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 21:09:51 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3345 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 C7EAC1C4D1B for ; Mon, 14 Sep 2026 23:11: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-25919-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-25919-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 EE97133B1D for ; Mon, 14 Sep 2026 21:10:37 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id A138B4A1DF0; Mon, 14 Sep 2026 21:10:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="lyQSyIU8" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-oo2-f34.google.com (mail-oo2-f34.google.com [74.125.231.162]) (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 DAA7949F12C for ; Mon, 14 Sep 2026 21:10:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.231.162 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789420210; cv=none; b=fNaIXdcgNBrxZ2MXTWEN775rvQc+MiqjL7BTfgPCDC/fEu5g9mwkGOd4dLsyPQjt6b4Zkwu839CwXglHPpYcorwJdYqNtF0du8wd7nzJFf6nmHS0AmOJRVs2/xJswY5gr+L1d6FbiFj6Mdgro9mb55Ukt+6I2ox1KmTq8IqT4Js= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789420210; 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=OybrcDIulDWskGsFN5p1ICfT+tHUky29nE8J66Owmc7eAkXo2Pl/rahBZvzcfJJE3xoUTffMxyW2YGd96/cm1v/IS+koQCN0Q994x0FoHd0so/x3BOrHcXmrSo3CRiQCFnTRclafBojTuPRst4bDeJJ6XOtgI0Hf63+bIu2RaqU= 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=lyQSyIU8; arc=none smtp.client-ip=74.125.231.162 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-f34.google.com with SMTP id 46e09a7af769-80032c08611so2329991a34.3 for ; Mon, 14 Sep 2026 14:10:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789420202; x=1790025002; 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=lyQSyIU8YpyL6Az1uiDKbl6gE09EJqZC5e550nqPzSLk3i0z5OYM30A4+tL6B/M+fh ox1YcvM23Ar49pwxP9RQZ1n+u3I5GoxqKyGsi9PmK5sACUGP/HKJWPkHUar0c/zzy+zO +DcGqN/CRpq/vbeOK+8MgHUZcoiH2CTk7eHDN5rxDZZUoaMB8MXwsd13evS+hoxoGsh6 bZ7cm+SNkrSLL+ENi04qsrc5c+q8DsaahT/a29V8Vxx1+WC08XVebzTuljCJQbDwlO3y x+ZW5nwS+eJ0I7pZP/Lysya8q1pUQGBX9TjQwfjokZcH6sunkwyM1drKjOS56d1IrVfB mGcg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789420202; x=1790025002; 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=Mr9z/OtPqIKUlxPg16Yxh+djo2B7CjJXbYWpzJWJUpPBFcT4VvownmewmeFV+1UMgF Y0Jtq+FO/s9Hx7heCSnSHTZ97yZEjEesYpjkqPOUJc0JUxwo/idVV5u9uf7bKGIk18O6 Wyre1byMlShz/qUiLKEYo8GcBu8UsnN1gQNNtq5cbH6oBJ1mmKWJYAiw4wx80xpbE2oF 3mzqFTRUfd1l1saWrzdACYPfHszm6mCLss+m2RPG5oC+kO34wWQMtBAOyAVjOIjyJNb6 qrz7HZlCWX3jJs9GyoauMa7h5Zc5vEdyKxf/OTuWq4xi2tr5tiJ5eKTkVZefwXnfuJ2K RlRQ== X-Forwarded-Encrypted: i=1; AKwUvByEpm6NGjzraP6lH5/0Q2IMaFZxUdRqhZHIiKC8+XxNcTknyiXYa+Y2fJVTIXogiEMJ8oD1gE1PvhICfQ==@lists.linux.dev X-Gm-Message-State: AFuF++nV6gE2GkL4Cgv+hvNt91zC0EsdawfBGPK2np+dx7xk8LmYBfgU DCbQkVws9fnd1PCwTn69tID9mGoeVNceY5NqeFhcu4xxAtVNVHKqwbi3 X-Gm-Gg: AYBFou2IucO+Rj4G+o3aEEOyxATQRikka3kjk4gAViXlpjQoLcXSdMMJj4t08rezE4h qdHuVCbXfx06vSsJNncH8j/fTbvYCH0mI1rMHSCNKDfkxqFexAPEZVYoPhQQ+cKOMavLA7IOk/q cyGC9+mbuO/ppidK6LPTxIQ5KyCJUT57nnrdwABivkz7rF/st2KXgJYq0bXru+g3pIDmrFkGD/T HN59F0XII4Fc/DT7lgvuJiznSuYyLkDmrxnN/nGXc2HloVa2L7bHwZxOUlJazV4yYl3oEdh29wE jgHcBtwiR4ygSqIQEFReIj8RuhSi04Nxfp87jl4BYDU8f2ALTWoDOVIvoU4F31HnL9UNMJNntNA 8JjFrXR6xZhfPi3xyHH8vmpiwIKMk68EPrBfPGkjS9BU8CVs4xqMvn+PzEuiRgV6v0frJI09Uhz IyCF3e1KSMKZgydGUHB47mXYV7SC0tX8o9M722GPhril72GuzDzMOvsLB0keGC+N2GTkjkF5fC7 Z9FzuzhZlEdKQhzwA99oBxLwZqpFxjVAYHlVfkB74HPgw2glfWfl2oqVy5yP9npf3myd+L14HQY E3glUj7Kv+XtxeXcjsAoPrdiYzYuoO8m3H0RI3PWW4rzZro2W6hW8ZBdfYyj26l3Dhfs3QvTutN Px/WRAsqqP0aWYjp/dvk0Gq8/d43Y4A== X-Received: by 2002:a05:6820:80c7:b0:6b1:b33a:db69 with SMTP id 006d021491bc7-6c53fb6bf40mr4489299eaf.15.1789420202250; Mon, 14 Sep 2026 14:10: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 006d021491bc7-6c45bfc3fe9sm4698544eaf.15.2026.09.14.14.10.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Sep 2026 14:10:01 -0700 (PDT) From: James Hilliard Date: Mon, 14 Sep 2026 15:09:51 -0600 Subject: [PATCH v6 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: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-5-2fb084fe0751@gmail.com> References: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-0-2fb084fe0751@gmail.com> In-Reply-To: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-0-2fb084fe0751@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 21:09:52 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3346 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 077931C4D1B for ; Mon, 14 Sep 2026 23:11:34 +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-25920-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-25920-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 AB0CC60B101 for ; Mon, 14 Sep 2026 21:10:42 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id C22A14A1DF6; Mon, 14 Sep 2026 21:10:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="GC5FC4Xk" 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 954B8470EBC for ; Mon, 14 Sep 2026 21:10:06 +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=1789420210; cv=none; b=gPcVC5o5mPKMIoCweGBBHmuwRN0FPi4t4Y/FBklg11UBb4rLxoKRIqjqQerjIOn9ntkELNrO9rC6hxehMBluDNqkNoavTOt4/ufj0OKohqFGiKoSB4dvPLQKYgKLDTjQ9wz/0F8EjFDbfcE9JsPbHZErbMT+hwbWQRrXaleiah0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789420210; c=relaxed/simple; bh=QuwwqJoNNeFbRXCees1KSU/os0gxTVKzY6QPcLIi7JU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=kf1ZA+h1gB0UQx8BF1QnFlLjMQM/9lDpiuhmlwfHzhoqfZNMNrhHh6eYAKKYhPt8r93yFxyoB6zQCRjYM+aFCAZtgDuXsT1Ui5OZ3TX1RlD9twfYbE2V+hittTa6ogJaDihIYnLSkBH7HbGcJV8Sbb+YgfRsofEw8pIPhPvcmbw= 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=GC5FC4Xk; 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-6b1ae6f1635so898645eaf.0 for ; Mon, 14 Sep 2026 14:10:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789420203; x=1790025003; 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=GC5FC4XkUt+6viXgoPZekQ0yDMUoLb4aAH1+wrytrqCtQZQMQlzShSvASbWk3nL5qG oFqHrBP0caaffQqrdr1yzf/TZ8HcmvfrgGx9f8v2vF/aibz5AkriJDXrDNegnNy1MJ0I YCj70OwoOVYf9n6zlCDrZF7fh3w69vUvbC88DlkbK4HWDr+6nHnUVPdThrvqEAbFFxv2 E4wG6L3DrCF6vMIBWlupV7/dOr0sP3NvZhPV35JF73boBUlxxpPwyqaOs24nckFXc3+Y C7IADEGCwL69p0YOesvcTTluV9scWGPKDs5Y0cmR1VU3CSCtensCpt0HcemzIRxWIXfL bGpQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789420203; x=1790025003; 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=UCcksyFgdgtVm97LW4+7hzoxDtZn9UF33oZlUyzFRrt0X8DnK88ZEM//aQD5dgMFUj 3NqKO24v7kTQQ4CxUb3WT+P2mQwzfRw/NO2YVDzVzMfVtxuqQ6e7IkJz7rUX4lPetHNK e55BEeR40r6kwzz/GkQ975mk6A3SpZrDMxfFEPPLDDBNpUxYuuBBURlcowTZp1bdegJd MS3R8Zl9DFpHcY3gJniXuuI/UjrTJ0xEqMM9rE175O2SdWJK/5muzZwrnx+h7vlPt1Ks N6QCakcCSDar02oBJvIpa9q4sEVeC9SVOfVTccqyvZOXduoUIhHhvGw5wnN7JRvXQy/g Zo4Q== X-Forwarded-Encrypted: i=1; AKwUvBw0QbIbvG3c2OhfAyoV3EgDN+kwMq/zIpYcLnjG7DmfrCITT1Tpmgk0OoA5GxC3+hAuN+2FgzFuuvn2Jw==@lists.linux.dev X-Gm-Message-State: AFuF++l6ZyMtplesrTdPFUMfLUl7+0iV4A7KSMO7E3KeEP61dT7fBrvY mAijKTU8ixL103TQ1FMruQCioT1gmONIka7nJLMFBiwqmVVG6i1tg5I6 X-Gm-Gg: AYBFou1hnXQsnOsvAyE7z7j/r+eI7NhOA2tYKKCp6D1M1NeI0201xrhvqQUvw5l2g6D udZgLvbDdnulIZ+9QVFJS1HW533QYoudpao/nABXtLy1UsivRum23dXiXLepQpu4Rx7jRwIW8vX IGe+89aGiRDS6/kaGXnSDkqdIcmyhaLs/mVgii9IU8q+uQNq2Tlj8lCljCzHNv9MeVQMCEdYctn BeHOm5vwiEgv7v2KIHZd+ive0vRdhNChoQw5vnL/OuEBx+Lns+ipbi7BJ5yidKR5zHOzbOHABi1 BLQn250X9eObw0WGLDX3r6j0e4m2S+Ce7xrCNtnT8RlNdZp2XigBBSPY+edtvJVva2G12m2HId+ vbZOB/LeLFDrIa4/wCjqbEBm+pqtP9J/ZPF5jMxnssV6tW9xasCL+HciJRm1k0nzDiA501HexFa bSWL3kvVLcNVTMNrEyHopFJqIELYnWw/thDvGNrn3KEHpJC8U2sdNjf9kfg+wn7fvCc6oBwLphS zgkCDIAcbMp5nB5Z08CsZ5AzLn1uzfW2a+8XnXki0QKnPAKeWRRl66TxS4TC0Ow90aWrsgpPMKB AXH1Nca2iW+dxorgK4tyxjp8aYbPHxb6PlG6fFcSUA1bg6VZnNPSt7UIht9vzhq7ubRS5d1vS6B jUiTokExMGPFUN9c7EUoli7Ofkswx X-Received: by 2002:a05:6820:4cc1:b0:6bd:cb3f:5896 with SMTP id 006d021491bc7-6c53f558284mr2536286eaf.30.1789420203605; Mon, 14 Sep 2026 14:10: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 006d021491bc7-6c45bfc3fe9sm4698544eaf.15.2026.09.14.14.10.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Sep 2026 14:10:03 -0700 (PDT) From: James Hilliard Date: Mon, 14 Sep 2026 15:09:52 -0600 Subject: [PATCH v6 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: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-6-2fb084fe0751@gmail.com> References: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-0-2fb084fe0751@gmail.com> In-Reply-To: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-0-2fb084fe0751@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.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)[21]; 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-25920-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: 077931C4D1B 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 21:09:53 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3347 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 4405F1C4D1B for ; Mon, 14 Sep 2026 23:11:56 +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-25921-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-25921-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 5B98260B61C for ; Mon, 14 Sep 2026 21:10:48 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 42D914A2071; Mon, 14 Sep 2026 21:10:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="d5WA6VqL" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-oo2-f18.google.com (mail-oo2-f18.google.com [74.125.231.146]) (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 F31824A0F00 for ; Mon, 14 Sep 2026 21:10:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.231.146 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789420211; cv=none; b=s8KZoXhsVQ5VlM8g/ul7cHId+sQcOsh2/BuKOCHvFQ901znkHL2jScIS+WekIwaruZCP1BYBmfThclyeg/OmYt9iO6VZayM7qYy3IEvcwJRsQUFisRWuTnYGCexCTLw6BsTk49N8coZMfwdanV+G6VWnseAtnx8cs38HDoI52Gg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789420211; c=relaxed/simple; bh=ovOsliEdUhvhRoeaXGSGPM3LycBRMZNPRXeHkTBG1HM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=bMUyo9MQvpOM5RIggUdhK1pQ5pVWIXCbJeO61AOhPtS+/WsaBg+QBLkat0ByKyYjhcKAx9kAcN2f4o63uMnEXh7jrPymP3mcKfQRCdxLPQ+ObIOloDdXSeEwLAhhJizHcgHbRn22XxE3pTqa0z/llzs+BMFYrp/oZwNnZWClnd8= 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=d5WA6VqL; arc=none smtp.client-ip=74.125.231.146 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-f18.google.com with SMTP id 006d021491bc7-6b390bcab0cso1519699eaf.2 for ; Mon, 14 Sep 2026 14:10:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789420205; x=1790025005; 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=d5WA6VqL6D1qrRfsYFhFHB2f7KWItK60G2W2YEbz7Unm/kP7RtkPSnRSUpURL/xSnk Jg+EfCvjWAuci7grnUyUIPj8F8BY+YABVpkiw1as+p4oFlfKcB3VoSF5qVgvjJYNAPwl 5btZ1svb4U4pO3Dt2nCV8lbZzkJdbGBPdutpXFcdPjvaA6vHErAH5O81lCsk4yPnMYpo HVFiAvX5w2FUvH04sWN4m2QxzLXRu6xg6t/0Z036KcNgPfaIibUWKkup2LQCFQ/7AUbs D402/jpz8Z9GED55j8+4m+yYiKZlKUdi/nygTMyQo1Z5VGXkJuFMxKrC+OP6qsR+mBtV 2jag== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789420205; x=1790025005; 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=O8HAQ5FcgfCk5YXiqsH682Vs1TNl8CNu2mM5H26YFwLvDl3SRzCEWlNdzGBdOB43vz yRtfNEcdB9VNIpHEeUzdJRZkRk5z5UfMoNTk73LIOGyGBv/m+PP41jO0FDQHOGVUHCVW glXn90JoLd9jUxwTHFykK5Nr6zyzOG0PADuy7Q2/Tru6V1XjQuKbVakLFO8OwXDv6aP8 qhE/+AkqCdMFQ5dVTaU3LWebY1RwPwBkXnidI1IwaBiF4ARsDNCc15G3vDxakIwCncqf JEu1GSVg/r3Xgqvr0xYgd1iVbbyu/nFBi3o/6l0PV3jiD5Iue76Q45m2Occcf9uBzemJ 8Hmg== X-Forwarded-Encrypted: i=1; AKwUvByiZiVw8dUaz0UUOKdlnnF/Qk1nunM50Y2TBb1CMPlEG6qQy1o61zmGfj8SDfKixoG7MGhVpj3FM9eYAQ==@lists.linux.dev X-Gm-Message-State: AFuF++njNXy+ynCE7jsGYV2He60CXUicvts7L3qCfeBnYFIiWpOE/Wtu xw+aI1UOm3hQm/p2l9pOpk320+rgfUQlub4nmZKif4iM+ra9SEZ3VRuo X-Gm-Gg: AYBFou3k/cYSkz1kmQoP9Hk5rihtxMgU2zJernU6Zj76NxePsaDHHghhRkztiiiRnr+ aZVGOvyK33woBO29NjyuUZ2OeHHdiNUtLfiTcs3hMr2HC4GKU4NrxyjStGPjpscwHdSxHkXbhEV PY0uuR6Pyi9QCe/mZTbKLW0/BFUJkhW97UzY4wjz7lUoUN9GW2mnlgOWTnbkcq9bflF5GcXeu4V TPzfQPON+TiWVn4upKwazSGbFX+U4z/UqWRqkJvyabapx3muBJyollWRhUzPwHDlRXd/vWieUnj 10N/xeyN66uAZjlB5dWjyOj2o1ohhgdqe3j30jSKDMIJwbXz/lErpxmqk8n9kCnijXCqK4udGqW uS4aIv/9TJmLSIcqpTHOZuB4W3pdn80jJw6BWJe9UajWCn1GZ1OBB33V7JwCwhemX8v/Rbi9GDZ aGeJwUq11EZGprOcCLgCcUQqSgFAecoG7JQb0eJ/q8ML4KZTy/OUxhr8xdPc0Vk0IVY6nKUvhAU MyW76IL6eiNl/EeFHHH++gIphX5skntYJnGPKn6O60zuGL2SG73a03CEkhMaDCGosvki+n2f3dr KGeMn8iMwVZ9HHoxErAXYKPan9k+ZCxFoJXZnO/fZnGErit3+dS1iZl1S7itZh/yx+3vt6A9P0M YShBOKvNoz3m4vtWeg19AuhDNe/HH X-Received: by 2002:a05:6820:1626:b0:6b6:93d6:afcd with SMTP id 006d021491bc7-6c540b66d8bmr2665520eaf.26.1789420204843; Mon, 14 Sep 2026 14:10: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 006d021491bc7-6c45bfc3fe9sm4698544eaf.15.2026.09.14.14.10.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Sep 2026 14:10:04 -0700 (PDT) From: James Hilliard Date: Mon, 14 Sep 2026 15:09:53 -0600 Subject: [PATCH v6 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: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-7-2fb084fe0751@gmail.com> References: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-0-2fb084fe0751@gmail.com> In-Reply-To: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-0-2fb084fe0751@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.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)[21]; 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-25921-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: 4405F1C4D1B 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 21:09:54 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3348 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 286521C4D1B for ; Mon, 14 Sep 2026 23:12:26 +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-25922-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-25922-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 3B58060BD73 for ; Mon, 14 Sep 2026 21:11:02 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id E44334A2A60; Mon, 14 Sep 2026 21:10:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="PN4zJGPw" 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 2DC1A4A0F0D for ; Mon, 14 Sep 2026 21:10:07 +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=1789420213; cv=none; b=I9jZN2WKR2qQexdspdUb/FAoKGw7IuMf+nDed2X5Up0ORSaAVacIKBzojD9lBIuk57IGYJ4nfHmm5hy8XbhFVuwASxUM4ZmO6FZVx4H1+BGwmS7vHBDqXBFYbvB7/roKVu+ZGR98oASpEpr8PfymwVhOvNKNLiZIXNP3TD0yU7U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789420213; c=relaxed/simple; bh=YbBF9laHAErhZzSaGZGDzYG7q1LarpeBoJ8ap1tchQo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=XRusTJHGUqkkQxF2yCotv/Vf8zcDrQHmrmZUNPtk1gBqRUp8oKcGNmJ1kAYp4OdBbf5dcarNpSKgXMmyCZ+iMyQQqD5UGx78Xl47zx4s9p3uy5tcR0BS84QK0w13z4VsZxYNdwQIGue4pCxSF3ityn4Ctrc2D7Wi/L8ZWVA3Zng= 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=PN4zJGPw; 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-6b4bff33d18so1038114eaf.3 for ; Mon, 14 Sep 2026 14:10:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789420206; x=1790025006; 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=PN4zJGPwi2s6SSi7waVrxUQPpjf0nCMsB5IVqrhoZnHLa/3K/c0uFMOFH10ovDtrMM EP3Xsy0vegF1qDqzBgyYTbttNaQJ0h5nlvUCodpGAsyLZSZHP57nnRW/N61cLRqbHTnS LH0GzKhzxCvAyTkWcRH8SkNdoMmEgT6y1jk8zXKkG+cxNwcR5mM5heSm9tcqM71wPFuz 30ycHl02vAl6HaR6p5BTtrSK11gFjJwX7xLhWm00EThIodKrpT+yR5zcuBESpYTHYraV 2Cp2VlbhwFLyRjLHdQZ5KbwzUIXLUxawQrFFbp5iTMtGpdoICDcV0gGp2zxzm//3MCOp AuOA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789420206; x=1790025006; 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=Q5rFHA/WEu3lVzgmNRdNqYMHibZiM90Gzw83eHsAaxBhLOO2j9hc0MgeycyMjINMaG i+sy1Q7uhuolmGy6fi2N2AGevyd/1E6OdJoL/+N4xG3dYcaxF1v1IGOYLD3zg6WRxyNK BhJEhdp91mEDiiITfVKCh9SeLv8qoNjZzy//aPIR92ttqG/GbZnOCm1pGM7zN2kkaPqe U2dJiS/eYOegoG7KtM+ej1bvZU8HlXzlr4Wh+TI1wKYVUB97a1HNOnfOSJ6VZlggoYqp DZMJ56aUcKuwECyEtwzKcuBgpA+jE25zffhK3sJZSJ4gRyZrA2Srgkv9IR7SOh0ByRzx D/zQ== X-Forwarded-Encrypted: i=1; AKwUvBxVX/FnZTh7B26FP0ZZBrDAejLWClgdGUZ6xSdYaCi9HDUG5PZ9nAQpi3Sj/0szzKfAfABOfmnZ8M6y3A==@lists.linux.dev X-Gm-Message-State: AFuF++lqpt92pRxGsKYxpozsZuX6xvZS2YVKbNw+AhLiKOh4Z8x8MBEQ j2RY9cC2te0/NHKPXLTSJjpZ20wA0RZ/t47QDkcJXTT4ZZ3SkRiEu8c8 X-Gm-Gg: AYBFou3cILPAE4SemI0GGAWoPgewGMatvEkggpuJFnu1MONx+GPIZirlUp1uJyYOK61 lCKVJpWHBT1Yd3qX7Y/p9h9eNc6Ixc9VMyxAW2Q79tlnmx1OKBRCyErLYSFYAU9K+zTd/8ALNc/ Ep8BtGoZTwRRVi/XJQLLfn3u0Toxez3jBFAUKWk903qF8IVrTI8vc/6Ma4YIFGn9FtDKXlroM0Z 072F7ufFEQJMBpvK694maMMERIRg2TGj21X4s+g/1uJIvW+74PeQFYkipvr7G13t8tfHFEfCteT uUtz+epD9PtA5t2qE7deIaI6XTwMSSfsOF6RMN8jPs56JCTFJ3qycT20cQf8Yu5tNBbVS1jcANx MjvnpqwNiG5kxuJZfMglErew4w3TyQGeCPhyqR3yp8DTKHn8XDQp5Nhhlr2VOWKL+o/DmEH4yEh u+caOxQTL34zYy65GRCx/7uf/3DqxV+OK5HjzOqLjhCkb0BK3zlkspul0cnr1Pw3UXj9qDPHfyO IulrR6hW4XXpS0diaUoWUZEjXuYIKTZJ93qSXr4t4Eq9soC8W14U2Arcvvx0Tnig5p8mgjszP/1 8tUH0e2jp4/qTFUZbbm1gtpatUXW6hh4/4BT6hRiNMccs20/EydnXvsaqfFZDrwytTKdaDGJCfU mHAJft+yfPRB2fhOWllILbLpi4MZi X-Received: by 2002:a05:6820:c85:b0:6b7:8396:f3c4 with SMTP id 006d021491bc7-6c541457fa1mr2615579eaf.38.1789420206238; Mon, 14 Sep 2026 14:10:06 -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 006d021491bc7-6c45bfc3fe9sm4698544eaf.15.2026.09.14.14.10.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Sep 2026 14:10:05 -0700 (PDT) From: James Hilliard Date: Mon, 14 Sep 2026 15:09:54 -0600 Subject: [PATCH v6 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: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-8-2fb084fe0751@gmail.com> References: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-0-2fb084fe0751@gmail.com> In-Reply-To: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-0-2fb084fe0751@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 21:09:55 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3349 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 3BD4A1C4D20 for ; Mon, 14 Sep 2026 23:12:26 +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-25923-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-25923-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 4EAFE60BD7F for ; Mon, 14 Sep 2026 21:11:02 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id E50D44A2A63; Mon, 14 Sep 2026 21:10:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="M1p3Rb7f" 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 68A4149F130 for ; Mon, 14 Sep 2026 21:10:09 +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=1789420213; cv=none; b=D0nd/7valXd1dB9yOdaEZpEjW+EMO6MjF2yA920oNPxxFUht6zFx95sZT80aWeaGepa+C7DoSVR8F5YhGsXmmEojlMLtH0y8Q5CzKya5x92J9k/Yu/5Nr2oVvq/K0DYauZezHOo5LnjaX3NodxonSBItZSuQ71KofBqsdIKBv4Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789420213; c=relaxed/simple; bh=o3NPqjDQtjCU8+r59n9WbZaWXsVSsfQ6oMXDXHHDqIA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=aRV7HwKlZ81qKCLlEBMAsbbl1b+H8enE03K7M/cC0T1AavFQTeTUXpakI5VsjavJu49ywuWoYmOnEkUThJ/M64L4MzR0kVyes5XNlPYuCmDkBd9EtdEeoNMDV1QHPh/hPpv+Nfo9e0Lze8J8h/j7iNf0kd2X0IziXJuMWIkhfn0= 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=M1p3Rb7f; 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-6b1ae6c9b72so450419eaf.0 for ; Mon, 14 Sep 2026 14:10:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789420208; x=1790025008; 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=M1p3Rb7f5kz5OSZwfxHXjsvbkSogw3pNDLARomq3IsneZl/yJZtwNXXW4X+d3CdWJc /oazh5Sz7S4MBlFymNOS5WJD3KSJHZqe5OFnGNuGs7KtmtsBt6wldy/xDBceLSu180BY AuTEZW9KWq6vRHf0M8a4Kp0U2ixJENQ9y8AXOB0D/M98YA9SKmYUBWnzsYZYdqEgaK71 DiMMtWSY3SP6+31EWrfSvaDVKaKsBs+7xjarObn2dFYzvi2rg2W0HPBMwV/JKchCwyQP 6m9pDexmv9l2LrIJU4YGpVvL94IKyd+RXCkE4VX8AGgiZvhc/qYMiJoHu7O+LNDcaLVZ oMxg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789420208; x=1790025008; 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=x+V1iEDD8IdVArCWlkyphQjW6kCMVBdm6OmDOV7Oayt5L6L9IcNm76UBIYS6hQ9DpO nkbDTWtVXfZqv5l7z6aDrqYjvO4OpefctTEl4mHo44hRcI7k7+FccMUdkVExL7z99fns fpglrD/Ovyuhk1sEAWOu9O4MelHuePneO800wpYF9qTl9mIfW9IZZgt+tbo+ZOI1do/9 c9kZhyhdqxzYYL6rjFavU5ZsprVICg/TPDJRC1y/PV3FyJLwLUtN5YUHmApkV83V9SwP Nd/S4rnIuzw19VZcfeuDrUgg85lErhdmbJ3Lm5mQAEYdmZVOHVyA9maeNsRRlIigzMm9 sLYw== X-Forwarded-Encrypted: i=1; AKwUvBzEcZj6eawJSbfYB0C9QKuXMR0XUuB9Vu7wFq7vjEQAEZqcvWAEuazbdjs/8F1zNxMsPtjj/h83+JdFOQ==@lists.linux.dev X-Gm-Message-State: AFuF++lqNN9ucEh3EzCa8jQ5fyFqDQPUCwLAg0QQSnemrd8JfYonhfqI 4SoDKJs/8GtQzJYfGiUWjEIdUAEmBHDQ9KZifCsDMo0wUMxc3SkKhxke X-Gm-Gg: AYBFou3ILCffvhcqsHazRJYq9ztP6Qhi5KOR9yDX0Q148Tmos4MnIISAuaTsAIXb07o 2k8N5jmL/+DiSYkcvrZElwYsxgBleFEVov5mkTUUDuDRSSPalEna+NiFVErOVL8GOsx28PDQx6K Z21wlj0jSBaLffT/B2/94IEZwrFAyIucXHGAh5cVZwsI+7YqOF/oOaHnnhKzHO4/cQe1fw4xHqP t2240FsT8AQTaORKqgt7jFlwd+K9+BK8zoLYudzixgmBCPRvThtkXrScZQzbeUFLKa0L4zjrVek flR0MPJHI6BupT+UbPg71qYYlGJaczkjM1thrfS5OupPSi9LgnKmKCsS4vf5jvj9l5zaC5kLU1p C2/tUGanb2D8TZuqKWPvsyv2W/r+0e8usRfzRb8H/GDxuRiVOBtdP5o3lX3wiZ5X/WZxdHw/t4y UvCzB0kzeSwJEeilh/SAl/H/Mo+ooxxZ/D8cf+XzVEWYf8uPPdh8XK0h1Y30MRm9XtDsFo0Zv78 TitMMea7UOCClX/xKIQesJcWw6EyZwfxL7iME2x8+LQPqojeGzR9KMxsYOptwm0y/cFpVm/XP9v MzWWWLt6aHg9wHedAR86N8v/J4ggKA0fsts93GbpPyWB/uqIayJNTrmdv8WIUL6wSCqKFMemcTG plyp6lg67ofjiJEv/0xb4ZfGmD+DS X-Received: by 2002:a05:6820:1899:b0:6b5:ec3f:4987 with SMTP id 006d021491bc7-6c63a55903bmr501376eaf.34.1789420207811; Mon, 14 Sep 2026 14:10:07 -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 006d021491bc7-6c45bfc3fe9sm4698544eaf.15.2026.09.14.14.10.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Sep 2026 14:10:07 -0700 (PDT) From: James Hilliard Date: Mon, 14 Sep 2026 15:09:55 -0600 Subject: [PATCH v6 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: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-9-2fb084fe0751@gmail.com> References: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-0-2fb084fe0751@gmail.com> In-Reply-To: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-0-2fb084fe0751@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]; BAD_REP_POLICIES(0.10)[]; MIME_GOOD(-0.10)[text/plain]; HAS_LIST_UNSUB(-0.01)[]; TAGGED_RCPT(0.00)[dt]; PRECEDENCE_BULK(0.00)[]; RCPT_COUNT_TWELVE(0.00)[20]; TO_DN_SOME(0.00)[]; DBL_BLOCKED_OPENRESOLVER(0.00)[sto.lore.kernel.org:rdns,sto.lore.kernel.org:helo]; FORGED_SENDER_MAILLIST(0.00)[]; FREEMAIL_CC(0.00)[lists.infradead.org,vger.kernel.org,lists.linux.dev,gmail.com]; FREEMAIL_FROM(0.00)[gmail.com]; ARC_ALLOW(0.00)[subspace.kernel.org:s=arc-20240116:i=1]; R_SPF_ALLOW(0.00)[+ip4:172.232.135.74:c]; MIME_TRACE(0.00)[0:+]; RCVD_TLS_LAST(0.00)[]; FORGED_RECIPIENTS_MAILLIST(0.00)[]; FREEMAIL_TO(0.00)[bootlin.com,nod.at,ti.com,kernel.org,gmail.com,sholland.org,socionext.com]; FROM_HAS_DN(0.00)[]; MID_RHS_MATCH_FROM(0.00)[]; ASN(0.00)[asn:63949, ipnet:172.232.128.0/19, country:SG]; TAGGED_FROM(0.00)[bounces-25923-noreply=patchwork.local]; RCVD_COUNT_FIVE(0.00)[6]; FROM_NEQ_ENVFROM(0.00)[jameshilliard1@gmail.com,linux-sunxi@lists.linux.dev]; RCVD_VIA_SMTP_AUTH(0.00)[] X-Rspamd-Queue-Id: 3BD4A1C4D20 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 21:09:56 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3355 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 482FE1C4D1B for ; Mon, 14 Sep 2026 23:15:25 +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-25924-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-25924-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 1BE49295C1 for ; Mon, 14 Sep 2026 21:11:08 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 1F3BE4A341D; Mon, 14 Sep 2026 21:10:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="UCnIJroq" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-oi1-f176.google.com (mail-oi1-f176.google.com [209.85.167.176]) (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 7BB8D415F06 for ; Mon, 14 Sep 2026 21:10:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.176 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789420214; cv=none; b=CgMGByiqDWLgzvas/moS563fVZYjXpplSjkmKxnW6q1cUAPQdy2KstSzEUDq5T04ejCDktlzPgeQArDJm9G2oxTnczkxKh/msH81ooORufS1f3OTra/z8zrmi+PeEv+DopWUxw7Eb6epXmwRqAEnGkKO5IgsFopTHKFkZPn55Bw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789420214; c=relaxed/simple; bh=vtg+z9G0CuAdSRbu8cVWZ/uIsLBQGyskZGCo/vbBtVI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=u/nIWMb9Onk5B5FQzpOZNxdGege18QH6L6YqQN+Rg/mYyKRE1YJ22KW4pXKjVQb5byb7sE7VycwCahB05qAvde0HlXP7vFoq7c13Q0IzoX1Oft7XYEbdQxCuYHd/gmp/CXBt0X4kmoSnPUx9Red9AS8XXnEyjp2eot1BYd+xF7A= 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=UCnIJroq; arc=none smtp.client-ip=209.85.167.176 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-oi1-f176.google.com with SMTP id 5614622812f47-4c5373b1138so2039543b6e.3 for ; Mon, 14 Sep 2026 14:10:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789420209; x=1790025009; 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=y7F79jQI2v9SHnTcdbLyHrKpLzhqd8SwLgrM0tg4BfI=; b=UCnIJroqhI7H08tGrfDh66EOn2nGUdrKUa4TolpCooRRDaVOGdFBojrV3o1EtDgSg/ Havx+8RKfWQNBJl0er1XB8Mi3Ve8p6nRHcCBiP6ZdcHvFwp0CWp56if3zzjjWkzPWH62 gibU12pPryXDi/m3CU47KqmsTsjfWtsykwOd7MY604bnVEf8BruSSp8izm3HRqvn1VyB y8h2VD6vnd2e1ZBwsvqO102ckaC3eYvrQW8E3v0JV+5H3963Q/xN0q/k7zLMVvPBo2Rc Yj/EVRDfX6K0btxWDS0VoV/fidaUnNU+mSlhDXLTSxz2EipOgJpn9w+ISmjtOYG0vF2W +Mug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789420209; x=1790025009; 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=y7F79jQI2v9SHnTcdbLyHrKpLzhqd8SwLgrM0tg4BfI=; b=iKJzMhNQNN8oJhLXeQcwUw7MpMKgCz7NJpwFbhQVmM9Ef7muWbIGeQmJhAqVaPnsQX E62d6NAKfSHKoNgbOqbABtjVfyyiTZ13l7Y19e5lrksrTyVmT8UmwbuTGBMkjidrx0MY i58P5Pes6W0f9kY8mYrQ8GFWhv6C2EWY6W3CdvF6myyuNSbZbiNhYusY8SlGpCWc4Tb8 4XZD2gofd+UmOo5ya/NsO9kBRs6pvXlCACoHjg/kJVl3lgPnkS8Us7/qasBMcSJlnyyg EWnOmG4ytK2ryUiKHWoqLeXO/OMONk76HlS+tY0TSgb2K1xpVzXlK61+/a4fPpa9dA2V 92SA== X-Forwarded-Encrypted: i=1; AKwUvBxRFEQ2+ZzEWpSmHqG7qKDHD8610HjxpyHuSd37MdgZkdRVGvloks6nA1ITa7WBNVjQ2WpJUZGstXnKaA==@lists.linux.dev X-Gm-Message-State: AFuF++nmVKymUk9lc57GqkzNv3/fGqbTRR6qFUYJPGje9xpor9T6rC4y m+9HwB7C6vn+LxqpytBKaKU+fMT+wwBngF3NoGQmrGXtEZ4G1t6h4ZQ/ X-Gm-Gg: AYBFou3ESCW1ykue+9IHOdsex680GCVCBudHo/uf1jSNdxQVzqXtorYad7ILI9qBOyn BQGHY6bUs8t3queI/XHlA2lrMvPX11OprZCgxw2zWKAr3rwemFPaCPChxs3fk59mZ/MGU0ADyif SskCVKQL/DjKXtG18nrykE5hUSKWVU9asEQd22zzkcHFFZO/slMY5r3ejglapuCXieJGp9aPYKy lM07uxp64Vyi4Ab0tlpj1n3qyH+q5SmTws/iWIHOGmM3A64EBL/vedhCWwEVwqT4pjzyp1IHWjM FKGlBkrZQdTMf+tnnQsoPBhFNlmXlgcos7QxL6PB4el1f99uynQQ7kzMZYCuP+d/ZE15dm7wZO7 WStGJImGM0vmLRHcudH94gpu6u9cmOrOKoCXM0ss8mpSWkWncfSpHLNDoR4wSP/e15sEtLwoQX8 khPHLvF23xRVSka51K3OOC1RYr1mYAugHQ9AgisaByZzqhJY4oqKTQvLTvgHNzBE7/be3136YuX QiXMEv8LWuzutsgj43TwunamSouduCMvJGYiy9lhEoZ1L8emZ7tKwxgtl9obkyYk4SJL1EYGtK/ 6rL2L0R7Bz2ylpVdvZxf3uZNp2EiXYmZhe25kaTbQlvTgIpf+iR7GDQvRy3oiA5u5YXZ86n6Quc plSILofHSQRkkio0AfMHGNh5zWYCz3lDHpGQgT4A= X-Received: by 2002:a05:6820:2204:b0:6b1:5c8b:c0b9 with SMTP id 006d021491bc7-6c54008880fmr2485081eaf.3.1789420209405; Mon, 14 Sep 2026 14:10:09 -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 006d021491bc7-6c45bfc3fe9sm4698544eaf.15.2026.09.14.14.10.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Sep 2026 14:10:08 -0700 (PDT) From: James Hilliard Date: Mon, 14 Sep 2026 15:09:56 -0600 Subject: [PATCH v6 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: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-10-2fb084fe0751@gmail.com> References: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-0-2fb084fe0751@gmail.com> In-Reply-To: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-0-2fb084fe0751@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 while retaining the original logical main-data and OOB offsets. Fill the first batch up to the register-bank limit. Transfer each remaining logical step separately using hardware slot and user-data register zero, repositioning the main column and spare-area base first. PAGE_OP generates the second and subsequent main-data columns from its hardware slot index, not relative to the initial column. Read and write probes on H616 confirm this behavior. A multi-slot batch starting partway through the page would therefore return to the wrong main-data column. Single-slot later batches avoid those internally generated column changes. Pages whose user data already fits retain 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 | 284 ++++++++++++++++++++++---------------- 1 file changed, 163 insertions(+), 121 deletions(-) diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index e29638c828ca..18a4d1cc4246 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,47 @@ 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; + + /* + * PAGE_OP generates main-data columns from hardware slot zero, not + * from the initial column. Use only slot zero after the first batch, + * so the explicit column change selects each remaining logical step. + */ + if (first_step) + return 1; + + 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 +1029,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 +1044,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 +1297,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 +1333,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 +1371,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 +1396,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 +1784,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 21:09:57 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3356 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 491431C4D1B for ; Mon, 14 Sep 2026 23:16: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-25925-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-25925-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 17BEC2B5B6 for ; Mon, 14 Sep 2026 21:11:12 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 2FF3B4A386D; Mon, 14 Sep 2026 21:10:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="sLI2Cfm6" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-oo1-f45.google.com (mail-oo1-f45.google.com [209.85.161.45]) (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 6503B4A2079 for ; Mon, 14 Sep 2026 21:10:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.161.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789420215; cv=none; b=NGFZGZ0/Pe4Jg/t4crY52VVKfwcrRCK70DhLBD98El5obyux/TUrJTvmRvy9Z8i1Klcf9OYtCRiYRkh14iwod/RGWaMDo2zBMDEXe39RM+K7mVu+aSf/wm4eTCCuYoo9KXJvAWz5Yaf5gPVgmo34p+mRDTdYaYv9MTGQF044DAg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789420215; c=relaxed/simple; bh=ksccExueJsIuwGCb0dZjS0SLEa92Lo+4Eg3nzx6yLIc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=erZwziYb9rD46FsJ8cTI4FNX6GZmH9EEB57AXglNPOKmTWgo6b0WRH/FfoKzhCedCqTayUCjuRqUlMA94oTKfNquBWCxMCYhJORbEUVXjPG0vHH9FnGGZk3HGJaM601KKTcR3SdMSMR26sueia9lWmr/1sGwEZw9p16hECRoLSo= 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=sLI2Cfm6; arc=none smtp.client-ip=209.85.161.45 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-oo1-f45.google.com with SMTP id 006d021491bc7-6c1983dfaffso3072222eaf.2 for ; Mon, 14 Sep 2026 14:10:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789420211; x=1790025011; 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=Euqh3OGD+8WNOg3rzaOTiHhaf1O3ybQtEVQQVF9+898=; b=sLI2Cfm6nUxxGmdesJRJDZmTOTd44qT0gTfX6XUwmLhLrZqb560oNmXrNziatgzVd6 Ns2TwLLaeXD8JYhI6GdH32FCtGDulmF5D0ph94fY1uxvQVbnQ8yxeqUaaixl9+VOVtHo aiiasZQ8OBr0tIfSXy+LIM3n1dP4QvUk6r6YK/Y8qVH7jbPEC66j6VN1n5x8bDZposp4 S7UkVTEKtl2mHj2JrFwy3fyqT54QDu+vFUlDUAavHFVDCPUZ4Bu2n75g/GA31In67p7Q 0Z/EGmgQtEqciG1zDiW0V7ISVStOt5v610doHniw2gY2zZtGs3yvnEIfqQzsCJ0ohJVX bypg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789420211; x=1790025011; 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=Euqh3OGD+8WNOg3rzaOTiHhaf1O3ybQtEVQQVF9+898=; b=vVRaTC/kiAMKUksrDr2qSwx3BG9HBvO72kofGt0SWEWL/oMvJ8KsuYrQ1aAJ6+UF6Q zd1pATd3dMZ4vWmFs3tLgUo68z///eIwyIvtJ27+DI5r8+w/oPR76T2wlVWeoVBSWRmi 1CQ4T1ch+6LZXPIOga/XHKkGZ31YxI/P7D+pHiZJQryw0i82s2yxMoGG34ZzGKm4iCHG CXS0X1WRvvrG8hGlEoNktYyOmGz2Eh/Zl1BI3tmJwFUEHZVnxZEB6ZnR7hKQHRtkQ3BW 0+zJ7m8Z9VuC/nZxq8kCOs5j2hbzGUwOSzIwi3ixPUbgLDuxgJn07CB7Qru1ocSWVKhV S2IQ== X-Forwarded-Encrypted: i=1; AKwUvBwRsEBGHL0JU9ODelDylzeCkpSWREq0OpeK2ZCQS3PEaCYbAyIf3rYjYnxj7dnCt/JL7BeHOTEkQ89c4Q==@lists.linux.dev X-Gm-Message-State: AFuF++leUEnf86hi+uK8X0BMAVaayW/RE47uynOEzviNmJmWNaB1nh2D M4AEklG5ZhKnGCcIGNIxZRiZx3edESUTmoSwl6I+xZGUIUv+2mjVBppO X-Gm-Gg: AYBFou3rUL7e7H2A5ApY8QK4VRrpahzomjj2gBFhpDL/V+tb+sfKW9EANfDQwaPWkpg Gxr1L4ruwr9IzUP94GVp3v3/CNjPR+aj6C8pVOY0wKuYHN1Ubcc7R0oNlwnbn6YBY4ZoaIvWSJz OL69CZY1zaybEf8SnkxPKA327IKlVp9Vms+9Wv07Fq1b6DsAPE2b8CVc99aTvAy7cOmG2yPNxdj JUbdJMLVuRm0+TzVmR9O0RbuU1KJ6hzt0jnHJBqk1PtKpRfqR4JSjGGAQ8mnHNegkMTgOWU/WZQ gw4rQI93HNATacHUnzqNJeHLX/jG1dVxPJVyhB2C+lKV6aoPBXlgvnL4e0IrHRLC+2SRfvu28Ah P5j4PS4kyczj+pPU8WRlJK7fHW3T8z8pir0DfYElqAeGZks8U7cy26vGByePkGccAaC28I2wlGD b1zyQc/cXA4ge3YEcEWsqoPd5WxEbAfAWDrBArnfKmeAB27OQkxDxDWwbhZ7uPaSxmpdfCc0qZb xhSQP6rcOnpb6hr2hyyOUoe+KpFnCmSGZ+DwqLdm/rJNFpKH/GVrmWkSrV8tzEAQDqnLbOCWRgF cCES851fUnZVBCKRQOP8PDqPhHTHQtmfU8W7+S2GkWwCh5sMKCoJU10++H+FFigF230oLOexe5A wB8LkfVOjCArJjskCa0KcvxKyHBtoZNHITEnnVHQ= X-Received: by 2002:a05:6820:180b:b0:6b7:8415:d78b with SMTP id 006d021491bc7-6c542734c78mr2067060eaf.54.1789420210653; Mon, 14 Sep 2026 14:10:10 -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 006d021491bc7-6c45bfc3fe9sm4698544eaf.15.2026.09.14.14.10.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Sep 2026 14:10:10 -0700 (PDT) From: James Hilliard Date: Mon, 14 Sep 2026 15:09:57 -0600 Subject: [PATCH v6 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: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-11-2fb084fe0751@gmail.com> References: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-0-2fb084fe0751@gmail.com> In-Reply-To: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-0-2fb084fe0751@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?= 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 18a4d1cc4246..c55537bc71e1 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. */ @@ -976,7 +977,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); } @@ -998,7 +999,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; @@ -1021,11 +1022,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, @@ -1037,7 +1038,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); @@ -1107,7 +1108,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); @@ -1116,13 +1117,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; @@ -1138,9 +1139,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, @@ -1148,18 +1149,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); @@ -1181,7 +1182,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, @@ -1198,7 +1199,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; @@ -1224,7 +1225,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); } } @@ -1239,12 +1240,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; @@ -1256,10 +1257,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, @@ -1300,7 +1301,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); @@ -1403,7 +1404,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); } @@ -1427,7 +1428,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; } } @@ -1441,14 +1442,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); @@ -1456,7 +1457,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; } @@ -1473,17 +1474,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); @@ -1507,8 +1508,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 | @@ -1565,7 +1566,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); @@ -1589,12 +1590,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 21:09:58 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3350 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 CA6881C4D21 for ; Mon, 14 Sep 2026 23:12:45 +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-25926-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-25926-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 B75AE60C285 for ; Mon, 14 Sep 2026 21:11:09 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 0BF714A385E; Mon, 14 Sep 2026 21:10:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="RN51EjHo" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-oo2-f15.google.com (mail-oo2-f15.google.com [74.125.231.143]) (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 379854A263D for ; Mon, 14 Sep 2026 21:10:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.231.143 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789420215; cv=none; b=CxB5RunGskGckXxB3pCxGxHgA4ingcLdekWS2SdvdczVJEkvgXtG2A1v2q5wbYlWsYBd7d+NA5pjqNxG1IZxSI/wS5sf+xLaQ0TZDP/sY9Z5KTq8VnoQHYpxP/wrd4vVYZUfBXmOnnB2ief1NjTXPJDb7KfhiE3CGsUAWz/qfRA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789420215; c=relaxed/simple; bh=TnmhAN7UAS2ynuFEOPQLlzD2wvbIo/yeVWwhOMqNS58=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=IrSOYprOPSa5RVZidhNIXp9PMq0jtNu70yhzmRUqmfzPY8tA1dyq9fHpsmNmtZOHFW09d1G6Y4Pd4NjsKSBHVVw0lRpKRNoec8hkcYpoDURHui/Qu+9bWyFRyUWiIqg019gbGzdnX9KrKYz5P4eJCgBmLg2CUOvZqK/8MdxfRjs= 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=RN51EjHo; arc=none smtp.client-ip=74.125.231.143 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-f15.google.com with SMTP id 006d021491bc7-6b4bff33d18so1038157eaf.3 for ; Mon, 14 Sep 2026 14:10:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789420212; x=1790025012; 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=RN51EjHoc9JtKaeVXg6AjhLaNC+1LbcCWuDmEXPkTGhY9Gvw1fpa1Zn9qekWZKuSdd lor+5rybOFuWm8oy65/cSC52C/FDR/8+4yVgoyyk1SLBMlFhfsq+NJ3WE7v2c19zPh17 kCgxm+YtCukEzPFwIwlX5e/1yhxwM3muOHcmdVX+Oc5m8TFN/3DX5b9TAl41nxVTLUiq v4hDZq2VW+jGQX43Jn+1KgZA6IAdnC74kGfFI+nVUknRuhqqOkOdND/hg/tZ/FcMfu5i 3bEqE/+jLmdgazbIPFoyrIQHy69oE2dD+BJFGD9pE32ulNxKy3YYOoxn9xArLmCbhtsH Hzag== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789420212; x=1790025012; 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=nyQ0R/WESPPPQ+Eq7cwhekQBjjMOwiIWk0KoUGsAwbb80EQN3EI7tSslvl6Ja5TRSs ZwQW0nv0Wojm63j75GT/23cLgrcdD3RdNYBIGLFpz9GCfRM5JsSDbovC/+fq8XZ9Yit6 wryqt3cnEIN3uglatZ3gB9+bLp5yNtWGV/8+3wYzPE1W4+WVXajhmlEWWsiMjYZbiK5U 5UUmiv8g1CUKpgMTjK4Hy/gdL89PwnjsLv3hi8JhGaneTDAOQz6m7Selu2/E259YnDes FnOQFSTjiERF+IZIBkdbNawx5+5C5Sof10PpwoATktb5ssR9WhccNQAAZISuG4Dhk+A3 KUfA== X-Forwarded-Encrypted: i=1; AKwUvBzzza1iXgKgAt78EK9yN56d7wBwGCT8hCSoMf3C10i+C81dg9nt7U/5IrOZwiiP4Qw2rjp5us+vn2dWVQ==@lists.linux.dev X-Gm-Message-State: AFuF++lUZXr1dZFw7ZZbiPid5hWvO9lhoWafKQbz4ysP5KnYn53Ns3BV qYuC5RbGCjJ7ma2pQb5OotB0Yz0boFUgqPGn9PTcd6YZJIkEE8iSzC/9 X-Gm-Gg: AYBFou2llhtCFBoCWuXw8bbtuSV4vql6axIZWEf1lH0g8FVLRVBr7/xwt5EAA7SbV13 30BcHT07+UFXAQazyby1BqBK3H5+0wFnWjBg47ps5iouVMTZJzIJVYRtoz53vRaPU8fMH22TsbN RVxga2bwl7ExPxmbmDm7CuZQQ/O54gSk1eh4loLeAjReGy4Eg7h5JBDLq3dleO+KZ+IQfQowZTh ZAlet0luhhf0dV93Tq9otwU6i0xiCD2mSYb+6r8qB9L9Jl9MA6UvfkgEYycxzaLgKz1z1wk5vf2 IBIeSZtGtNMWn/ppeQ2OztsNXWSFs1N63ZQ/Fry2qUhWK2xK6A2HsTZIwvbWWlZQr7KTByoqTF6 gLFhMpIxXCaBIMXt8PSrx7E/d2aZB4cSH4kwObyN1XeQg3Y04fv6n1TmVdcNKO6cNNRxcxeYp0H lX5oob1ZrPQUpswn7vMIXJv2UNn+EeC7CX6eSQ8MkWHSdveN1U0uRx0jAF07+8nl3g7B8G27on0 THuvZ8jQB5pA0X7TKk3EIeZXmcMqEKjQJDnUSBDmadi2lCI7UrrebpfjI/G0DyO1ashUAw0b7j8 T0P3QgWcMvnWc0+bU++KrmnUlXTXVF5CjHKA7SNN7TS6KkUopspKB+xRvUA/jH7BfLok1tl1bDm UKzduA045tbVv2ymKB6jxGj/YFyn1 X-Received: by 2002:a05:6820:1609:b0:6b9:4557:2722 with SMTP id 006d021491bc7-6c53f252fa7mr2388952eaf.3.1789420211667; Mon, 14 Sep 2026 14:10:11 -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 006d021491bc7-6c45bfc3fe9sm4698544eaf.15.2026.09.14.14.10.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Sep 2026 14:10:11 -0700 (PDT) From: James Hilliard Date: Mon, 14 Sep 2026 15:09:58 -0600 Subject: [PATCH v6 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: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-12-2fb084fe0751@gmail.com> References: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-0-2fb084fe0751@gmail.com> In-Reply-To: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-0-2fb084fe0751@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 [4.34 / 15.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)[]; RCPT_COUNT_TWELVE(0.00)[20]; 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]; 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-25926-noreply=patchwork.local]; 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)[]; ASN(0.00)[asn:63949, ipnet:172.232.128.0/19, 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: CA6881C4D21 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 Acked-by: Conor Dooley --- .../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 21:09:59 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3357 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 7F0E11C4D1B for ; Mon, 14 Sep 2026 23:17: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-25927-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-25927-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 CA1013665B for ; Mon, 14 Sep 2026 21:11:17 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 3231B4A3D4E; Mon, 14 Sep 2026 21:10:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="ZWr6H7dR" 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 590ED4A0EF1 for ; Mon, 14 Sep 2026 21:10:14 +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=1789420219; cv=none; b=TIO5Gw8eKn8nF+v8lQL3KX6grkwpQtOpbqQe3jnxohpz91XUpXsaAsnHzL1A9KkVvcbwMVFRI4Z3XzNT9XckE4/ewgxOoL+Myd3s169LfI9VmOuerwdJkCHbP9wXxlwjdABKBWPJNdhUehmjI0uHQnREzDHVdwOkrxEYBnkc8Ek= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789420219; c=relaxed/simple; bh=pkxkYvAECUM2dxAA9qSlcoZx37otQGFTR85S/Ac1keQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=gRAUtlRO+dL2fggkj1wTOSq2KC08WkViwc1MC8C2M++XOVExAXWGG2Xn1VjYLApEMIx9bDNe+WWNSrGb89609DFNJPrjS9bn0Ax7DpleS/W3nTY3VzsPW6zuNfVR7/k2+q6X1tMXDz6LwrLQAcyLNlX3qU0YZCNKaHnlHWJ+aT8= 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=ZWr6H7dR; 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 006d021491bc7-6c24d19ebcfso1395794eaf.3 for ; Mon, 14 Sep 2026 14:10:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789420213; x=1790025013; 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=PM3/kqI6jzm2niMT/a23gQ0WVuxg3p+u/T3bZIK5RE8=; b=ZWr6H7dRqcSX7+uugmUiM7Z2HvazAhLE5/7eGWuzWlgL1MQdxY/rIo2zSlvrYd0wM+ /I56F39HRdQjvJl6f5EWAoGtp+XBm0Xr5+dHxGDpaOY4btg8PhwxkXyt9PTLv4gFOBhv TaPrUt/haT43+RAC88hFhVwlItAdN3jHHLQLSBY7CBDkrYwNQjjZatlNs4LG/Bnbz1ef si0CjjQsOs/OK/Rctyc9O6kBc2yAy80ByYPeN5Tb7nNE1PzOnaSTVHrkLIvZQS9plV7z tYhro/B6UdoL87CFWJbRqsldDUXVroNUNT+BJDHndKMadMDftl7lrLPg/l/4l50DVkeb x8VQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789420213; x=1790025013; 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=PM3/kqI6jzm2niMT/a23gQ0WVuxg3p+u/T3bZIK5RE8=; b=VxyCfas+fLvRjojzpM5hw5XzQ6B1z9ec65z8CN3Bb7F09JITYQdzzDunY532AizyVG DsKpRaLzKghLGwpLfq5GogB+qIlTGeuGX4GkSnlpuviIoeK2gHeP67v3A7wZxefuqzSR cR7WybIjZRVFvKcdSiJa6qgr6/OkCl/PGG6+b6UtQLHvBc7zfxy6B9qx7qkUDORc0FkY Yhw5cG3Y7IkHeDQf7c63IGCwiLKYY3/Pik3AgVR5lsZf2+7zN7OgOlSnhxM9iCi23zfh WLN8uqi0wNq8QykeWAJHJ28PtFfPXSAumUhynt2iD1xXKwtnVY9kLnhirjdIEbmCnCS2 r5uA== X-Forwarded-Encrypted: i=1; AKwUvBx6JgCa9KucMaVaQklGeKtWB4ybYeedCrKoHn4+8yRCuUmKlPLqrBYp39p/y1HgjT9SSuzHcihAgYcx2g==@lists.linux.dev X-Gm-Message-State: AFuF++nJK9uOYyzROtpukzT6+/qEvbOh9jJ4hkcPQSg0f+lmO7K1378A kHcJusStETq8H7zPeoivrCGwLf/Cc1LCePDIab24xWAnh09sRyD054aX X-Gm-Gg: AYBFou2xp7SdYCsa62Wz4u+TXmXV3T/XKmXPg7E137wWdUQIBY56GGt8VVJNOe5gvS9 K+Or8h3sJssL4FbeiC+7znFneKwJcDU39vue+qCL/Q3DV9j0PI633ZTFiYboigvvUG+3wVwXvOe Zhe/3YMWLDFN8kdg58nFKz0fZF5wEenKjcsZyapzlnjmSFEfHfaSCT7SYM3JRy+sBpsGnez464J PVeklTByz5O8YzUdEwhfY3tdF1VXNWkt2Qr2xCdca+Des7iKanDef0ar/eM0x9ZYR4fWft2yrCl c4Ek3qehYbBw+1otBw7QC/gADIQVeobiqk4ruPkw3+cCUn18PzvIXStJjtcSt/lwTYbfX1YVUdI RsfWJZt+dv30FiC+V2jZguQQLoNd1WKodj27+LiiivtHspLTZxtgEY7XkH5KbKy70H1aRfuP5aU 1Ob12pXJFgcqlAU+cAZ7b2CLlvyONNW5mEDFLkLuyyNPf+6dpLo1J291xqznIzNfiCPoc2jdI0q IKm4PG25EarlEXfTNyOmgxNySWhYhXRY5poiFGXNm5EaNYqkDbQPZOw7GCxHZy+aw7BR8zWSoH6 vRB0gNjDwkPnM1IviISL81q+P3imaWD3QwuKu3tTL9d8+Favj+e2v6n16ffLJHQBfC+M9rVNd/A PhO/m0MKtasqm/KqhKf9jwqBD/FcM X-Received: by 2002:a05:6820:3091:b0:6c1:e01b:3b32 with SMTP id 006d021491bc7-6c541f45b17mr4443872eaf.33.1789420213021; Mon, 14 Sep 2026 14:10:13 -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 006d021491bc7-6c45bfc3fe9sm4698544eaf.15.2026.09.14.14.10.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Sep 2026 14:10:12 -0700 (PDT) From: James Hilliard Date: Mon, 14 Sep 2026 15:09:59 -0600 Subject: [PATCH v6 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: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-13-2fb084fe0751@gmail.com> References: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-0-2fb084fe0751@gmail.com> In-Reply-To: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-0-2fb084fe0751@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-25927-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: 7F0E11C4D1B 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 or physical pattern. 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 ECC exception mode enabled for physical-pattern reporting, as in the plain-marker format. Uniform physical steps can suppress hardware ECC errors, so treat them as requiring page classification and do not use their correction counters. Otherwise physically erased pages or mixed uniform/encoded pages could incorrectly appear to have decoded successfully. 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 | 280 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 270 insertions(+), 10 deletions(-) diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index c55537bc71e1..42c5f782db40 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, @@ -968,6 +978,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; @@ -978,7 +989,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); } @@ -1035,11 +1047,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; @@ -1107,6 +1121,43 @@ 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); + + /* + * Exception mode can suppress the ECC error for a physical pattern. + * Classify these steps with the vendor page check too, and do not use + * their correction counters. Keep their decoded data until then. + */ + if ((status & NFC_ECC_ERR(hw_step)) || + (pattern_found & BIT(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) @@ -1149,7 +1200,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); @@ -1198,6 +1250,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); @@ -1298,9 +1360,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; @@ -1383,6 +1592,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, @@ -1409,6 +1626,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; @@ -1438,7 +1658,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; @@ -1448,13 +1670,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); @@ -1564,6 +1790,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; @@ -1586,13 +1813,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); @@ -1638,6 +1871,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); @@ -1658,7 +1895,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; } @@ -1677,6 +1914,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); @@ -2308,6 +2548,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]) { @@ -2391,6 +2635,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; @@ -2400,6 +2646,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; @@ -2629,6 +2883,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++) { @@ -2907,6 +3164,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 = { @@ -2930,6 +3188,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 = { @@ -2956,6 +3215,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 21:10:00 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3351 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 083EA1C4D1B for ; Mon, 14 Sep 2026 23:13:22 +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-25928-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-25928-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 8094060CB95 for ; Mon, 14 Sep 2026 21:11:22 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 0D22E48423B; Mon, 14 Sep 2026 21:10:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="WOZeq4ug" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-oa1-f50.google.com (mail-oa1-f50.google.com [209.85.160.50]) (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 E434F4A3878 for ; Mon, 14 Sep 2026 21:10:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789420222; cv=none; b=Q/BpU7Oce0hV933y0lPYUSwHPkD88cX+/6lUemD4hx/PldQEObd0H2VfX5JBKFsM3xy2uUUh2LIgCW0jpExacODE9BaP3F3n8VfHDJ8TvL68AHinVAPAGQWKxVBPme5Hf9xGRzWFS0Y922WjuBE4n1r5QmJUgfgBRftnPQwlArw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789420222; c=relaxed/simple; bh=RYMhZUroOg0vuK6FzRQ8q2eVSn0RelC+x7nX6I7sGZ0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=fize7pYPv/DWpgyal+1auNuHuMUUtarxydon9bDPldCfHKBGng1prOw1Sl0vDeF6QtbB974nm/OH5xXHwpA3tUhx7neVUZXhWEG8B8gsAHsy2TXwMQwERIt/T2q4eeJrZrFedhHer3cBlH9my2C90/kTOwsIBDoH3H4c+n4EteE= 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=WOZeq4ug; arc=none smtp.client-ip=209.85.160.50 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-oa1-f50.google.com with SMTP id 586e51a60fabf-4827cc09eefso676810fac.2 for ; Mon, 14 Sep 2026 14:10:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789420214; x=1790025014; 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=FDb8CvIky7fTL8ZHKUM7VSBHzZxqYVS0jxwrplOkME4=; b=WOZeq4ugd3G/B1IDIx6NRktERIPCF+7DkWApqgc86fhPZlJ/BP497C+NRAyHbirLIQ 4TCNKs/ghh+cJtKP/15tiY+o+D+Zl0MrDmA/0/eUmy7zy8ZcC7ajgvk5ENqSXTeCWgD2 irWZ/04sjRNqZeaAnTdas79/iZLj4jV/mTwMwqToIjlCk5N1fktvoNLaGI1RvWxEy3Fx GDtoZhhSYVjKo0kBUA8vIoRXRoZ9Y/fcNkZ/ORowFHj0Y5dspXmspY6Jr4mTq1nHp/VF T/bRQpWirUPFAnzE1oSNjERQ4nMWMFXCU0vK3JiHSXItOigtn88OvyeltplzVblXu3eG bW9g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789420214; x=1790025014; 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=FDb8CvIky7fTL8ZHKUM7VSBHzZxqYVS0jxwrplOkME4=; b=c60oTG26i3W+UTY8FYG1MCnP2ca1SK2aK28w3H2GiQKf5Qr2E+zY1TimSPUuFLS14n LRtxpfmWM7VTTZAoAyqTWHPkO4b5mRTZVyqQPLOwhyw9XcEDkAdHUQJDfXVSR0tPie05 M4CIbHEvFzHUF6ojcuKq5w7psBiE6Rgiiu/230lENWUry1/U5fWxul4tWTAkd5QNbRBn APBEp5goFFP0NDYpMMDqzjtePcqpJ36WWj1Ctmf6vjS7Kx+M4k27nLYjh6/vJknvIsYQ 9KfohykiuZf5cZhb8RDJNTbTnKzGdX1SdULkO0McFVgGvhBeIbGX8t2ODAVsmD9rLebr 57XQ== X-Forwarded-Encrypted: i=1; AKwUvBzMWOgRL5WLNNlFobaK7Szrv/g+ZoFNE6hOIuz84v0R7UkAF3MAZa74DcnD6x/lhT25Shgf1oHNv/EU/Q==@lists.linux.dev X-Gm-Message-State: AFuF++m54LEAYkCZ3dPdLy2s5vJn7/nF09Msdd/8peIDTMScFkV/mpbd xmRoFhtBGT6gnSjwEahQHWT3no+bwN/byI1BTdAUWvb2I4wl4HLreomr X-Gm-Gg: AYBFou2JzB5NQOPAYZPEb2CnUu/KpQ41ZEKo2Y12Ipbl80UA72s4U02GZg32SIMHYuF mZ0klrnoE2Q91LqQfA310c53DbSpCCZNp1dLXQsiFrwjnNDvIWQL58WVS+LTibPPmMH5V6kJeY8 Rxls1Z+Y0RKTNucDPt0fGo15XE8tP280X30gzE+yhllCc8j1Q4o1/o5KjsPq2XY/RRr5EeJ+gNW Ab+/H8BKZUSyYt076Z3bZIjfrA4B9EUlRt5CMGQjyqkw9PNmhhAq/Wc8VYtkcvaHQFJMGf9OjJ/ ZTkHIghskdEGI2JT6JWMw9bE8AaLx/0WcgWpzaF8kjZ9PQ+M5p9m+357HQlrAnuxyanD58Fg37K Q9hZb1EX1rwGOqSKA64ZxF/gn3Hni93m4oU8hgaXNGEEyku+iOR0zJl+cl5RGO0QuL8rpum2ao5 cv4dxizJlV++CNLiGt7el6T7/tqqATUqcroTUpr/U0CVErdd850OFzbdf3Pb2AKFBARHURqQANK u8eUptDCkPg61TcN12OhcCONMLl+OydadkOheIOSlpUj8837nRfMjork4Tu9LHMfRx8YUUTjcFl 7iRtT7zaVh6vSUf7UDP+o62NZUwYUkvdohbhVt+OHn+FwB0lF7NLF+/bXAket6z6x60MA42Tnp7 GvrDy1GcmjteXkLaNg2LM1tawj1GfM8YrLPjtHLo= X-Received: by 2002:a05:6820:200c:b0:6b7:83c5:fdf7 with SMTP id 006d021491bc7-6c5451a9095mr2847169eaf.56.1789420214324; Mon, 14 Sep 2026 14:10:14 -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 006d021491bc7-6c45bfc3fe9sm4698544eaf.15.2026.09.14.14.10.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Sep 2026 14:10:13 -0700 (PDT) From: James Hilliard Date: Mon, 14 Sep 2026 15:10:00 -0600 Subject: [PATCH v6 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: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-14-2fb084fe0751@gmail.com> References: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-0-2fb084fe0751@gmail.com> In-Reply-To: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-0-2fb084fe0751@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 42c5f782db40..8b0d0620e1d9 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 * @@ -2431,8 +2434,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); @@ -2448,6 +2457,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) @@ -2508,6 +2523,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 @@ -2578,12 +2597,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 21:10:01 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3352 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 CBAA91C4D1B for ; Mon, 14 Sep 2026 23:13:38 +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-25929-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-25929-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 1CC5460CFF7 for ; Mon, 14 Sep 2026 21:11:28 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 49BF34A0925; Mon, 14 Sep 2026 21:10:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="TT2jSE30" 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 DCD6248F848 for ; Mon, 14 Sep 2026 21:10:18 +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=1789420222; cv=none; b=cH3eMdFZ9jXCEDFwf4M/wPVx4zIoxQueuaK8ghlouoBLnxrfy8dgxcMioFM/m0y6YqwiPuQl0w97x9YPMGdaa/4WiDDCox5iA0OE8BQ8mWAl/mVJUOSCHx6daJNZfe80W4CJzS8ne04ijmfTgXCMaJB2aXVLXln/0zjchB6sKp8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789420222; c=relaxed/simple; bh=bniJ2L4Tvp9lAApOs8qjlReFeiPBCiiQVEC33ZRnv2k=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=aHvZgbyspc3zWh2m0kxgEJJoEIgclPFmXLL1SKUGVTIm41kgfXAzRjMN2VnkMhK9zTprvKabfruOseBsV9cEZgtI9YEen6deXrFAnOalzRjpXbx6AORfLyHdmeM/oquJ5AiBFaGgWrzq86GHnNxzoJ31YjWmfErcDiQvnjPL9ZU= 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=TT2jSE30; 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-6bc475ffcbfso787673eaf.2 for ; Mon, 14 Sep 2026 14:10:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789420216; x=1790025016; 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=akH24Z1lLy7buBHyV5efDWLsUp/yg44TnSGfRiXVwiM=; b=TT2jSE30zjQjmq5crvljO+HYZw2PwxDZn+X6YUqVmPokaHOjR2Zle0F7PMGA3/0Fwv VrT9wLk6s+db/cnSXEfwyDu+3lVhtTaCQrFvhCBufujjIgYIRCyIoAw3TOUGbSl2X6Bl Q1dHvV+9fyyLTjdJHvxZ9wQRleE/VQa1Awc0Sy6VxdbDAYxRUWcup6OkIXW8TZSHtY8V QkcMwD7Brwgrwa/Hbz2ceyjxOHd9nFe8WzXuZX/mx1APGNXZOyEKMmgaWZnuiF+9HrdG iyG92WyeVEXB9gIUodpHE36zknLezY9ONHRiBsO5UgpJXzyLxR6cyRISDQtsS/UnG0yc EgeQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789420216; x=1790025016; 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=akH24Z1lLy7buBHyV5efDWLsUp/yg44TnSGfRiXVwiM=; b=Iw9lnScp9tbFBvF9LHi38uTpS1tay+3jdevq3+N317AzgKHRYq2t4VJ5NC6oPXbCVZ WNLTAbWOAbaGs2AFwpe2kH4jmGnJo8y0xbTE7tYzBB2dY/S0N+k+vFXlmebNsjdDlxCV 9fLgRIyYinrJFcEjfEFPHMjiKvFRfirNIyl9/yBhu0c2SoqwMoKaP5tTrXZifBL1XiVw ZAHMUANE8IFVwAfhz8zdTeQ/RbJ8Av58kU+Mu0k0tR/CU2Di4r+INppu7nnafKeU9NI0 NtXMBqD2MxYBWy2miXQm7VXTDelU5/AuxdPWFphgO53tcQGJc/IJpiMiM3eP7CAs5kHO DUGA== X-Forwarded-Encrypted: i=1; AKwUvBwKuS1z33ppKAumw5nqCQdjOoH5p6vWGYWF9aAEO9oOcNcMr7NEriQy0xNydMDAPVruI8X1v1sGxfeuqQ==@lists.linux.dev X-Gm-Message-State: AFuF++kKAGVTijT6GA8o66Q9F/7agUMNwqyNCKosf3zkyGfRAU5h/xgF WyqibqwF5QvT7SXlR8agmMWGVwFz93KSrYdBqm4uIZ6KjvaBfN/mzPPX X-Gm-Gg: AYBFou21bEreoyW/q1nf6jINQMDUNeG0yESjIpwtnZs5wRpQM/7ZXM6LMkwzalEhpem P0ap+J//fr+8CosMjql/tBaZcZnXWUkh18iA2IcLWLXm4sQ8HjFBvkdkAPeyyOfsvBYNDqQGXwu oQwnNGDUn5hgRlQoy7i/jGQKW2M6cAgGz7vwyMePXuMPF5JWq9lfrQ0p0F6GoQLK7bB6cu5zq3u JY4n5qloIOmnIBMgC4N3ufM+NxHspXXdxhZbRATjgktWQ/HfTyt/0zpzEu+IkSdihEM6oBZFRzX t+N8np4fTWK4lGQh3JXqHl1Ijys5e6O0nHR1xK/r5PohTNeImEYOWWwVQw8tzHHh9hEz7jbOF4Z NFF1WEiw1+Fe1xDKOQkgEIQoMcSfFgQXwaCHo07KT/cu2Q4DW8cjKUu/5PJTaBI+Iy3338s/kZE jX7nUcb6R9ktMh5hzs9E52mYhiL37tUZj+Hxf6s/vVuvb7NiFsBJUebRMbQQ6CD0YGY7fCQAfA4 fZ+46NfAoErmLNswWkn4Bz7c2z/OJBZ8q9ng3vSEozAQIEzgIJu6WPDU1T2d49KQy5/amkPSP8v 34g/2ichdyh8ZBpXxt/kqEyp/1J4KCngRN/b8M3FSb0r+k5ECN7TZOGzgbrRZVG5+J6rx/6wY+q Vr3XvWJzFzn2YTBh8k3hTo9vkY9Dic6aNviIv1zA= X-Received: by 2002:a05:6820:8c5:b0:6b1:2843:1312 with SMTP id 006d021491bc7-6c53ba3546bmr2248641eaf.0.1789420215927; Mon, 14 Sep 2026 14:10:15 -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 006d021491bc7-6c45bfc3fe9sm4698544eaf.15.2026.09.14.14.10.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Sep 2026 14:10:15 -0700 (PDT) From: James Hilliard Date: Mon, 14 Sep 2026 15:10:01 -0600 Subject: [PATCH v6 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: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-15-2fb084fe0751@gmail.com> References: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-0-2fb084fe0751@gmail.com> In-Reply-To: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-0-2fb084fe0751@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 [4.34 / 15.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)[]; RCPT_COUNT_TWELVE(0.00)[20]; ARC_ALLOW(0.00)[subspace.kernel.org:s=arc-20240116:i=1]; DBL_BLOCKED_OPENRESOLVER(0.00)[sto.lore.kernel.org:rdns,sto.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)[]; FROM_HAS_DN(0.00)[]; RCVD_COUNT_FIVE(0.00)[6]; ASN(0.00)[asn:63949, ipnet:172.232.128.0/19, country:SG]; FREEMAIL_FROM(0.00)[gmail.com]; FREEMAIL_TO(0.00)[bootlin.com,nod.at,ti.com,kernel.org,gmail.com,sholland.org,socionext.com]; R_SPF_ALLOW(0.00)[+ip4:172.232.135.74:c]; 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)[]; MIME_TRACE(0.00)[0:+]; TAGGED_FROM(0.00)[bounces-25929-noreply=patchwork.local]; MID_RHS_MATCH_FROM(0.00)[]; RCVD_VIA_SMTP_AUTH(0.00)[] X-Rspamd-Queue-Id: CBAA91C4D1B 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 8b0d0620e1d9..f3234d2831ea 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -1435,14 +1435,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, @@ -1453,10 +1467,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 21:10:02 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3353 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 3C9EA1C4D1B for ; Mon, 14 Sep 2026 23:13:59 +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-25930-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-25930-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 206A960D489 for ; Mon, 14 Sep 2026 21:11:35 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id EC7114A0922; Mon, 14 Sep 2026 21:10:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="jcCAaOVM" 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 F03304A3D3C for ; Mon, 14 Sep 2026 21:10:20 +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=1789420224; cv=none; b=kwrBdOyiyCkSLz35WcTFkwOYVeDUMEPEr/iOh4R4v7TqTVNt9sJxWtGDE+1MtbyJ0c+AGUbzsfri+DDG3GgRP10QmeRz1BG51gNYT5CZOWP6dMK2C6HIBiOTuRMJOLmX//V7IAauqxIBESfZ4oHJ/8RFGbVFr2XVl6jR8dfsNW0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789420224; c=relaxed/simple; bh=ZhwsgqB5mjFiVy7QQ4USypPx8q5jZF5EM5tixdJx7b8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=UTLHH3UNmpB+VXe3R4IHSDwMFxfvdte6BRooc7q4845+XIO1nsPVDcEOEDY0C0CcFR6rpCjIpAAv0vSUHKKjJVPLEnoMtIvrDgiM++me9vk39xIUnGrOz0PGvoLtGblYXmXES4dnt81LbgVV71hr0cPN3n/z3S7c6IqLgfhD4MU= 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=jcCAaOVM; 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 006d021491bc7-6b1ae6c9b72so450449eaf.0 for ; Mon, 14 Sep 2026 14:10:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789420217; x=1790025017; 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=7XwVosOtOADwbw6wxbVAGv82uPNwv85si6C2vLS4JkM=; b=jcCAaOVM1i6zck047/3ikxVaKOxjiaZ9YaNMpizVaMZ7mPJk90q9fjWslpUUngng+1 pO0aywt+apTBllq5KvifMcFhL4g1XWGMonDd80zpmhw5bDSu3r+8LkmyO4b5B8dM4KvS iSpiX4BssE7hIUnEC4g7vdOltHBtxGvtTEpG7xNxv4l81GXVZUP4wYVD3ndf49kZlcLW hAvCozeGY9Upd02CkvcI6mXaxHfMTqPbb+mw1nRt/fBVNnv0w2062KaBIwnizmUwCoN0 ZVVd7bZeI8kWdWy2/mPhWaxex/GAVWqXyBkVU0A4fSpfRAOfnRAZFcn3Ia60C0oG4BwC CgRA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789420217; x=1790025017; 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=7XwVosOtOADwbw6wxbVAGv82uPNwv85si6C2vLS4JkM=; b=b1N6ko/uMpqXb1cPFlNrBruBKHYWZ6vDRoctqC0JMk9kBzEHZkX/n02FJgCitcb0Kw R5/uSUdRM3yToIDNZRJFGPNb2+qiD/AKp/9fdPARX+i7KpOO93L9KjP+lW79fHZsP1sE os+jTG7C2opnMRqDGrTb/TPVVkLVMypYCbFecxg4vk713Pa7rdxr737QNsF4qAZ7kAZC IrPtQr1hH7pAcslXoD14tCLU5FNtI+XBHXzhTz8iuoEYD1FcNTOT9R/4rsXt7HT787P0 mwUXqscue56ipf8j5DY5F4urDlR3HmB/YfYY4qD2HTxDz2fwz0KGF2mpT3H5H6je4lZE sOng== X-Forwarded-Encrypted: i=1; AKwUvByEbyp73QqyQMBFsaWvxN1rDuwO3ZM4jZkfApTk+3EtLD8/fmaPaVRfNhgaU2CEVK+vegj1g2mXV9+OVA==@lists.linux.dev X-Gm-Message-State: AFuF++m8DBpaGDRuzZZcmr7CrBZm1Sa7dsYx+jZuP56DrH1n0fLNdAOe 9cYfa6BRdIIsaccW9IAM1esRW1jNKQGEwEItelsLVDL1mGHRTz8B2O1B X-Gm-Gg: AYBFou3Ct4dvCX0XsMMUB4OrWzztnUlRtK39z4QJK3+OjVUaqgxJhRZXpAwLja8uLcK k0AVtkLEoxZKsSKRhrA+qeaffcKvWtJEPjG70yX7Whu7pKlJAI7ubB0gP5EhnnifMhKMCobuQtS smqWV+OVDZqnMjtDRJRKTy0OlJttLAEJLcvGUle547RS+1mLOt0MpyO1DloJbQ0UwhZNC7GCES7 kmJnd4dsKwrbDiGV54L62URdWKJ2Z2DIXz06Jg1nVpuLnDLkbsJcXRJPP8fTRHmwjBQIqLsAIcF D6MSU5pZo/crGy52y8zpITMAibmnoSabCTI2OdktCfmmtxEuBRIH4av/QPZ06jbQUgwgChrSz/d fGqW3Uy7g0ktC+1RR8dwJcODM21G4wK2GGl6ViILkJyZ8XfaW3k2lXLkhTiEorZTYvMMVrqf7qv KH4OuMf3NUulOQWIkkCUjUxFuvRKbSjX3WZosTDQhZXFxqkPjO9spfcZrFg4nYi3Rd2Ah+M90z4 30w+o2kXm+MaCxbCR+azjNU7mnti0mi7uX+q0W5fuQVSrv0RqMpWhD1TdLpy4DI4FZ8wpOHd+u8 cHKJuto9e2sjx4jVxX7/kmWb1k3MuIVAWTEioFeu+valG6sGNu9L2hoqVBz6OqF2RighBXiUNOI UD/jEt6fXinTLL44Uf9Fth4ctVOQg X-Received: by 2002:a05:6820:1890:b0:6b5:ec3f:497b with SMTP id 006d021491bc7-6c639498c9bmr552266eaf.22.1789420217054; Mon, 14 Sep 2026 14:10:17 -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 006d021491bc7-6c45bfc3fe9sm4698544eaf.15.2026.09.14.14.10.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Sep 2026 14:10:16 -0700 (PDT) From: James Hilliard Date: Mon, 14 Sep 2026 15:10:02 -0600 Subject: [PATCH v6 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: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-16-2fb084fe0751@gmail.com> References: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-0-2fb084fe0751@gmail.com> In-Reply-To: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-0-2fb084fe0751@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 f3234d2831ea..773ba55ecc07 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -1808,8 +1808,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; @@ -1858,8 +1856,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; @@ -1888,8 +1884,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; @@ -1930,8 +1924,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; @@ -1955,8 +1947,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; @@ -2000,8 +1990,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 21:10:03 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3358 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 B274D1C4D1B for ; Mon, 14 Sep 2026 23:18:19 +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-25932-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-25932-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 65BB337777 for ; Mon, 14 Sep 2026 21:11:48 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 755BD4A4851; Mon, 14 Sep 2026 21:10:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="jJDRT7DL" 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 0B5634A3F1C for ; Mon, 14 Sep 2026 21:10:23 +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=1789420231; cv=none; b=WYWV4gn13p05VgNnZhN0EwjH4q3cNH+6JkN0XyaWPvCWIVnFyrbgO7k92SRDMZteIaAuEjkAQGx1FSA7Vahi2YO4mDspzcRHuSsdfjF19UDjCLymiCNRvOjTGsQWkNyYbkMlXT4aqkNT8uuDpA1UNhknHcNNIpyCHQGy3x4EkLs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789420231; c=relaxed/simple; bh=Izml/kmhnoiBi2LFA6kerFQHV26tFgrWjsTUcd1Th10=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=b6mdVKHRcH7P7Y2gjc1cMk3MCPb0+RVsCDB0x/mH13B22FSj7QHZ6fQJmBS6xOMdGZAx3sJ4eTVC2zA233tbOhYsfgegN4EFVG2V19TIGN/kg4CGgBC2NFTBmKaE67ejFqafLBGRgIhRuT2X1j531iJFEJ6WD8vmzEFCa7Di4xw= 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=jJDRT7DL; 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-46ac6e5d8f7so1446988fac.1 for ; Mon, 14 Sep 2026 14:10:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789420218; x=1790025018; 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=+GbSlDHSjNPM9B5dSRFNO0YLnNdNTULtbcSEuiC7wJc=; b=jJDRT7DLUvr1F3HjhL0PVHL4ETRWc7MbuXEXpxfBDqG0Asy1dtw2IeaRxNxkjAdnzU yw1FzboOcDIKJbFvefWNZb43J51IXFFK0ar6kenD+PFBPb02LM3OHKxqR3+8l0opK5fY ir/mRUdT7srxFZxZPxLs8/YabVU5CoXzRBtIqelnSH+CfK7Z6cWuqkUOZkDtjvd721Pi tKcJFoaH/xe5CPGgbDmVA6z2hC/sSdcMdoCsaauzCz83aZ2/uBPBuZzVSyLsbykMfdjc vvEB3/PLjGTFZWWJkt6gr+5gbvFeFvqSi8LJYFhfUc7ZyaCLdSFPP9Zxsf7zqeYLzIqx fWUg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789420218; x=1790025018; 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=+GbSlDHSjNPM9B5dSRFNO0YLnNdNTULtbcSEuiC7wJc=; b=mGKENjsEucxULx0CRecfeGQE646tbFlofBnKObdEDe2UMhCfzdSrzZsbEJgfVPUjNS 0bUp58PJunBxT6YsDV8BBynTWa+vYezVupl5MVwxjGCW/eNH77Y0ztAcgn7RYfuPEVW0 QbRNUb4hbLrdeZFDVYmhFakOlpBZnP+srDpZBeX9/Yws6Axx/ZW9Iil4OoZ2tJxB18wR enTiHXLEmKOWlezyubVTRISPkqCWCOeaIPNZBxrYNgYr3lMRc1gmF/qABZy5YcwtY8Oh 0lKiVmbv9uIVnhK01XXyZoEEweJNrTEpf9fVf3X6Z6RSKIjW0xx408pvndkYvLHacPxi fVqw== X-Forwarded-Encrypted: i=1; AKwUvByn9t4TzbqEqeJcTtqgvVQ1koQ1u57WJLw5IcSlEys4utwNa5Sep1/YxkUl/6TJPAtiSzFTsXN1158SqQ==@lists.linux.dev X-Gm-Message-State: AFuF++kWz6t444eGp/ykGjSYNjbXWPRFT2+BXlYjofeHCz9d2Zu48OAi YYavYzdew2pYmB4qr++BUKbhib01wE7gQYy2lqJavWh4Ic+luu0DBzY421crnw== X-Gm-Gg: AYBFou1WalZKbsYcbpPxqvyL3vNxLDRHpHcsxXndJs9iusPo5+Dx4TkUFHr/gDBIKRL ThdjdsqfPULNsOr4yfJF5N2kCNWej1gvVacbWnAiU/VOY92fqKG+3dyI/63JxNkSZ+YRt8B3yV0 upK90ruhmHFl7DUZMaA5VFDLw0iCsx7t2iBH3tJ+wJAYOJBF9HMP/FRKNw3zIpiaMy7fla7W5qz qMZzVbuS3KS5jL9OycFVICUqoLHfruN2WUDvMzXCH48WNXgSuLZbqVNjznjt0K9VwN13oYueNeT qnazGGBJ+3FpW10ipnXiWmjht+4MiPvEy8eg50Y/mSlAbi2mSQBwfIC6+pM/E8011OxCQJi4hXg sUduD9FHtDoEYMZcQcXWbOwbmKNOmlcZ58YyYr6KNZzExLVlAjgrj+hrHi4WdE1eECdG2qLlQtc d12C/Hh13Px1pU+IeoQU/8VTqlPXpDSKkPYHQ9iK0GxRM1Tue5KFzoPKqH7tViH6LQRVnU/NzUN udQiGf277R21INhKZwq9JL3r2ftmWuZDEHLIbi82bXtT/CHSkRuVafNP4lA0E5teBIJVjiMAs97 RFNWSoJ5grDa+Z+q1qPJlz7DlAdzgkXRJn0GOCgH1iawjcVSunhJxTIYD0WrrOSqAVKyhC9x1MT fjVUPJ0YXF3wdVjgiZskb8viTmfiQ X-Received: by 2002:a05:6820:1893:b0:6b7:8396:f3e3 with SMTP id 006d021491bc7-6c542249981mr2544577eaf.69.1789420218531; Mon, 14 Sep 2026 14:10:18 -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 006d021491bc7-6c45bfc3fe9sm4698544eaf.15.2026.09.14.14.10.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Sep 2026 14:10:18 -0700 (PDT) From: James Hilliard Date: Mon, 14 Sep 2026 15:10:03 -0600 Subject: [PATCH v6 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: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-17-2fb084fe0751@gmail.com> References: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-0-2fb084fe0751@gmail.com> In-Reply-To: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-0-2fb084fe0751@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 773ba55ecc07..41d6ef31ea3d 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -1013,35 +1013,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, @@ -1237,7 +1262,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, @@ -1554,10 +1579,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), @@ -1747,7 +1769,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); @@ -2051,7 +2073,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); @@ -2059,7 +2081,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 21:10:04 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3354 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 5D6181C4D1F for ; Mon, 14 Sep 2026 23:14:41 +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-25931-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-25931-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 2A3AD60DE22 for ; Mon, 14 Sep 2026 21:11:48 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 4FBF84A4840; Mon, 14 Sep 2026 21:10:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="cSZ96GYS" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-oo1-f49.google.com (mail-oo1-f49.google.com [209.85.161.49]) (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 34EA54A33E3 for ; Mon, 14 Sep 2026 21:10:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.161.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789420230; cv=none; b=Ax6VjYYYBbHlzjQuZq73+1T4MzRQmV8xP7B5Ksf++yGWM/Q1eFIKMjdOeNc7X9xpNrpnRdjnLnm4du2syGZV/g4j0SIgExtf6h3uxn1VEfEbxRfShITczYebN0sxz/V7x/+lyqCuMBODOVIfleoNO0aBPrs5yo+cphJH7Fvos9c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789420230; c=relaxed/simple; bh=4xHXBQvwmVz0oonK9wMD8Zxqf2blrn3tsTPZp69gKzE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZJl+w3yJugTT6pmcHc2dtLndtUe57qwK+jN8cvo9c4RsdZ3OLiSbKExs25WajrRS3Ri+ziFYDixPrZ/KdCokKn54NEw2Pid4vI4opGB+qOfwj2I5Fkr3waTfrLCe1G+pEo9ij5uMJb2Rr1wthLDPW95VeNMIKE40Oc2WvwtnyXM= 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=cSZ96GYS; arc=none smtp.client-ip=209.85.161.49 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-oo1-f49.google.com with SMTP id 006d021491bc7-6c20a9c464fso2484153eaf.0 for ; Mon, 14 Sep 2026 14:10:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789420220; x=1790025020; 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=eqAKP8KvklWhrAanMl0NJZL0/+j+O7CDNjnmlHeKJxw=; b=cSZ96GYSvZ4+cmd0NLVdsaDBhc4hM9Z9favESrDPaEEV46rZULhqWRNn0jexoDBR7D uaQg0e+E8UeIY/0fc0yOzPFn1x1cJPRaI/fqf5Ong/RLQdfWdun7DNcbDt8mrOcYOodV DqsxMDHnxcHwZtuICiRU9YgahfAxiBk35XZCt5yT3gF8Lsj9XxKf4YC2DvtqfTwSvSVB hUMBDMMDwyRfbloksenB1noc/BenS+rz/jANgh087MIyilN1028u2Prm5tfv00+fRlQA ysm1Dwzp8/5AYAA5+nHEVL3ozgf+X40a7eHSpLB3l9EL/AAFs7Rrdes2eM1cmDKgXX9P xlRQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789420220; x=1790025020; 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=eqAKP8KvklWhrAanMl0NJZL0/+j+O7CDNjnmlHeKJxw=; b=Ctlrlqh92UtIFC0AKX4t10m+BkfY5muc4qKsxTG+SiS4W+5KLTYNmuyVviRc8+u0YR FsOlRhSEUMKQW80c+diBXkBh/I4VmHzdFM4HfTV6clcu0Mo+wza1wjRamuEdvgYINpbq lj9WkYVVuLXnsMBiXCLwr3trXkbMZcggSFGt/YTnf09C1u8F/U6d3a+2NZsxJyPuWtVX Wgmdo/M5tWjx3S1sP06E6j+yiaerre6p+wGieXlODAJhKQoK4zpLExmd22ulpx0YOofF ysZRRQnfnotqmOZyXAHz9Wu8xxgZCkjn2VItZ36JK8J+QVKE03qMynMDkE9AmoHwqpEs 9lvA== X-Forwarded-Encrypted: i=1; AKwUvBxI01ktg5Mac0SlnjXkRjOQvqv5MkegAmQLxPxX/Kb280RG394GuqWdpsFUP5A4SLkkdPm//y7MmfWLCw==@lists.linux.dev X-Gm-Message-State: AFuF++kFL+6PcvOUj5YRcYqhVGqVAjduqrm7JBXGniZr+XD86tZbSTtS l97/p7MkBwjPtNZrH5pW8CUeaDbeuBWA5TT/cJpeZYlU7j/ifo4/cJ4h X-Gm-Gg: AYBFou2wHclAjfNET4zeO3/naF9SEkLAwtmEz0Fx5rHij1YOIjQ29w1fZOQM6YbGzxY BmIRvRROSX+5D+t23B0fCH4RV044c/Wrelt2iovpgkORAHPAwUFhHAKyDfYDSIQE/COH+PtSL3B NMY7eiCSY8AzNPbHvP4x3x0zonCWOwndGLZkvht7mulzHrSrFeXseF8K/0MYbn01fG9aFJxLYyD llsF0aUqSQcuipwnLaZeLqYkMscMJZWFrj6vBr5Wc9Jo9NiY/OCm+Y/en89IWyG0s6D0ZgwT9wm j6wDG9KsWA9AR/WzJPiKPNYDrMVGN30u6wOlsyQeyqNFGG+O9j/+bDeB8X8MIC6zHHGaBXnvNY1 h7gTV0gIT89KcPEdsB4XK+szV0CvEySMIVnp9EQS2jlv2/HA/Zd0FVUStMThRN3QJK0s7J71HOf 5TBnxVCMkIeL86v6eU559D0zxN9sCMT5y9f4c9eftvLQsXAA6NkajwvdkqNgfz/LnyWRMhLIv8Q UkLO88pfsj+VNgD2HWc9G2Ht2dmSvjiPhIj+0KoSMnZIw23XkHLG6Zditc+nJG3Z3yFFsxQFjPI BI8yY1Xy+AnJs17UpDg8gxfMHxGhfxybvCBZuZUd9/B7mJcwj3PWHnqWqgpKAOVwEPWSDfiDbks Tvx7K3yGJ8iPmg8/wSz3y7eTV+dU/ X-Received: by 2002:a05:6820:1628:b0:6b8:ef7d:e181 with SMTP id 006d021491bc7-6c544daaf8cmr2777294eaf.54.1789420219820; Mon, 14 Sep 2026 14:10:19 -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 006d021491bc7-6c45bfc3fe9sm4698544eaf.15.2026.09.14.14.10.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Sep 2026 14:10:19 -0700 (PDT) From: James Hilliard Date: Mon, 14 Sep 2026 15:10:04 -0600 Subject: [PATCH v6 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: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-18-2fb084fe0751@gmail.com> References: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-0-2fb084fe0751@gmail.com> In-Reply-To: <20260914-submit-sunxi-nand-vendor-oob-layout-v1-v6-0-2fb084fe0751@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 | 103 +++++++++++++++++++++++++------------- 1 file changed, 69 insertions(+), 34 deletions(-) diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index 41d6ef31ea3d..b79bf13f3ff0 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -1157,16 +1157,60 @@ 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); /* @@ -1174,35 +1218,32 @@ static void sunxi_nfc_hw_ecc_record_status(struct nand_chip *nand, * Classify these steps with the vendor page check too, and do not use * their correction counters. Keep their decoded data until then. */ - if ((status & NFC_ECC_ERR(hw_step)) || - (pattern_found & BIT(hw_step))) { + if ((snapshot->status & NFC_ECC_ERR(hw_step)) || + (snapshot->pattern_found & BIT(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; @@ -1218,9 +1259,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, @@ -1235,7 +1274,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; @@ -1275,13 +1314,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); @@ -1289,8 +1326,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; @@ -1555,11 +1591,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, @@ -1612,9 +1649,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; @@ -1628,8 +1663,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; @@ -1637,7 +1672,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. */ @@ -1664,7 +1699,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; @@ -1672,7 +1707,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);