From patchwork Sun Sep 13 04:04: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: 3291 Return-Path: X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from sea.lore.kernel.org (sea.lore.kernel.org [172.234.253.10]) by mxe881.netcup.net (Postfix) with ESMTPS id 465DD1C2CE8 for ; Sun, 13 Sep 2026 06:06:12 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=gmail.com; spf=pass (sender IP is 172.234.253.10) smtp.mailfrom=linux-sunxi+bounces-25841-noreply=patchwork.local@lists.linux.dev smtp.helo=sea.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 172.234.253.10 as permitted sender) client-ip=172.234.253.10; envelope-from=linux-sunxi+bounces-25841-noreply=patchwork.local@lists.linux.dev; helo=sea.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by sea.lore.kernel.org (Postfix) with ESMTP id 36A18379DA for ; Sun, 13 Sep 2026 04:05:15 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 18FF738B7CD; Sun, 13 Sep 2026 04:05:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="ijUK/Amj" 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 DEBB038332F for ; Sun, 13 Sep 2026 04:05:09 +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=1789272314; cv=none; b=TnI8b1MPFh7ZGeuq2Szpj16BsQby5uzG6FxxCrCrGhwNKkiKJIgmSN2taUBK0k8bAkYPPzbO89gulQUWml0rvovkNyl9Fq4acokAxdwkZp3LyV1uxpy83J8o6rUlBz9rV0UpxEeCx9oUy3cfdDtPH2JS2CLWu+BeXqCuU4jOurs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789272314; c=relaxed/simple; bh=Lpu8BYiYZNteYXFlDSxlBr4C2CnU/Gx0SiTFgcn6nP0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=sfdBZb6xpdELgP30Aib4P36qPofrzGKhiXInyF0S4vhT4hNEiG6rn8T4bT1j6L5nbrcoYI2Jqo5OIqHc4QKuRMezxb60FBjxIfDoL/ZcYRE7N2L8ADCC+DOPRopwTJsSsQIQmCBRtbCuAQy4qPzr5o1J7zWWmf85NCSApDu7h0Q= 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=ijUK/Amj; 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-469fdb78b1cso627073fac.0 for ; Sat, 12 Sep 2026 21:05:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789272309; x=1789877109; 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=ijUK/AmjH0hdfiz5d0adzvuKGsYTwoaruZD3Tt10ozsUqtKngf1pi5l8Hfa9a3XN5s kxX0V5C88K7YKFEmcj7Mn+Zz6+R9+eEPVi4DQvapoHPsmaK0+4/76Z63jLUjnnwRbCXU U41z9aOEMdxFh+UOtNuuDefVQBg6jN8v8EJOqUAw0GkBKaf84Bz4I+fKOpX1W6fw/8L+ Lyjaal7QyM9vUd2XL0Kr57bBG6G42ALd0u15ogohgraWv+LriT9tIYL+GNMzG6ZzRvID DgbDwaI1miMY5LOsVr+Xus0b+H2wdkrg8LEZHSDQcbmMI58Hb8orND4JvS+YNVvUP8XR f17A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789272309; x=1789877109; 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=JyL7FXFfqNb+Eozl6STur0869tJxoHDzvNnBFLM01objrKJrPJoAP5ckyqxP/JgS4h 47tFj/1msKSdlQmNU7hc4N6CxQzfBgt4yHw769dP6KEOJBzoEGn2O8KSauhU1GB7tci5 +/NK8TM+XSTcZAaVJp4lHZJCJBXzwulb349IC5pitgewdcmxhzV2lZ8eOuzssdHHGSES e6plRxmSCgXhYM0XWngPHkO5RjdFNMLRnKT1XCE0uaEpFYWBBBKDYW6WA4qfzlkEhemY uBcrJHuYF8eGHk0JGlc/F6mg7chOi25V0/azdBvnqfPNjWPQm9xKkOtLePzr+hpZedx3 zQww== X-Forwarded-Encrypted: i=1; AKwUvBwRv+70bNsX671vZAtjv4DFiqMexfZDgYNYKVAcNBBvqyA5e/UiisDHiucKzL7inE0lT87kVLv/4XH3YQ==@lists.linux.dev X-Gm-Message-State: AFuF++n5iwhAiHjDFEGlj/R3Pkd6piWi3Q5PIxzCbRaeH7PJ/15TxW4U 3hfA+IWqTUszdeZZOE61IB0gbkU23MI6FAGmDWlylXvTK8ic8FHJd11p X-Gm-Gg: AYBFou2sc3AUmFkqzQZta9eqYBosfbzd0nRWfS6t7bbwAKHCMUKHBV7Nh/P3b4CWcYH Yzlfnr1QPKaQmC124Yx/mvmaN3m5/q+u5CyV1ZW+dXXTqNUlR3AkuLHMD8+wRfncSM8ePNLN0pJ Q/mKcZH6w1siEcs+09udJgsCbqST9n+GAicxynjm0PPymw8aRGbSXo/ObwaIdAZoP9AN6fOl7i8 zMJ4dKpZ9okT3Y9f8FhLFKjxF4zUC7WEKYR8egWtn3YsjOZSZQ8xmgipjT4fR4QCfOll5XVIQow 3wF+8bAwnV9OI475Px/mf2tj/6/zoxymCXtYj9n4aTpiUOFnVRQ6lldnelo4YwYbTEkCFmcmYcU g866Sudo2T8vE/VHCL0UNzrr4Kp+3/GuHTRJEtN1agSlmNgN6yB7q4BBlatKiPfQEBRvkLmSwR6 gDeDVcy55o72a7aDqKWRQsNd1td0iJvqkgmfcqMCkk92VjJNgAazLo9Zsd7T0uXAtjidpFOz8bY cD4PQLKtbNXjvmRWIoEbCaWCE4V+fbtzCoY6XHLvcwTjZYbYGY2yhLFpG7UeGSIgdk7ZOSJiWAd a25ungYm58t76Fz2B7y+xBtqf0RPCZqcBmEilHivixzb5gf0+C7qpIYAibm666BPHPNkZt4v4kt sagJsewV7Fr3PLHMihr37D4lt9RQuTg== X-Received: by 2002:a4a:e90a:0:b0:6be:8d11:a077 with SMTP id 006d021491bc7-6c24f2660eemr2474010eaf.67.1789272308682; Sat, 12 Sep 2026 21:05:08 -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 586e51a60fabf-47df8699647sm6011535fac.5.2026.09.12.21.05.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Sep 2026 21:05:08 -0700 (PDT) From: James Hilliard Date: Sat, 12 Sep 2026 22:04:52 -0600 Subject: [PATCH v4 01/17] 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: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-1-4a64bed94229@gmail.com> References: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-0-4a64bed94229@gmail.com> In-Reply-To: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-0-4a64bed94229@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.234.253.10: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)[]; RCPT_COUNT_TWELVE(0.00)[21]; FROM_HAS_DN(0.00)[]; FORGED_SENDER_MAILLIST(0.00)[]; ARC_ALLOW(0.00)[subspace.kernel.org:s=arc-20240116:i=1]; FREEMAIL_CC(0.00)[lists.infradead.org,vger.kernel.org,lists.linux.dev,gmail.com]; PRECEDENCE_BULK(0.00)[]; TAGGED_RCPT(0.00)[dt]; RCVD_COUNT_FIVE(0.00)[6]; ASN(0.00)[asn:63949, ipnet:172.234.224.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.234.253.10: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-25841-noreply=patchwork.local]; MID_RHS_MATCH_FROM(0.00)[]; RCVD_VIA_SMTP_AUTH(0.00)[] X-Rspamd-Queue-Id: 465DD1C2CE8 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 Sun Sep 13 04:04: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: 3289 Return-Path: X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from sea.lore.kernel.org (sea.lore.kernel.org [172.234.253.10]) by mxe881.netcup.net (Postfix) with ESMTPS id 63DE41C2CE8 for ; Sun, 13 Sep 2026 06:05:43 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=gmail.com; spf=pass (sender IP is 172.234.253.10) smtp.mailfrom=linux-sunxi+bounces-25840-noreply=patchwork.local@lists.linux.dev smtp.helo=sea.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 172.234.253.10 as permitted sender) client-ip=172.234.253.10; envelope-from=linux-sunxi+bounces-25840-noreply=patchwork.local@lists.linux.dev; helo=sea.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by sea.lore.kernel.org (Postfix) with ESMTP id 7D34736FCD for ; Sun, 13 Sep 2026 04:05:13 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 0CEBC38BF89; Sun, 13 Sep 2026 04:05:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="IKS8xEI/" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-oi2-f13.google.com (mail-oi2-f13.google.com [74.125.231.205]) (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 478E9384CDF for ; Sun, 13 Sep 2026 04:05:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.231.205 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789272312; cv=none; b=mY0aAXkpsCYceUQb8mCgIeN1T1cQGFhMVOKycsVU94x0wfBxUMqI4OGyW/ZHWrnViIDyZAwBymCL1i+SXyzsiiZuFkBCd0FC7DjW1w6djkBimPou/4qrMCeaIcaj3Efr0QnErlCy8yLTPGzlakhVabTBSqktr6B+hHR4cnlxsp4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789272312; c=relaxed/simple; bh=pCshx7KzarhNGja6hjwZgV+xF1fwWKykuklNPxmL+JQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=t6W32pe1AF3FkveH2DPQwPha195bvdwcSPEvlQsnQ/vKalmBu1Oqk2fHSVgNB/MApdevwDsM22xNkVbdQ5WYR8K2AqYrh1sw8YIgFPXY7/1o8wMaKWexTusHgPtvKsLvzLva66bmY5GPCXmp8OI9TIGw/f0juWUI/Rhkh/t7DT0= 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=IKS8xEI/; arc=none smtp.client-ip=74.125.231.205 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-oi2-f13.google.com with SMTP id 5614622812f47-4c13f2685f2so717220b6e.1 for ; Sat, 12 Sep 2026 21:05:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789272310; x=1789877110; 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=2jxU2MaLD6ynlliV/V4nmXeQrG06Mf6j7bRrOAd0XuY=; b=IKS8xEI/TH6Sbh4fRLik0It5kORiIPhxYsuoGnC3br/Kf7P3B2l5HGLS+LODTjL7VR tlFjRN0y7PYlLtmA47cHab1f9r7DQtL3gV5Fr8ouu3efKd0g55MNacTavuTCCPOL0pkG 4x4dOMyLfCCMxldi9/M7S7PSIQmXxR9L/wKFhqQ4vrEEN1ffRwWeP46ZWpvRTgjdiH1j mjIKNKc6Os/SToimIsZgbVqfbn650sFZ8XRdvZgXCxgXyyA2ubI/TfEZklRf4zFwaPrN o5J5KzigoqEIT2LtpWZ+Vn8INyETRM12fv1qH86rU89BkX7Oou9PMTx49JbRqSWJtp3g vFOw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789272310; x=1789877110; 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=2jxU2MaLD6ynlliV/V4nmXeQrG06Mf6j7bRrOAd0XuY=; b=re4EFjHWRDY1/w2dKJIqn3kNnIaGkxWR0h8woQPfpBmAWSY0Z8A1uT++KdPLj0hYmJ 19IaPUIhmWszmrflxYTUhlB9E1zca1OZw6qFqaIDKEbgnAHV5WFVxEVDeWedpIMDsQJ+ 1nUriZcW5khJ7cRh28YwSjtpCu4YS7hEnJWCY4PZ9zctlAcWTdS/j/pzLOsOXYvBNmvu tK+7kkjNA2ihS/nbcrQttGN7Z6S5CQy3bktGrqV3g0lBIH4tPuJ6EwSmAWv+0U7R8qgN gc+EWG/rGc6bnOfG8p+JCorHMJA0I8m8cAqzk7Ch+ZAs4kLuvyV/AewNhORc6CmUgGpQ 8Ixg== X-Forwarded-Encrypted: i=1; AKwUvBzhGFlycePLpwMcaqVOVt1Ntjh2rPPHbCLgND7at4SE8KnSyzzm0m+FugvGvoKZPBREf52SihXGvjYp/w==@lists.linux.dev X-Gm-Message-State: AFuF++myBGif436rrCsGXiQ51oOFlONXZgjEMIwx+tndvXV/udk8iAjq n80eo7zTzfTpL7k2jtdokuo2W3r0KTFJc0RqHtbGqbR6FqW6B4XFiV7a X-Gm-Gg: AYBFou2sj/wLVxTcupGHRU4PLVaEyInyPkmDg3xW1FJYAz5zj5ErNAbtjv47rsbBxnJ z68hmqCb2kNDOgFXuVs18PIkzJn/yE/VIx9RzWfT1/g2TbibGBtNfJRrqGBXy1ZlGqNC6yWyg49 ah7DWkVaEe6wjgUBZTIzdQph2RZfDX/0LWSkp75aEWhgyfVeGF05HptImuoupP8+Mdt7gs0qgKl NPn7MsfOY1jUIoc2FuAKdIkPN9HJoETD7B0OT3yJUklULBEtIMgKDIasuud6wkukdXtCIx9EIrE L4CMc4LBDpA1OvCi0j4J1UX9uQjT7Ax76X7KgteyP/u2wj6AAA8Me63KB67ZhXn2eXXFrj1VFvg SPorF/4xZ2Ybo3fcZQeEsBoxyRoK/PXDqnJQ2vFuBieJOeaxZ/Hpcb6ZY17OR3xOg+fRTSn6+Cl IePE8UFyItcGooHIo6ivOZgPo+J0AaNYNqyvK2Z4DsflKw0QqbZkDG+sn1un5AzoIFDY3hd5KP2 Qqm5riP8OTyql2T7IyAS4LP4nAVw7oE4IDpR+kvKTjrluZcP1zaxrrgsc5OufkUvB4XkUrkRo2W ZC15jgdEWlgEz8XeY4LGOdRyEi0hYpGpFsPYH1aAqK61G2pQlKsQy97SeVliWFe77M3ZI4LfwmT YtotwUOtD3Xw9JHQ4myOfIy3q0CjvxQ== X-Received: by 2002:a05:6808:13cc:b0:4b9:a8ac:489 with SMTP id 5614622812f47-4c31c8306c5mr7319934b6e.39.1789272310145; Sat, 12 Sep 2026 21:05: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 586e51a60fabf-47df8699647sm6011535fac.5.2026.09.12.21.05.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Sep 2026 21:05:09 -0700 (PDT) From: James Hilliard Date: Sat, 12 Sep 2026 22:04:53 -0600 Subject: [PATCH v4 02/17] 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: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-2-4a64bed94229@gmail.com> References: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-0-4a64bed94229@gmail.com> In-Reply-To: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-0-4a64bed94229@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.234.253.10: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)[]; FROM_HAS_DN(0.00)[]; RCVD_COUNT_FIVE(0.00)[6]; PRECEDENCE_BULK(0.00)[]; TAGGED_RCPT(0.00)[dt]; FREEMAIL_CC(0.00)[lists.infradead.org,vger.kernel.org,lists.linux.dev,gmail.com]; RCPT_COUNT_TWELVE(0.00)[20]; FORGED_SENDER_MAILLIST(0.00)[]; FROM_NEQ_ENVFROM(0.00)[jameshilliard1@gmail.com,linux-sunxi@lists.linux.dev]; TAGGED_FROM(0.00)[bounces-25840-noreply=patchwork.local]; R_SPF_ALLOW(0.00)[+ip4:172.234.253.10]; 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.234.224.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: 63DE41C2CE8 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") 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 Sun Sep 13 04:04: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: 3292 Return-Path: X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from sea.lore.kernel.org (sea.lore.kernel.org [172.234.253.10]) by mxe881.netcup.net (Postfix) with ESMTPS id B69721C1EF8 for ; Sun, 13 Sep 2026 06:06:22 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=gmail.com; spf=pass (sender IP is 172.234.253.10) smtp.mailfrom=linux-sunxi+bounces-25842-noreply=patchwork.local@lists.linux.dev smtp.helo=sea.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 172.234.253.10 as permitted sender) client-ip=172.234.253.10; envelope-from=linux-sunxi+bounces-25842-noreply=patchwork.local@lists.linux.dev; helo=sea.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by sea.lore.kernel.org (Postfix) with ESMTP id BB14936635 for ; Sun, 13 Sep 2026 04:05:15 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 9864838BF89; Sun, 13 Sep 2026 04:05:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="X8z4toZ8" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-oi2-f13.google.com (mail-oi2-f13.google.com [74.125.231.205]) (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 67F9C38737E for ; Sun, 13 Sep 2026 04:05:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.231.205 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789272314; cv=none; b=F+wyfx63x2DH5zvcuf1+VP+kWYiHuYROIPbofPXKLyoB8tzpP5vAmCFkijAk0Yx4kN0IjY+x4YiVKBjDB5ZCrKvs2+I39CvI6OFxa8j4KKO9AnaF9jwyamv9LLIMXqA7/GLuGXHrxbm42VPd7kCBcD6pCY9dhdT6U9TQxkH/dU4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789272314; c=relaxed/simple; bh=1ofTSNVZqDsQSHKXpbBSZfkmR0m9OTYZB1KI3A7Jry8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Yjf4YdsGxFWngFsQVufIocD5jeCo5tbrUJABgQ4vTKLgPEYWMDrEvJx6oRZ+n+MK0AwzgDGig3jcQW97Bcw6ZWJgdvsqNCVztQlds30egqwv7Zn2gg+SH/k7IgikRjIBImusF1SqOxX8DERs6U15pnCrwPHA/bk4Y70DyehTXho= 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=X8z4toZ8; arc=none smtp.client-ip=74.125.231.205 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-oi2-f13.google.com with SMTP id 5614622812f47-4bb359e6878so230455b6e.0 for ; Sat, 12 Sep 2026 21:05:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789272311; x=1789877111; 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=hXoUvOv6OG+lMdZt6DQEcnmCosxaVhf33Z8ty81lQ6w=; b=X8z4toZ8cm0XmUEljDUKTCuehxSZz8P4GlqKSBuNUjOE2WglB2MIMVmsqHtiSVFI6b yWdirnj94gBv1kBLcC6dFuO8AZdiagBlHSbee4Fl/07LH1yLVj8ATmxyuLMAfJvxGk1x yeDvC3I5iWL3jzU0B35nMd1CSWKVr+HIY2Swu31bb4SQIQwTkEGrTtJRK0m9+dKMYh/C P15/Kse3CJXglEsNWdjbKsyhiBYTeP69+DD5gEKz24nPGBxipDQKFXrflHpxBUZQlZyF E5TBbAbT8nAFAuf3ewC+Wxnz9vnpzn8SOzS7HT2VJQnBmcieaOEDMFHwiCYPGdgGue2C BY+A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789272311; x=1789877111; 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=hXoUvOv6OG+lMdZt6DQEcnmCosxaVhf33Z8ty81lQ6w=; b=nc3vqEwAECqFMCDN0cLM64rFJQ2ZCXTHA97dhDMcCr6t55JMRxNNisDw3GM0s/qELp 6vXYY9MFSGKIrdX3mM6axcLQ/FNfu4SjYQUIYPU2mK4Euctcs2DE39CD4Fog/pNkkXV0 v9j6QMaqjsuqXZmOLlrg5pANro2q7OiGi7UmLbeguab2mc4ALtCEUVVdcy4VBO8gVT+b ql0rLBYyyqtiAFZHLgdYoqDeWT35+82lbXPKqjeNFyRTJwr86Aoe4hZj6KL7MJ5msrde gNDjVgzGUSVzqHDf6ep0gV0UnVZYqd00TMNh5lJZGx04XySrt5pvsCgt14+GuGBwwhmf veKg== X-Forwarded-Encrypted: i=1; AKwUvBxxatvl3BfT0n4WUaOu3vYbFZtAIuNtvn5PxLTegWdwRfRDHoA1KhmYpgwkKjdY+Qpawh0DRiraNvkakQ==@lists.linux.dev X-Gm-Message-State: AFuF++kMBXTeM7vX2vPs34NE4QHY/81AUXEj0yWDkeuxd7GIaXtyhoTT 3A1ms5Kv8/dR+wnkQtx2rZ4OuTkjpN7Fg0+ZwcuTGImZcyaOiSEhYLWb X-Gm-Gg: AYBFou0VR/I3mlw8Xh1UaoVG7VZ0X0yzMzUw+HVkywMoK0bk8p+WaiRM3i8brSfW1oz qKJZxmcUyBR/rYo0VzzCbQT5CizrMYtIKTWfzmj/Gkn2AXmreY41yITxqQGjBIWU9oZJMzUUngB Z7lGdPzxRJUIW7YhbxjR4CnWeq75AaxSmu468elp87035Nwa9B0Yxnory1FneKVS9zQKPAzkVqZ z7I+cyiYEFqnNSe43dta4PNz99LIrstheEeUPpfzEc72+24ekpcJTn8xQGnLrpjieBANnq+jqsQ fzsSIKzeBo9icq9EvG9v7RYt3NNfMytqiO3dSqYo5vPWjaqY4qXHfXBk17KYUWYdoDABy/7GfAJ FJDK0COudX0qydDGyJhXxVU9d1uFHwqsoiYH79a6402xbsnCypchpcQPsVZH6qv3Cfmt/QyESna C063mKpzIhTlCs3oLjaW+IpYMkqbwehMx5ktYiPJ6qLHWECK8UGPyk/Gl25dcDOsXCl+yilL5OQ OW/CjrGqKhpmEfrzEsTtykagQMYIHmuZr8f5bzZiv46BPThQese2NTYEVkLN+30zhMEgDURo7NQ 9ey8Q6GRGTiLnVmBFgNAs1jpeidAuSQi2f/p3bZfsUHOwFUu6htCarZLRm2kTAGo8tlhHRrehZT lcoXwu19N7hzRQsZJLBhHtHZ331kE6Q== X-Received: by 2002:a05:6808:13c2:b0:4c3:bc5a:def with SMTP id 5614622812f47-4c4a7a390f8mr3678679b6e.6.1789272311396; Sat, 12 Sep 2026 21:05: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 586e51a60fabf-47df8699647sm6011535fac.5.2026.09.12.21.05.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Sep 2026 21:05:11 -0700 (PDT) From: James Hilliard Date: Sat, 12 Sep 2026 22:04:54 -0600 Subject: [PATCH v4 03/17] 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: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-3-4a64bed94229@gmail.com> References: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-0-4a64bed94229@gmail.com> In-Reply-To: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-0-4a64bed94229@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.234.253.10: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)[]; FREEMAIL_CC(0.00)[lists.infradead.org,vger.kernel.org,lists.linux.dev,gmail.com]; FORGED_SENDER_MAILLIST(0.00)[]; RCPT_COUNT_TWELVE(0.00)[20]; FROM_HAS_DN(0.00)[]; TAGGED_RCPT(0.00)[dt]; PRECEDENCE_BULK(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-25842-noreply=patchwork.local]; R_SPF_ALLOW(0.00)[+ip4:172.234.253.10]; 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.234.224.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: B69721C1EF8 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") 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 Sun Sep 13 04:04: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: 3294 Return-Path: X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from sea.lore.kernel.org (sea.lore.kernel.org [172.234.253.10]) by mxe881.netcup.net (Postfix) with ESMTPS id 1A1F81C1EF8 for ; Sun, 13 Sep 2026 06:07:02 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=gmail.com; spf=pass (sender IP is 172.234.253.10) smtp.mailfrom=linux-sunxi+bounces-25843-noreply=patchwork.local@lists.linux.dev smtp.helo=sea.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 172.234.253.10 as permitted sender) client-ip=172.234.253.10; envelope-from=linux-sunxi+bounces-25843-noreply=patchwork.local@lists.linux.dev; helo=sea.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by sea.lore.kernel.org (Postfix) with ESMTP id 5159638E9A for ; Sun, 13 Sep 2026 04:05:18 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id E41E336A377; Sun, 13 Sep 2026 04:05:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="kQZB6GMJ" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-ot1-f50.google.com (mail-ot1-f50.google.com [209.85.210.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 1E6D938DC57 for ; Sun, 13 Sep 2026 04:05:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789272315; cv=none; b=unQDCmflS5moA3E3+L1MlHhmwue3Wujmb8aSF2tohINx3C7pcndqnQWongZ6jsC+RuQ5CqegT7Z2vfkIG9NttaKSvIrRs8o6FH2vXaIb7+bLIbZd4MURbAP88VWQSzo3GIfFY0tyb8OPWlUZJ2WWNVM3I0R25598FzIEx8aOQlU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789272315; c=relaxed/simple; bh=7ad0N1K59n1v3Jr94aTA8Zx53dMLKuYLMcOiZWOAZ2o=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=C+qIIzkQV4BgR9COuFsv+DWvy9mBrlDw6UUx5g60aUEJAol0aU0UjtPWkCpkvhrGBz2VTqVt2MgJ91tS4KTV9q/ElVfrnFJj678QlROUNy/yOVYJGb58iG3Me6J4LohFxO0anay8RYnSQ8BZuJ7a67Z7jZopN9GC1krA4UOh2dY= 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=kQZB6GMJ; arc=none smtp.client-ip=209.85.210.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-ot1-f50.google.com with SMTP id 46e09a7af769-805d2fbefc4so525682a34.2 for ; Sat, 12 Sep 2026 21:05:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789272313; x=1789877113; 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=zvSS6wjgtzp/kp5vxvE4i3FisWUsufvg/JdfpaRzj0w=; b=kQZB6GMJEqjbA2zw6XRB9dmjws5imV24JjuokhsXm3wU5uKfVXjjj+avbkhqHh7I6Q s6WDIJGxxYGNcNK1++DD53pAcsTh03+JDdRkAksP8P1XmML6B3Ubb4WG/FnXQzKCPyxq Ie/pruItKWBcwXAPz04AAb9x9K5B+eXd3foD8g1sgD01dIr5I+9FaeRX5IkUQoQzwbow xEeDSeluy8mx0SXrHMmF9+HCheg7H5yrKTbY70VVNfhzU7BDSWsurLgwBUQn/ipdZG9u GkmzZSS/sEKSV6D7RXHlMOJXkm7wyaBYpVglOstyudopvW0NfD2MfcaJVP8VCsONWkWT tG4Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789272313; x=1789877113; 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=zvSS6wjgtzp/kp5vxvE4i3FisWUsufvg/JdfpaRzj0w=; b=oa5LbuYGKj7DUN3FjvJ7poGIuQyPOZII0MPQh/9BhLIGayIDbfYofpbCyYKvMR+rMy 8skDXsHg0zeK8b4WTSO0nYpCeYp3rsDKh34fydKYVYHlaxadnR5XPh3vc4CS7nuYziXI ebsDI7Zx946PV8wiiKEsJnSaY5hzX80awXNvDLYxcZJGxIsOGpQKcH6yymEW1cZMarb0 BH1l3zX85ur/6JmXl94UgTa1m2MyN0yOAN/WIQ0RwvhtRI9nkopG2PH1nPEVTqAGu9Fn iIKuknyHWLv/YIt7kpOdoo9U3rrn6zbXruOPphokcbyDaWymSF6A5sKkIiRXRB/sp0qE tNGA== X-Forwarded-Encrypted: i=1; AKwUvBziihhn04C+ihpCdX8KdOyg768CAc8xwT+HEdb4j/T+XchQuFcnkuNAoxY47z/VDx3EhhElHPBMXo75WQ==@lists.linux.dev X-Gm-Message-State: AFuF++nTj9luF0GBkxwSOU3SiYl2uZUcWHKfQb44NRHGzUS+UMxllJp2 99nfQSDrwlLwFG/jBleXk9VtilE7DT4h1CbiLToEAvMLWUVBYZdyw1p4 X-Gm-Gg: AYBFou1SuTHTxf6gnyXMxlnmpiV4tgqhQvRJU2uzLA4lgjtGTSbMAMZ74UZxWsycjEJ 5c3Mo2PRdvb4TuyCZ4+1Skg7BcshBN/ngfClNUhDFKF1VhHeneEy7HOlQ+6HAAYZVCA3kQXYRcP pTmVM9YufG0S3yxovDyqRqQ6K+WKjUnag7a/Fyxqj4EtnfofFty8bGGpBjZBV/geE4UnYX15GRy 6Z1ZiLjJdSZ4jfieFTLSD5E03gFv9wjNWmRk16sjtswNu9Csmfmmw71ChO3nXup1+AJyMhynMVu MADBY1DWZBgUv6kaTzLZ0G2GQvo+O8kxS5TvWMaTjMvosoBpL6LI5rBGBKfUk1DkiWDoB6P/ZQX hZXzCCWoe2c3kDh9mNOdGwqCO7sy0UEzZrngl7DRGrXqG0KvhkQdko85IWjanPhqZFSa4yAR5j1 v+44P81ctAuGRBcSw2S/ANUefE7onR8IvZP3OEJQw4TZIDCQ38YxOfvbvTUqQ4yxhv+uZGXDkrl lyQHE5/T0xmJX8seSvBfSteQ4e6b+k69100LeuPnIGIlkbSL2coO1WnZhA5mAqb8/DG93Pd4wn/ IVd29V6Js9vxgabcn3u1nfvcLGqbE4Fn44G6JdKWC53UlCi3TcGa7XjhOeqrq2+/qEEHOeg1uVG I8RuWSxMxaNgcaCUILKuYC1KTGxdZew== X-Received: by 2002:a05:6870:6111:b0:475:e235:902 with SMTP id 586e51a60fabf-47dea515f36mr7446958fac.32.1789272312951; Sat, 12 Sep 2026 21:05:12 -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 586e51a60fabf-47df8699647sm6011535fac.5.2026.09.12.21.05.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Sep 2026 21:05:12 -0700 (PDT) From: James Hilliard Date: Sat, 12 Sep 2026 22:04:55 -0600 Subject: [PATCH v4 04/17] 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: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-4-4a64bed94229@gmail.com> References: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-0-4a64bed94229@gmail.com> In-Reply-To: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-0-4a64bed94229@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.234.253.10: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)[]; FREEMAIL_CC(0.00)[lists.infradead.org,vger.kernel.org,lists.linux.dev,gmail.com]; FORGED_SENDER_MAILLIST(0.00)[]; RCPT_COUNT_TWELVE(0.00)[20]; FROM_HAS_DN(0.00)[]; TAGGED_RCPT(0.00)[dt]; PRECEDENCE_BULK(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-25843-noreply=patchwork.local]; R_SPF_ALLOW(0.00)[+ip4:172.234.253.10]; 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.234.224.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: 1A1F81C1EF8 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") 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 Sun Sep 13 04:04: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: 3295 Return-Path: X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from sea.lore.kernel.org (sea.lore.kernel.org [172.234.253.10]) by mxe881.netcup.net (Postfix) with ESMTPS id 804021C2CE2 for ; Sun, 13 Sep 2026 06:07:43 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=gmail.com; spf=pass (sender IP is 172.234.253.10) smtp.mailfrom=linux-sunxi+bounces-25844-noreply=patchwork.local@lists.linux.dev smtp.helo=sea.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 172.234.253.10 as permitted sender) client-ip=172.234.253.10; envelope-from=linux-sunxi+bounces-25844-noreply=patchwork.local@lists.linux.dev; helo=sea.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by sea.lore.kernel.org (Postfix) with ESMTP id 0B7993A307 for ; Sun, 13 Sep 2026 04:05:20 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 655FC38B14D; Sun, 13 Sep 2026 04:05:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="jWbnrqLW" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-oi1-f174.google.com (mail-oi1-f174.google.com [209.85.167.174]) (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 DC3C438E8AD for ; Sun, 13 Sep 2026 04:05:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789272317; cv=none; b=cQ/iSq8D+SE16Y2GWzRn9w7szpeNrSrRojQ3tkpEfEq1hzZj59S+urJ5YzrQOkhlD8TQaESP0Qf8idsuJGIgCvS+nPaRinjzht8vZxHHAU9PDNFCcR8L76lbEhMdfFf+wMGsodtz2IslOaf4s2+jsPPELgCHcLp+JG/4U5fBRuE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789272317; c=relaxed/simple; bh=ZVisc35YlAHASgRL9Dg/dczoW+VnaymOjG/nj+ZynBM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=bKJmTOSMnB+mpE2Zi4FpOpwI0vkKZ/ihWMZ+c85iLK+HPZtRzexlOZUsA49PqqN4ez4MvJRN4c4Gjjd9cFAsnr99IWs5l9387q+nIQ0bSzraqUDJwfxvjQD0vbnj0HWzp1ZfhFHCx6WhbA3Xg1kDAjJqJY4qICyz87y4bZkM1BU= 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=jWbnrqLW; arc=none smtp.client-ip=209.85.167.174 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-f174.google.com with SMTP id 5614622812f47-4c27f0df6e8so1483599b6e.0 for ; Sat, 12 Sep 2026 21:05:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789272315; x=1789877115; 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=qvHpZ4p+GIyvL8ZBW88R4SfXXqB8aP1HME4Kv/dMBls=; b=jWbnrqLWfESKyyL0K7s6yD0UFdA94edD+wFROjMqFswY3GrJY/dMoMAlaEAONyUgw6 M7QP3TSCORczqSGtEbuJ12Wu5c3NYTfC1DMuMcLxY6yrIi/wYPPD1xeH9p+Icmqh4tBI QmKMEexuY8w35KyHCrUs21KVGb6UHqNAnFgCGoK5lbtD5pE0eQLNlHt2Vvoc12c3oiyg YNwyG8aTAS2xYhAUG/8Q5zLf2F1h/Tkj36CUjDmrhgkcsWrPgJcDRbAYloWYfKCbobMc Z564vXy1NtfQPnY74K3hpRGfvx10mZCbDZ8vXiGtC1S4hrahu8D2vDEd+XnyzCKtpF2K uYYg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789272315; x=1789877115; 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=qvHpZ4p+GIyvL8ZBW88R4SfXXqB8aP1HME4Kv/dMBls=; b=QyaUSVrH470MaaSHkO1+UeGM9nR5DVvuv8UY6WPWKBXCmlMHvHUEcmRPiN1sQoM1t0 ddbH8MChzg2nDev76UU/SrKc6rx6Gnx0boQZLVvNE1yM8usNaZZYLL46GZYbpB6pbaCV oRPNdqWzPbdoru89A5MB1rbln9mCo2waVKLr77MbD53JYlfciG6gUbo90R4NUVYYhLrM KzQYQlr4RgbCy5OvOtOswl0YagVNaI0oX0/jETvrPaIi5HQo/hSc75Ip4lIk7H/M1L9y iuRi5/JBr2w9g6NLV0BBi1lppOx2DhDVToVsWxP5GWk4jhnzjWqH1KzgSsog6jIpzB06 q9Mg== X-Forwarded-Encrypted: i=1; AKwUvBx8YmoqiZYRnKzjC639R52ALdzs8oWAQIbPYd/SkKr+oHG0MTJii14dEL3iR5gFO8ekXyn2H7jdfTCyRA==@lists.linux.dev X-Gm-Message-State: AFuF++lwE5QYX31IGdoJpa5ED2KwDkMKZbHbNyJBSmeD90W+EmRG36BE H+yvSy53fjZHEEisgCZEZIvvG/p56CtqRhmeUC/oUju+QQ6FUxwfTH1q X-Gm-Gg: AYBFou0tHKrBlhXGbEa4B0jnrZEfnb2h8fr5WEZvm8NOQBvqO+GRf6O0A8tEASt5w1B NpMEHeKbjCZvvrzaxYrAikh+f7UoC6gPACIuSrpdGekxCRdU0VykoYGHKnOAbCEue3Z4rhVMFY9 xFuzDuxNm/0cgOmCqqItQINQydducYDUPgIAhN10beLuZDjIE1XnCUMNXyP5SO3Tf5/ci/y7YOL kD9BBXJKKyei/UyL6YW8H4iz6U4RrvHSm6aS9uFk276R+xD68LLbCV1A9OCpOuhObkFpvtMhtqj +4a+aPD8h4dSCP6NxO75lilc3fv+qCvbRaD9eV2vt9anu1qlo0hSaJuqOgAi4WDJwwE8RLzwQKR 63qRMBIkuqCOxSj9GhgW5zm/3ydAp6kAV5MWvPyzBAm+UAMSXobIa/Ud22OzvzcZi0XM2+ngxqv f0ETnVtmKakU0PbhRBgOx29Shqu+0KG9jdGdlGbcejijWWKrs7ZEaVWI0rPZI0GTHoSWQ8GCI1N 2k68/GdgjqTeL/tDZn+DpVW0gjyKaIx8X0ehPnNZ98s4DiWoA2FJTtChLz4lRCIKLgrCRs51AV6 2Od9erghlA5MLn8MOAJmyJ+rm1Uqesx6kxU4TpSw1gX4Xm58SgoUg/I29yp5qmuXy6CM7fyBd8Z 5fXRNdPTF+AjzXeO3CQ6Uk+FY/uOgbw== X-Received: by 2002:a05:6808:d4c:b0:4b9:e5fa:8907 with SMTP id 5614622812f47-4c31b4c5e8amr7737916b6e.26.1789272314888; Sat, 12 Sep 2026 21:05: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 586e51a60fabf-47df8699647sm6011535fac.5.2026.09.12.21.05.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Sep 2026 21:05:13 -0700 (PDT) From: James Hilliard Date: Sat, 12 Sep 2026 22:04:56 -0600 Subject: [PATCH v4 05/17] 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: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-5-4a64bed94229@gmail.com> References: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-0-4a64bed94229@gmail.com> In-Reply-To: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-0-4a64bed94229@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 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") 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 Sun Sep 13 04:04: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: 3297 Return-Path: X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from sea.lore.kernel.org (sea.lore.kernel.org [172.234.253.10]) by mxe881.netcup.net (Postfix) with ESMTPS id DB8761C2CE3 for ; Sun, 13 Sep 2026 06:08:29 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=gmail.com; spf=pass (sender IP is 172.234.253.10) smtp.mailfrom=linux-sunxi+bounces-25846-noreply=patchwork.local@lists.linux.dev smtp.helo=sea.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 172.234.253.10 as permitted sender) client-ip=172.234.253.10; envelope-from=linux-sunxi+bounces-25846-noreply=patchwork.local@lists.linux.dev; helo=sea.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by sea.lore.kernel.org (Postfix) with ESMTP id 5AA833B24C for ; Sun, 13 Sep 2026 04:05:23 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 249AE38A725; Sun, 13 Sep 2026 04:05:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="BoIazdCv" 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 7E84338DC61 for ; Sun, 13 Sep 2026 04:05:17 +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=1789272323; cv=none; b=CzAEoyqXgqVw8cyCuY8OYU0CGG/3DXvNwG9LkvwydbrgFjJ0KMw3tFLf6bkTQLH4Psr6MqjO4i7pY/2IH6g8OZMtRZ8HyEXWcPxVgYT5W8KUxqmtFnFVMpDxsJlQ9xvynOHNqmtc+D8upZvaQzzyneDsDgHgthWx6cUYINyzLLY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789272323; c=relaxed/simple; bh=BwaJyFzlFHttOpzQWC5cJaXOsCB26F1Sbm59Qoabces=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=XVHa1+VSdRrDq37uIY/tp1SZ4wlIbDBwvDwgeDKP3YL8F2mlWRcAIFJ6FAXAjswwqa3e4tdvdVUF2amezP8CpPUcvDk0/JZTLb3voQevkIgMSGJ36vyL1/Twk1sYB/OfmUThSnIoSXaoKN8Cl3mib11WBP+hn7BeuEZM3a6CvIc= 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=BoIazdCv; 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-466cc9ab667so1501842fac.0 for ; Sat, 12 Sep 2026 21:05:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789272316; x=1789877116; 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=iXMUiYhcNcQU3o5YIAteHcfA6in7/WsaQMspzMho3uo=; b=BoIazdCvDxpLN456idfDmxeEfDl52Ea+8ADqa6x5YYvdlISkImZrnhnwmIfASP4F/i XaWndMkNeN5GI51u2scyFVm700aVQVMAcux4XBT5dbjDGuRFf60ME9AzspDJw51kfeDT ku0/pG1IYj1PPRXlzF3CJESJRGiTsEGn0mCB/WxFJ03BOLwTyO1+DNzANbMimX7S8L7c WdoQvLloZn40epuecMevaA6Icx9nboIuRPuItQfqD9Jr477+5T8NyivcK4f+7FSk4tvU zMi7aNhKtNrLfNIBmVY4i1aV5gUTYVwWx3pWys2FuSNEsVb3e1JUGa/ttjIsfmjXfY2m 7CPA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789272316; x=1789877116; 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=iXMUiYhcNcQU3o5YIAteHcfA6in7/WsaQMspzMho3uo=; b=V/hICHjb/BIA0/sMBEKJe4GuOrqMoyEOPoXqdO3ATUhF+5mUknVFQ9ebQNWteQbJAZ knUc/vHwWp5vhCkTtrrkfJIpAK5/Nqzf5RvbaTjyrDv+eQSo/56dgJGqlKXx0EdKs30z eJB2aBF6iBzRukvXlQI9rKA4wSZdQdVkAeLqAMulG6mgOYnPjDXWuopHPpBZc3JpA630 bXgCOfBm+sEhKwz772JgHJVYYgRh7/K3xsfABjQ9jmc5ZWIqyb/FgN7e5/CUcVTkB0jx d9GkEx2fwOpgrUHEx23hfngBci9ZWXepnjl1Ip5tjmbit/PIBb3QdrZX+aLZAOVJoqvk nvhw== X-Forwarded-Encrypted: i=1; AKwUvBwn7EF3ltkIiBRIWOoUXQl4FQD/O/pJ2CnXGYIbDkVGjVpCRMEwwChbnn177Myzvw4yJpxyr/dN/suMmw==@lists.linux.dev X-Gm-Message-State: AFuF++m2Pb2dVdBsh2si7MauqomACle8lDdVQk3AVv/awLxQ0ukqOcUJ KFAktFDH8xEf3+2/GcCJ59Wx5bmUIeqaIQ5mVGerbyFvfY5AbrWcemGi X-Gm-Gg: AYBFou0OeJVmDHkiWrrgLOefFRlk8ZrgtZy5+hOkBl43Ixd2VIGvjSYXoYXSaFH1PV6 3MF1Vm2vGhqeIlpHtaN2Gp6riGD112O2pE2s0vpYdURjLzGhoUVAPM3/RxYXsvjQYdj2VnLGV15 buCVn+GxTu3+G5bVj0TKKZipYXozXRGBpPtNI1EKs3Uc8CtbONEkwg9Pi93AmHOW0j9mkaiJpNQ LbsWQiHITKk6yrktBqpA5b4WkXnCOxiSkc/yEKe+9neI/pAuqlsfcSSVYXYu8H4JSbRRs1GzPXZ RRcZs5Z+yBC1EhLUL+l+CpFlRovSWsmcY5jof9ihalj6BioXRTxQTDNB40BGka8sqLzQJbB5RJx iRifQsSzgT4YmB+rY1xUOp1G4p0Mqcbk5bT0hPn32JLp/ttRAa/sXZdB5Ys3EK0cYsE7ygCsH+f bkh+I326FykDDkhgyoxCYUhTfGaOCLuqY//cpNnH64myzqg9Y8e23xQXzllslZ5AXmPe6SRvT+z wkVi7cSSklYmWiw1Z1A4HH2LSUlBoiBeFVz0nx7W/+M0i6OPOwabfqrL+klNg/sYXkBT3sPJyhI 5ZoTZptN7ivWAgDwy+pMo0/DcE4ca2uAZhhU5+BjCFkOW51cTBXIZ8PQ81hmDjltrC6dz3nD6Xk /wkxt4IyepYCs3c48UcYvITefcq1yFg== X-Received: by 2002:a05:6870:b40e:b0:43a:c6c1:e40d with SMTP id 586e51a60fabf-47de8fa793emr7029141fac.16.1789272316328; Sat, 12 Sep 2026 21:05:16 -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 586e51a60fabf-47df8699647sm6011535fac.5.2026.09.12.21.05.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Sep 2026 21:05:15 -0700 (PDT) From: James Hilliard Date: Sat, 12 Sep 2026 22:04:57 -0600 Subject: [PATCH v4 06/17] 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: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-6-4a64bed94229@gmail.com> References: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-0-4a64bed94229@gmail.com> In-Reply-To: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-0-4a64bed94229@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.234.253.10: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)[]; ARC_ALLOW(0.00)[subspace.kernel.org:s=arc-20240116:i=1]; FROM_HAS_DN(0.00)[]; PRECEDENCE_BULK(0.00)[]; TAGGED_RCPT(0.00)[dt]; FREEMAIL_CC(0.00)[lists.infradead.org,vger.kernel.org,lists.linux.dev,gmail.com]; RCPT_COUNT_TWELVE(0.00)[20]; FORGED_SENDER_MAILLIST(0.00)[]; RCVD_COUNT_FIVE(0.00)[6]; ASN(0.00)[asn:63949, ipnet:172.234.224.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.234.253.10: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-25846-noreply=patchwork.local]; MID_RHS_MATCH_FROM(0.00)[]; RCVD_VIA_SMTP_AUTH(0.00)[] X-Rspamd-Queue-Id: DB8761C2CE3 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") 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 Sun Sep 13 04:04: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: 3296 Return-Path: X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from sea.lore.kernel.org (sea.lore.kernel.org [172.234.253.10]) by mxe881.netcup.net (Postfix) with ESMTPS id 84C5C1C2CE2 for ; Sun, 13 Sep 2026 06:08:26 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=gmail.com; spf=pass (sender IP is 172.234.253.10) smtp.mailfrom=linux-sunxi+bounces-25845-noreply=patchwork.local@lists.linux.dev smtp.helo=sea.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 172.234.253.10 as permitted sender) client-ip=172.234.253.10; envelope-from=linux-sunxi+bounces-25845-noreply=patchwork.local@lists.linux.dev; helo=sea.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by sea.lore.kernel.org (Postfix) with ESMTP id 14B5E3B0E9 for ; Sun, 13 Sep 2026 04:05:23 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id E97C338737E; Sun, 13 Sep 2026 04:05:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="W3l1113F" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-oa1-f42.google.com (mail-oa1-f42.google.com [209.85.160.42]) (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 004BE19C54E for ; Sun, 13 Sep 2026 04:05:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789272322; cv=none; b=Bf+3Zi68kNWihdM32qTWTCJw5tRhxTE70fNa7hBbVDDMqV5ARkTs70ccF9dOq+b82+K647YNOG10Qh4jPA7DFItdn6Dz2Xcu1wkokGdAyazzz3rTBLdWyJDcmZ0hA0GEvWXxjrq8kR5YCnUkW8GVLfB987MnWn/5zdyRDZebq0w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789272322; c=relaxed/simple; bh=6QXvhJNkBJWcV5Ntyx9Vdimd7EE2MpJdJCkLfrX8lRo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=k1mwezqcgJbBzEXWcyZQUitaatFELwCO6J5IfZJW7MniP8UPXJEDzYVHu6Vh5pXSW5wzqTezb2fG+jzKscV9+W6fQ2NVZwrAEsIvJEVu0rlw5BFLddSo9ukvQEtr/jiAOFV/k9uGpzdFTvZ06VmjKk6tv8inBzVNLIRhw4oiDso= 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=W3l1113F; arc=none smtp.client-ip=209.85.160.42 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-f42.google.com with SMTP id 586e51a60fabf-478622cd851so1000188fac.1 for ; Sat, 12 Sep 2026 21:05:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789272318; x=1789877118; 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=hb1UAgJ8R3xqyuxnkYr/GKcQBuP99rDSmeFz/RErrU8=; b=W3l1113FuTjB21E9zbZZvoyKtklCKy0RoNEkkzJEcb/Ho02/5uJVwicsrxJFot1+E7 vEgkMwx3JbR0Fv47m+hkRHe+hXLaWEy+zZpIVyDVSZ9o2kQxBKPJEespB1fFiNr8pgan tlm5MwDBQ05PH6pJgvN6FSubdmWNN2xjfOk/EH5UiPRsQ0GyJqhL6bxhM1wrPhVd3jLN uGfkrwvIqEcTJVOMdUbflqrfwbVg5DNCll8hnqTpWsOopleQEVof/L9uM1cJNKH44Vj+ 9Oi9/xef1X8WJUVbSeRbte/Bk5ALbL0ptDfRkD3HHPJ0bTi8n3jSIYrQyV/6ENRx30zX oZbg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789272318; x=1789877118; 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=hb1UAgJ8R3xqyuxnkYr/GKcQBuP99rDSmeFz/RErrU8=; b=o69wM3tcXS0mjiCFA2gIjDgQ0rAlT3UFE3RmAkc+ZrcbvefrHkRQ27obd5n2LVMMuI wMZGZ6N5avfR6WXVXcYg+DfGir3T49fkdXpUojANGBk6Bu/UAcDxmDcV2DLm2AwHBWKZ K5AE5P5TPv7pEwEHH8xR7p4yO/BNovJLdQUPI4xS6KyeJIt5ZIyfHs2ozorjLOPekXzf ZhFZhBgkqZ9NMKu/0zE0Y1wEiNWbzmlIcWIUC3FceNgwX/fqfNyFZuij4JD1398KgQs7 Q/dCL0HfDXPv4IHfr24b5CKjktTkaNJ17MGMr51eW3V+Sf3jbQIWPQ9QhIHHajEXL/MT bS6g== X-Forwarded-Encrypted: i=1; AKwUvByyYLOL9VAHSdX09wX0xC/FeTILYQwP4x7umMAvdeub23VPwYDGxWULk2dON1RQ76j04/Ns7Fl2NjtBUA==@lists.linux.dev X-Gm-Message-State: AFuF++kdnf6fikO+uW/tVd7otDhoKpyp9m0CD4C00h7FahLmsRi1Zb6h uz8epKYni8OQSUl8rCG2tEK/FySQ8hxVjWckn64l2QHwTsB/P/xrGJ3j X-Gm-Gg: AYBFou1FmhelTbGQ2vD83VSGxIqQw4+M7IsVxkJgeuDE8tcaUXq5gnXb0q8fmFLVOpM OIkZa6xCqqFzj3IZyPwlMkSEAYmfn78+PDklpE6kL1dRJ7rTf+U/9FTyvr6/IpdOKcjTqZ0zn5W 9XC+rtkyMvUo/tIcycZEXXcXsUY8EUNr08pLRlSkTi9/aBDb3hAI0sT94zG7kI860AVq/6WuilS 89a/VoO0C/eY2WSaqD1u95kod7fPOKLUdmUvfvTg4/cjsc/eRihNxxU8R8iYNs8ga5DuHqVvpV6 MRKAViS2aSR0pzeamBep4rM3El3gQLACTYG1QfinD0+c1FfGM6Do736QKvBDLeVON15KUXixNyr d0LjeHaKcawzDvXCVfBR5/mqYnxPhSsTPHN/ZnPoHZDFQlFPmKgyOqMjjj4KxwndG4kpGgXNfXj buCELn2uIFqWDfuiWAY5e7YyL9eRZaUiuEMkvwhjoM3SFMVGZCG+ZTvKFtSebHm9iqfTX0A6HK5 HrGb9Log0lacwDlhXr9R3wTKQ/a4+bGbn3aDRzNOi/5iu/B24yktcPNetslB5ChWYrr6vdGop49 71/Ubsm/zGxGWph7otXZg2McYA1Gf9GR33sEoOa4YwCEHESkpHf/JnlsQ9MNXAJLEm+CQoPlBrx ILEp9qTfJplJ3WTv5Q/8Xs9RqLUWbGONneWNA+qe3 X-Received: by 2002:a05:6870:8306:b0:469:fb51:b351 with SMTP id 586e51a60fabf-47de8fd0c3fmr7839424fac.17.1789272317809; Sat, 12 Sep 2026 21:05: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 586e51a60fabf-47df8699647sm6011535fac.5.2026.09.12.21.05.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Sep 2026 21:05:17 -0700 (PDT) From: James Hilliard Date: Sat, 12 Sep 2026 22:04:58 -0600 Subject: [PATCH v4 07/17] 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: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-7-4a64bed94229@gmail.com> References: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-0-4a64bed94229@gmail.com> In-Reply-To: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-0-4a64bed94229@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.234.253.10: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)[]; FREEMAIL_CC(0.00)[lists.infradead.org,vger.kernel.org,lists.linux.dev,gmail.com]; FORGED_SENDER_MAILLIST(0.00)[]; RCPT_COUNT_TWELVE(0.00)[20]; FROM_HAS_DN(0.00)[]; TAGGED_RCPT(0.00)[dt]; PRECEDENCE_BULK(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-25845-noreply=patchwork.local]; R_SPF_ALLOW(0.00)[+ip4:172.234.253.10]; 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.234.224.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: 84C5C1C2CE2 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") 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 Sun Sep 13 04:04: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: 3301 Return-Path: X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from sea.lore.kernel.org (sea.lore.kernel.org [172.234.253.10]) by mxe881.netcup.net (Postfix) with ESMTPS id 624AC1C2CE5 for ; Sun, 13 Sep 2026 06:10:13 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=gmail.com; spf=pass (sender IP is 172.234.253.10) smtp.mailfrom=linux-sunxi+bounces-25849-noreply=patchwork.local@lists.linux.dev smtp.helo=sea.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 172.234.253.10 as permitted sender) client-ip=172.234.253.10; envelope-from=linux-sunxi+bounces-25849-noreply=patchwork.local@lists.linux.dev; helo=sea.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by sea.lore.kernel.org (Postfix) with ESMTP id 22FB43CF24 for ; Sun, 13 Sep 2026 04:05:31 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 0122238D01B; Sun, 13 Sep 2026 04:05:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="SWoEdC8n" 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 7AFA338A718 for ; Sun, 13 Sep 2026 04:05:22 +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=1789272326; cv=none; b=UmnZruFAsBWp6R1K2gwVQFZvX2RqySvmtdVFV2+vBlGUyU4eucflli9HlMfN6xypaZhD7GYRIEyD59B1OPjI2ae7FUaucBppeq8jGTERZ4xnEXTooKQKPrRlws2vr119HcPCLZADoJoYfiOJr7z8FZvzIDTGXpbcQLJWclrpeGA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789272326; c=relaxed/simple; bh=YbBF9laHAErhZzSaGZGDzYG7q1LarpeBoJ8ap1tchQo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ozWJFS3aVd6Z+bbRZK7ETG66PH/tn0Pl0A2sBv0HTXV4WE2Q0oot8lbHGpagxeY+YOgbSnUewN9ZdkB7FqyK1RRBlOjI5M3KMdKkuwrObs0loswKJIVN2NVBa3eeHBXMMFRJASUJrGNvn5l0NfhjffxAw83+JHEyhmyFwUU8304= 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=SWoEdC8n; 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-469fdb78b1cso627129fac.0 for ; Sat, 12 Sep 2026 21:05:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789272319; x=1789877119; 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=SWoEdC8nwKfkImJIKTBCuCxiXLZIevvPQnAx2tyIUCeUfk2yB0ExFvELfXDI3hsfjA iJ3IOXJxWz9HuPwCUaqpm5PttqJYzHgMMbbNFBnO4C5vEwFHyA8sBdwv+TzVFYZqC8aB 0BV/pWLdYXOCxwgWQ6UYHHBEn0Iz+3UWAyFKcbhK7nRq84GhfJ55kkGwLdYkfFMw/ehA v3BwpuopRLiy16yAZgiUt3Tvzm9uQhSAGjBl2g06KR5Sn3lI835741anLc3W0P3oae4i ZpctNhv+5c1oDzT15WuG+DPovibGT2YVstZyJLy73piPNafnf2FbNEQbh4t41eu3qZew 4zRA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789272319; x=1789877119; 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=mwMGwT+nyTyTmnuszAoZyKiCChjEgXPVJV9GUmdM2QxfLejswNObvlePpm6fX8SD99 +R/wSweDQx8PKArufSajCe9aqkJamTQKy+XmjyQ0N3L+HAMvcqesGi3VGm/iXqHqFgMi 1E3cAAn7ZfITgYU/oHbj0VxsyZceErxnC/iiqY4aF8SP9Vkbi2z7Bb+sa3yzMwPHmYG4 I6BwAo92ay77Xxeh0c6jbmB0rPRs5L1ranT0Ib7USg90RvhWUNsMXhWTrpw48z2CShOr 32KFU+caAmdF7zhn3+9H3sLn/WOLB/XlSlICL5PUnaJHw/oig13O12kXP1TUxu8jagZm 0ECw== X-Forwarded-Encrypted: i=1; AKwUvBybgIUXKBbiZp76AY9og0t+MP8Ffn2gU3ggciCeW7XrhT/cWwnDm7hzbcLb5SZyJkE61C+0VoYFVtN8Wg==@lists.linux.dev X-Gm-Message-State: AFuF++nia0euDA/4vkPaQuWSAFmIlL2F8egsDL2vFgCOECiO8JvfjHEq 4e+E0SGZpFQ9lwwjyKggWGjkTLnV+EXBKLuWV2qlFq/mchWO+oHDDUmD X-Gm-Gg: AYBFou0Gi2hUm13OOwx2qjASJK5k0VdDOLeLBt7TOvQnMH/syH4P5QpYMLtMai/3mk+ 0zBZFS1FA3dn5IEVdXXheAyhh2BMieqquaKVKTdhswsL4gMH4R6wJXfzNp3guVsiiQ7Cpo0m1AT I0xkBeqGucrH1Ku6F9MDuY1BYtoMz5QcQ44sdx4zqp8aVquYCwYa9tTA2I+4I+Kr4pt6D4DO+nG pWi0Nt7aNvc1TMjH6rcp6qP0qxfQhxPXf8dodKL+XbnJUyEjUnB1rxdpCpHAp2BeALwh8Bm2heA WiYMvOxE0hjQo/a8cOu5+HI9EOa977NizjQybzEaRe7wzgs8w9yq+bLIpl8WFvfhSeDlbuzbErB 1sepLOds3v8REEMyTHh0Tps6fSGYBi7ClV95qDwh7I5jyhRc4FHALaGH4IHNCvlkJcEzPAzTT+w I1esVzhw1qF02t1lRmLs5B1WzNZWolftBlf/gCLdAClMML+9Ri0Zf7Q2b27++Lu5lGt8fzuC2ro 1zY6Wj2MUqZiclDdB7fqYWCGYSAzyDO7QEl+XRVDbHv2q+0zdwliM/UHDb2D2+rO/NL7uVspyHO 9W3Vyw4Qi7asOTEziFgL5ptshF+Rg9kdpqH8hgp+txPtvJXxsjeerSNYKi+BjhEspeEf8MMQyQO YZvhrcFhS8kQfuMJP5wteqQxLYOJcgLyqdKCJ2JC6 X-Received: by 2002:a05:6870:9386:b0:47b:7862:c1c6 with SMTP id 586e51a60fabf-47f59a2cc34mr2957205fac.23.1789272319247; Sat, 12 Sep 2026 21:05: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 586e51a60fabf-47df8699647sm6011535fac.5.2026.09.12.21.05.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Sep 2026 21:05:18 -0700 (PDT) From: James Hilliard Date: Sat, 12 Sep 2026 22:04:59 -0600 Subject: [PATCH v4 08/17] 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: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-8-4a64bed94229@gmail.com> References: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-0-4a64bed94229@gmail.com> In-Reply-To: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-0-4a64bed94229@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 Sun Sep 13 04:05: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: 3298 Return-Path: X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from sea.lore.kernel.org (sea.lore.kernel.org [172.234.253.10]) by mxe881.netcup.net (Postfix) with ESMTPS id 8F2A11C2CE2 for ; Sun, 13 Sep 2026 06:09:00 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=gmail.com; spf=pass (sender IP is 172.234.253.10) smtp.mailfrom=linux-sunxi+bounces-25847-noreply=patchwork.local@lists.linux.dev smtp.helo=sea.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 172.234.253.10 as permitted sender) client-ip=172.234.253.10; envelope-from=linux-sunxi+bounces-25847-noreply=patchwork.local@lists.linux.dev; helo=sea.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by sea.lore.kernel.org (Postfix) with ESMTP id E3D913BB72 for ; Sun, 13 Sep 2026 04:05:24 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 7090E38737E; Sun, 13 Sep 2026 04:05:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="OqybOzTk" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-oi2-f13.google.com (mail-oi2-f13.google.com [74.125.231.205]) (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 0525538332F for ; Sun, 13 Sep 2026 04:05:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.231.205 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789272324; cv=none; b=VUuj2wTSfNH2FM2OqFrxK/saX0dGzLGdUbu+DRKKdnbcvgLy1dx9zGBPwGLIh8nDUv4hM10mx6RqXWvIup6xKCmNSP5xSNNf0yfL7fvByNCpyRgsOSUaWPtr2H9mBs0vt7YqvBJKF0gMlemxd/XrZePUjpXK3OnkB6Rcu4sdvbg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789272324; c=relaxed/simple; bh=IwH5UB17e0EIm1Uov1vUqQp+kI4MV0xZU7BoJKOPdug=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=bZs241Dy3ZbXBN7fiKZS80BhvWCE7uS+tV2P7pZpV2ridp1EuzK/0q+HnHXCiryQoAgpxErJtn7fDiNtx4s/t0t0JFfhE2irHaoStZdkqp7Fyb1GHgp2OReR9L2Ot7yjIQoG+mRvDcQv1L6klCe5vX1l4TLX8qErkgJjQxKqLzc= 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=OqybOzTk; arc=none smtp.client-ip=74.125.231.205 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-oi2-f13.google.com with SMTP id 5614622812f47-4b37a29bf27so211557b6e.2 for ; Sat, 12 Sep 2026 21:05:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789272321; x=1789877121; 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=mVFhsZOFWXOaaokEcxhZoL5Z9W04LeNellBPPg9dCY4=; b=OqybOzTkuLcjWhtgWm3qEw81jSm3N/732OTl3VSsmgDGDHcAMf/4Pid/IyQIzq2wd1 0IH+nf2wqSR1k0a8KdPT4bmxu9i6LALLM+HZR8tstrAWjlL6OIdrCuVxOCIf0EtAyvO3 ApspAMGczYmeZ2nbMnGoYG6M/GVGh8/imUzRk6OOBk0jeEUd/2QHxu44AuyxtPV/ZOnv xtImGXyvDPdvn2oR40Q/dLiEYIxgJ2ozX3a6yqJO2t8vcN/RIKZfR3FrA0dnyLYtKKaB /KFGdvF6m6diObsoScn/MHS4F3mcto9rymzKoXvBP/9btYJPQqXOHpapd4UBiSdy7Jd7 aCPg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789272321; x=1789877121; 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=mVFhsZOFWXOaaokEcxhZoL5Z9W04LeNellBPPg9dCY4=; b=Lb1fFitpNnS4qaEsw/ZITno/PTtBWHJ5uUP6DaUw2a3HkW/3yV/Nn/e+ynPBZFdSFj sIWBR5j0Cq3Ri2fzdnJ64sZul33kREYuXEmA2VusNCtVwC0kzHbnfYl1Ceia3igGQbZc s4Hcer9TJxVmGarzohuB8aOf8+HBmuLTzRQcYjF8PHq6klItHMguAgSgsfm8Wnl/5Skz DJPrsMwY2GhyEkCOXd0t3Eh5tvhs7Kr4QvPWoVrwgeoCL/z5tt5SjboVD+e4+QDZBLAe 4gNlYNVab9MmPSqi+eH+WqTPbd5XzOl/dheHT7COuepkZfh0+q3/zAo3SzbP18uTFh/x MR9A== X-Forwarded-Encrypted: i=1; AKwUvBzIj5ZDl6LK2zpGedUqHMxtfmyzp7mI4AmC2SMUs+/Sqw8ZAwdABgM3y9w4d/iBqlrdYC7Q0hzJOIIEUw==@lists.linux.dev X-Gm-Message-State: AFuF++laWvhL5xXc2fEmbUaWe7OBZ9Vk50VegjgY6bZdl+Sa/YWCM3Yd kbFFzkQlwUo5xQmShEIVoJ6567QY5vkSOjaa7MybsJEvRWkXg3YQHZAv X-Gm-Gg: AYBFou3ah7aawFRjhIhrJOq2OuEI2SJA/BWAjb4NHFosVUAEF+QwcuTXJytq8JquZbm klJ7j7vQNLLaTpBHCM7yjP7ZDSvCOw2K5nN0O+DBCfRk/r9sqBf/cUKkSoLWXUi7T/yZv7srDAQ ZDyzDQVPRsl6Bmk3bITFfCk4k5aLobEOnlY+grdJ0uNn9H8CZ9ne5IIr37HC+EghbMMrBkPiiEw 5Ojr9GMyPsTSNCpOTPY6t2JGq3OlXeEjna2Nl9dNQ3fES1zi75BaUW9U67+8JsH+1NJaji+04DJ JWU6uBI4uROsUA9a/WiRIsgZiFN8nm5w9ROCFFCgmEsq3kaz4x6BVOrK9mP9gyZQRMsOQl4z2i1 tsLS6IMdq86sOApGsngukJKuxG6cFHZI7RXGXVhHXg/Ear7kpPlAQVZF8sE46sngmSpqQ3MlMFO w8dzwCiPsHInU7p9Oa6pppssVssoj7mD3XQS6Pwwn37awoDMiVLCxpZ/o3+rwEMr+HhoU+6LKIa mwsgwrErXmikmIigv9TCbF6m6J8aXrYyeUU56HWErEnIhPQ9tbRNejJOu/50PpckwtqrMniEuzM RVeC4WuEJWeTKICyJKI67KKiHMc4JQDGXIxoSYok0ICBjpgjmTZ0YmMBExCM+tVFz+/0mm3/uUu a58CirbgUIYVBr33YCYcMeF6HqK2XDg== X-Received: by 2002:a05:6808:1385:b0:4b9:a88b:8892 with SMTP id 5614622812f47-4c4aa8e6f34mr3706612b6e.40.1789272320822; Sat, 12 Sep 2026 21:05:20 -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 586e51a60fabf-47df8699647sm6011535fac.5.2026.09.12.21.05.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Sep 2026 21:05:20 -0700 (PDT) From: James Hilliard Date: Sat, 12 Sep 2026 22:05:00 -0600 Subject: [PATCH v4 09/17] 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: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-9-4a64bed94229@gmail.com> References: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-0-4a64bed94229@gmail.com> In-Reply-To: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-0-4a64bed94229@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.234.253.10: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)[]; RCPT_COUNT_TWELVE(0.00)[20]; FROM_HAS_DN(0.00)[]; FORGED_SENDER_MAILLIST(0.00)[]; ARC_ALLOW(0.00)[subspace.kernel.org:s=arc-20240116:i=1]; FREEMAIL_CC(0.00)[lists.infradead.org,vger.kernel.org,lists.linux.dev,gmail.com]; PRECEDENCE_BULK(0.00)[]; TAGGED_RCPT(0.00)[dt]; RCVD_COUNT_FIVE(0.00)[6]; ASN(0.00)[asn:63949, ipnet:172.234.224.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.234.253.10: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-25847-noreply=patchwork.local]; MID_RHS_MATCH_FROM(0.00)[]; RCVD_VIA_SMTP_AUTH(0.00)[] X-Rspamd-Queue-Id: 8F2A11C2CE2 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. Share the variable-length user-data register-index calculation between the protected-OOB read and write helpers, keeping the separate MMIO loops and existing fixed-length register accesses. 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, 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 | 143 ++++++++++++++++++-------------------- 1 file changed, 67 insertions(+), 76 deletions(-) diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index 13dc0af56eb3..40746686142b 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -924,16 +924,33 @@ 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]; +} + +/* + * Variable-length user data is concatenated in four-byte registers. + * PIO uses hardware step zero; DMA slots follow the logical page steps. + */ +static unsigned int +sunxi_nfc_user_data_reg_index(struct sunxi_nand_chip *sunxi_nand, int hw_step) +{ + unsigned int byte_offset = 0; + int i; + + for (i = 0; i < hw_step; i++) + byte_offset += sunxi_nfc_user_data_sz(sunxi_nand, i); + + return byte_offset / 4; } static void sunxi_nfc_hw_ecc_get_prot_oob_bytes(struct nand_chip *nand, u8 *oob, - int step, bool bbm, int page, + int hw_step, bool bbm, int page, unsigned int user_data_sz) { struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); @@ -941,35 +958,22 @@ static void sunxi_nfc_hw_ecc_get_prot_oob_bytes(struct nand_chip *nand, u8 *oob, u32 user_data; 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)); + user_data = readl(nfc->regs + NFC_REG_USER_DATA(nfc, hw_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_index = sunxi_nfc_user_data_reg_index(sunxi_nand, hw_step); 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); + reg_off = NFC_REG_USER_DATA(nfc, reg_index + i); user_data = readl(nfc->regs + reg_off); sunxi_nfc_user_data_to_buf(user_data, ptr); } } - /* 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); } @@ -991,7 +995,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; @@ -1014,15 +1018,15 @@ 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, - const u8 *oob, int step, + const u8 *oob, int hw_step, bool bbm, int page, unsigned int user_data_sz) { @@ -1030,7 +1034,7 @@ static void sunxi_nfc_hw_ecc_set_prot_oob_bytes(struct nand_chip *nand, struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); u8 user_data[SUNXI_NFC_MAX_USER_DATA_SZ] = {}; - /* 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); @@ -1038,32 +1042,18 @@ static void sunxi_nfc_hw_ecc_set_prot_oob_bytes(struct nand_chip *nand, } 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)); + nfc->regs + NFC_REG_USER_DATA(nfc, hw_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; + unsigned int reg_index = sunxi_nfc_user_data_reg_index(sunxi_nand, hw_step); 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)); + nfc->regs + NFC_REG_USER_DATA(nfc, reg_index + i)); } } - } static void sunxi_nfc_hw_ecc_update_stats(struct nand_chip *nand, @@ -1114,7 +1104,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); @@ -1123,13 +1113,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; @@ -1145,9 +1135,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, @@ -1155,18 +1145,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 = nand_change_read_column_op(nand, data_off, NULL, 0, false); @@ -1188,7 +1178,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, @@ -1205,7 +1195,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; @@ -1232,7 +1222,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); } } @@ -1247,12 +1237,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; @@ -1264,10 +1254,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, @@ -1317,7 +1307,8 @@ static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, uint8_t *buf 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; + bool erased_chunk_found = false; + int ret, i; struct scatterlist sg; u32 status, pattern_found, wait; @@ -1397,7 +1388,7 @@ static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, uint8_t *buf } if (erased) - raw_mode = 1; + erased_chunk_found = true; sunxi_nfc_hw_ecc_update_stats(nand, &max_bitflips, bitflips); } @@ -1420,13 +1411,13 @@ static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, uint8_t *buf if (ret < 0) goto err_stats; if (ret) - raw_mode = 1; + erased_chunk_found = true; } } 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; } @@ -1443,17 +1434,17 @@ static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, uint8_t *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); @@ -1477,8 +1468,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 | @@ -1535,7 +1526,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); @@ -1559,12 +1550,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 Sun Sep 13 04:05: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: 3300 Return-Path: X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from sea.lore.kernel.org (sea.lore.kernel.org [172.234.253.10]) by mxe881.netcup.net (Postfix) with ESMTPS id 20D181C2CE3 for ; Sun, 13 Sep 2026 06:10:01 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=gmail.com; spf=pass (sender IP is 172.234.253.10) smtp.mailfrom=linux-sunxi+bounces-25848-noreply=patchwork.local@lists.linux.dev smtp.helo=sea.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 172.234.253.10 as permitted sender) client-ip=172.234.253.10; envelope-from=linux-sunxi+bounces-25848-noreply=patchwork.local@lists.linux.dev; helo=sea.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by sea.lore.kernel.org (Postfix) with ESMTP id C37BE3CB6F for ; Sun, 13 Sep 2026 04:05:28 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 199D8384CDF; Sun, 13 Sep 2026 04:05:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="p6V6FEjt" 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 6C350388E43 for ; Sun, 13 Sep 2026 04:05: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=1789272326; cv=none; b=U90ZjfxOyOEh1oyTtSm0VZVlpgdak4Hz6Ebrhy+ta0hkw/zPW2aDjLOm2r/ucT52k9SLbOaS2Kget5C9R8ej+I1LinDkCjtr4pdq/PgASkKgmKMZfmZKWdDGMbkTQJWyaTkiB4VuyCOiWMJiIAcEgDawe2vQ/bu39iY8PShvnZE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789272326; c=relaxed/simple; bh=TnmhAN7UAS2ynuFEOPQLlzD2wvbIo/yeVWwhOMqNS58=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=OhDhOT+Mmri++o5BCtmbHfiB7OXyohsrytDwXzFrodxUGHPSYON3pvo1wjy8MRDJ++YIxYKvV6cnZkpwCfWvX14Ae+1eik1L6TMc3MYyTilPLEFWvNbpfSsaINiyWGJmF6hB8X8F0hK+k3FZcPPLHvMn3v2PlKxkKbb9L4+OFbY= 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=p6V6FEjt; 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-466ccbd4773so206825fac.2 for ; Sat, 12 Sep 2026 21:05:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789272322; x=1789877122; 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=p6V6FEjth+NkNgTkqkjPe8NMHe8VoZ5CcGYOMgzBP0HMBFz6VYu+AuWNF+VD4nzJ9a Kso97gZxFtsbVF71wf+/amuQ6Qn5GK9Oc7tY0ui2rsWeX/xMlo/zooQ+g+N4ILwkjBTc nB9BQuZDIzYkSh2crina+5yJJNlmp531vpE6Wr7dlV+Ksx6XhaNJpS7JdaXwdAQm6z1h DhGHo2vifh7kyFDLZamzBl7N4X1i5ZvjqSwTRreyUGPdhtqw/9/j5eDZ6UrlVVR9NIZm DOjQnvL8PP2/jPWgsGxw+0EAZUNMXq715LrClMZGyWwcqav5tmgMcTCDHJSQ9We91vDv hC0A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789272322; x=1789877122; 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=Mw50J/0a42dtazxcs2liNAn/W1XSqzmgaMQ7hVgk9rKlUzOt+jnSJUifZZM8g+v0Qz aUJxT3pm2rn13gTGSZpMrLW8GFryoC9PMcPmqRudE87TGNK5Z4UeUePEpaGP4wjK92kU WR9r/x+Gyu1eVYkzZflWpWnCR2OEioCugQEGkbYRf6Q8L5CMok71y1ZbvsaCPYriNY0h h5O53y2uCXZQyrn2SDX4x1k2ijYSxl8xbKM51klfWcn4GcfmIltwSYrCtcVza3yUaxjl 75DyhZOY0fPvcwVWQn3L7E4z2ua2WNqvL7sEgsoV9JbxOjWTjNIAZxjS4eurhC3wHy/R 5X0Q== X-Forwarded-Encrypted: i=1; AKwUvBydsV6CJ103j8xNkV33gJI3R7mNdBqYGSS1iYiOgQotZk5lzspzDyesyzfDtwEVHSf6FyaCibTigdfhSA==@lists.linux.dev X-Gm-Message-State: AFuF++krM1Rv0n090LVxdJNBH4R4T3DkjVLBu36CCtNExodI3qJUbcBp livOseBY+f+CQVYdXxccDM8n4oD0JxSLSpFsmUQjg1GAkvDO0y8Nvn+J X-Gm-Gg: AYBFou2HkPPNgGl14+baMLvC2EaVK1fy4LJ8hs3e2vxXp77ea4odDh+A1MGyIDtJKmu 5LALH3EaEuNUUOXXYHGSzIQYNPPG1SduZhq5lhJSD8fM/LwpY9vD/SsED8GkqRb35FlRqT6EINm y+tsdOcNyvVo4G9PEPwnrtlvCI9tGEzWiuG7qrjpInYsuhBm3VTNH8x2n7LOmH0ceA8axJ1sYg6 fDza9b5suJ1WSG13fmOyNaNrNAjn0UHyRFeQFOqXfKcZNUNo7SEkxGY2oKJrYfecMhuzmleUe93 HUjY81/MG2IxTe1dnBePkWsYWTPURXoXVzwdb1IjziGFWQoZGAG3KSthb9/wa33srSsdKSUX+/x Gh/P0n9/ZSGh25JgIJyWkSaDwsDi9rcDjnPLC4YDh77XPwfgIj1J1fMMX0UPzjR3EYvWnuHobE3 OWTBDhQxujJUPttTu5RsV3SrN8vrWM+bmDcYC30iqf048cL4c6/eP9OP2Pq8fqdeRSSfdljVUlw 9qtFiMSysay0drd62QbGd2oC7aab/UTh00xFxTKfsclxXkXTU12KQwZ2GfZOzf+N1AIHP6dNHcQ DlB2ahOZ4ZK6eIWgob/Zm+G9XIzblAKFQ4lYxvqLB/wXiagCJV9Z4bsEfI/OIkxKcbstqhfJhvB 3XULOncayUmThOmJCssiHSo4ZppdlQg== X-Received: by 2002:a05:6870:82ac:b0:475:e0a7:9f32 with SMTP id 586e51a60fabf-47f59ca2579mr2988460fac.32.1789272322076; Sat, 12 Sep 2026 21:05:22 -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 586e51a60fabf-47df8699647sm6011535fac.5.2026.09.12.21.05.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Sep 2026 21:05:21 -0700 (PDT) From: James Hilliard Date: Sat, 12 Sep 2026 22:05:01 -0600 Subject: [PATCH v4 10/17] 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: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-10-4a64bed94229@gmail.com> References: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-0-4a64bed94229@gmail.com> In-Reply-To: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-0-4a64bed94229@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.234.253.10: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)[]; FREEMAIL_CC(0.00)[lists.infradead.org,vger.kernel.org,lists.linux.dev,gmail.com]; FORGED_SENDER_MAILLIST(0.00)[]; RCPT_COUNT_TWELVE(0.00)[20]; FROM_HAS_DN(0.00)[]; TAGGED_RCPT(0.00)[dt]; PRECEDENCE_BULK(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-25848-noreply=patchwork.local]; R_SPF_ALLOW(0.00)[+ip4:172.234.253.10]; 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.234.224.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: 20D181C2CE3 X-MORS-Enabled: yes X-MORS-DOMAIN: patchwork.local X-MORS-HOSTING: hosting172546 X-MORS-USER: hosting172546 X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= Allwinner NAND firmware stores the bad block marker through the controller randomizer. The mainline driver instead compensates the first two randomized bytes so that the marker remains plain on flash. On H6 and H616, the firmware also uses a fixed protected user-data placement while mainline fills the OOB space left after ECC. Add an opt-in property selecting the firmware's normal-page format for the configured controller hardware-ECC geometry. This covers the vendor-specific randomizer, bad block marker representation and protected user-data placement needed to access BSP-derived images. The property does not change raw-access semantics. Raw operations still bypass ECC and randomization and expose physical main and OOB bytes. Signed-off-by: James Hilliard --- .../devicetree/bindings/mtd/allwinner,sun4i-a10-nand.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Documentation/devicetree/bindings/mtd/allwinner,sun4i-a10-nand.yaml b/Documentation/devicetree/bindings/mtd/allwinner,sun4i-a10-nand.yaml index 9d061e2216cb..8ecafc40ddcb 100644 --- a/Documentation/devicetree/bindings/mtd/allwinner,sun4i-a10-nand.yaml +++ b/Documentation/devicetree/bindings/mtd/allwinner,sun4i-a10-nand.yaml @@ -79,6 +79,16 @@ patternProperties: minimum: 0 maximum: 1 + allwinner,randomized-oob: + type: boolean + description: + Select the normal-page format used by Allwinner NAND firmware for + the configured controller hardware-ECC geometry. Normal page + transfers use the controller randomizer, the bad block marker remains + in its data stream instead of being compensated to stay plain on + flash, and protected user data uses the controller-specific placement + expected by the firmware. + unevaluatedProperties: false required: From patchwork Sun Sep 13 04:05: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: 3302 Return-Path: X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from sea.lore.kernel.org (sea.lore.kernel.org [172.234.253.10]) by mxe881.netcup.net (Postfix) with ESMTPS id 028C21C2CE3 for ; Sun, 13 Sep 2026 06:11:05 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=gmail.com; spf=pass (sender IP is 172.234.253.10) smtp.mailfrom=linux-sunxi+bounces-25851-noreply=patchwork.local@lists.linux.dev smtp.helo=sea.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 172.234.253.10 as permitted sender) client-ip=172.234.253.10; envelope-from=linux-sunxi+bounces-25851-noreply=patchwork.local@lists.linux.dev; helo=sea.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by sea.lore.kernel.org (Postfix) with ESMTP id D0FF33E25D for ; Sun, 13 Sep 2026 04:05:34 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 003FD38CFF8; Sun, 13 Sep 2026 04:05:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="HoXtQ+OB" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-oo1-f50.google.com (mail-oo1-f50.google.com [209.85.161.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 C099838E8AC for ; Sun, 13 Sep 2026 04:05:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.161.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789272328; cv=none; b=YVbZAYRavISO3a8s4zE/q6UDLT5aNNZbeoOMgA42hKQ0WDnQ9gh+Wf+Joyi8AEB+VPhqOutvIq5eSs7q+Gzk2js3a7OMDO2EH/LQLtpBcxv+ivnVKwMRCZ1+a+eEwAmgmyvJfJY0oEX20HxBkNlyI2fyWwOdmX+8eY/z4LAONgA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789272328; c=relaxed/simple; bh=ba/GKgzDDScyMYA9/+L/r9vJQ7auFMFBC5kuQrceT2w=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=aTozWYVzcOob3PbTM2oLlsRlE4gOD+MZmOVyy6tzensjKdFGCkif5TkSURc5lkTSDvAmeGoM9qi9l28+sAwPwj7x0n+WV7r+gKg7fR/tVjde6ZT7ABPri45wrdhe35Vng6TUybiFo+XbpZY8G/cyt9LUpRUtIlxLsiaZ81cinME= 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=HoXtQ+OB; arc=none smtp.client-ip=209.85.161.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-oo1-f50.google.com with SMTP id 006d021491bc7-6b1b1d128a0so1388638eaf.0 for ; Sat, 12 Sep 2026 21:05:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789272324; x=1789877124; 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=EoqaJxRX3qT28aClhgaCfrfYghT7IZdjt0FxLg5X70U=; b=HoXtQ+OBZqDrsgm0VuS26XxJ9g3rnivVe6PCxIJZCsqPFGMZUUX8uv2nT/n35Y3EPR HwGcNTdZfF410jPVpADJFnROSHnMQFGDCKHiSosTU4iCJWd4GSPEEP3uQzYy2HFSyGsG ORJDYQC1SpdZB/llm1zdhOl2XN5krOSpjlMPT0UCzQ/2kYr8r+/OpHhuAna5djDRaTEY SNmMe5yq3lwLpMm8JfwMqZBnPnPLvPsNwzYPfRytj/EqCmfiI8uUpl2Z3my1MB+A+45G T19h2xiT5nKbObyEIlYbMZVARHM6FF/jSHMgzDILLs4YbZ3tl8izvXQSVx6CugXCcNot NpXQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789272324; x=1789877124; 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=EoqaJxRX3qT28aClhgaCfrfYghT7IZdjt0FxLg5X70U=; b=emAyWZUMoLkCmZRN5eaeACGSZFPJt10oB39sNhrzi8LVuONtr2A9ZtHI7Rx9H5ABrk nVQCsXLWjcW2T/E3C8NTB6aFlSSynYsagVHxmGlDWQ0LMCDEFYdvXpFjYSe7OPbLKMk4 slOH8MFq5lmTIBR8d/M2S+hTn3hFWHr8zvFRGpS3djUDpiZT2bGdWorVjBUrAIqKUJEa OgHJeEIKleUGuFFMQ09iyqcpkCPSEUw83a5dFyYhP47EpTScvPuHuTi+XPloRzh7Oi5g EzGr2fqhvRYvz77STNjTXW3IYhCSJpTpeESVUOv//M7VJxFAogRPHQ5qvY1MQ2qj20Q5 ++qg== X-Forwarded-Encrypted: i=1; AKwUvBz7Ndk85kPMIFzGIrm25ft+fGGwVaDyq8vJZylLMXzs15V6YxetZO9FoSI31mfXFzCvUzEIP0AlsbgcPQ==@lists.linux.dev X-Gm-Message-State: AFuF++ldqXXD0meC/2X7C1fUerlZOLiUH7I/aVNW3aavcPQawVxmty3a Or2PHx0kPX31/Y1tJabmXR8YGW7Aq689JzDdhhwjh/kYLexLPrXftvLP X-Gm-Gg: AYBFou33pn9X/YqY40xZajKFdOT+LVZJ8jrN+Yn2kmQS+YvMSVx1tkmgfHAJDgu+DA+ 9z8/erdt2BpAXU1WIZJuqE6X/lYX3wlQS3H3Pshksahz37x9JY0pyuDt3oITUL2hIv0APJWAUe7 WDFloCPqzsWeRJse0glTMfZZMCb2lO4VkZv0mBWuNkaM4HSbEQWauwKjutWifdWROweerePVZGp Xw3NOlGV3AICwQKmXXliKF5FOL4dnQbqQ3GP+OwxFbXkX01aX6Zl1UC9cZvWzUYC1NqlhLP2NwG IhafDTBWnGod1fsZrEueTvyuiliZIvXDTB6aVB7FvL/gle9mDJEtOm8WDQdUxVNcEH0Pgr8vocq E17gcW8tljXcJHxsbfzptOX5tOdJlTwFUURjYrmvG2YaKpHCGVeQ0rMcv3sjrjdEu0BTLlpjVB+ UN4HBhWnYhA4nNYMA29gxxj2LfYgId9HTRrOooQT7RP2cqsy1804mF4hWevUf4SKfeX0crd5f34 Q4SfjS3duF8ojKCR5zojfQ4KIbjdvBHyixPugpcyzHrX8HJFAtovpAma+THdyeirkudEgK1KPDz P79v6h/F3rGFQ/V09BhBGSC3nixjBavuXX4Wky7zoD2DaLgwCDRvGF6vU0Xgvyvs6OsrWoaeTf2 W5aKZpN7LR4h1kL2jtc5kmm6ptZhrLQ== X-Received: by 2002:a05:6820:2907:b0:6b5:ec2f:356a with SMTP id 006d021491bc7-6c3ce8c4c5emr400751eaf.27.1789272323609; Sat, 12 Sep 2026 21:05:23 -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 586e51a60fabf-47df8699647sm6011535fac.5.2026.09.12.21.05.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Sep 2026 21:05:23 -0700 (PDT) From: James Hilliard Date: Sat, 12 Sep 2026 22:05:02 -0600 Subject: [PATCH v4 11/17] 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: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-11-4a64bed94229@gmail.com> References: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-0-4a64bed94229@gmail.com> In-Reply-To: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-0-4a64bed94229@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.234.253.10: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)[]; FREEMAIL_CC(0.00)[lists.infradead.org,vger.kernel.org,lists.linux.dev,gmail.com]; FORGED_SENDER_MAILLIST(0.00)[]; RCPT_COUNT_TWELVE(0.00)[20]; FROM_HAS_DN(0.00)[]; TAGGED_RCPT(0.00)[dt]; PRECEDENCE_BULK(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-25851-noreply=patchwork.local]; R_SPF_ALLOW(0.00)[+ip4:172.234.253.10]; 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.234.224.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: 028C21C2CE3 X-MORS-Enabled: yes X-MORS-DOMAIN: patchwork.local X-MORS-HOSTING: hosting172546 X-MORS-USER: hosting172546 X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= The controller randomizer covers the bad block marker along with the rest of the OOB data. The driver currently compensates the marker bytes before writes and after reads so that they remain plain on flash. Allwinner NAND firmware instead stores the marker through the randomizer. Media using that format appears to contain bad blocks unless the randomizer is enabled while reading the marker. Honor the allwinner,randomized-oob property by marking the NAND as requiring scrambling during normal hardware-ECC transfers and leaving the marker in the randomizer data stream. Keep the existing plain marker behavior when the property is absent. Reject the property with software or disabled ECC because those paths do not operate the controller randomizer. Also reject an ECC step larger than the page so the NAND core cannot fall back to software ECC after the driver's initial engine-type check. Select the vendor's erased-spare predicate through the SoC capabilities when the randomized format encounters an ECC error. Older controllers require eight exact 0xff spare bytes, with the vendor spare-scan shortcut for four exact bytes on the first page and pages 127 modulo 128 within each eraseblock. Apply that shortcut only with the vendor's 1 KiB ECC steps. H616 requires byte zero and at least nine of ten bytes to be 0xff. Reconstruct the physical spare prefix from the protected user-data registers, padding unavailable bytes with 0xff. Each ECC step restarts its OOB randomizer; account for this when gathering the prefix from fixed four-byte user-data fields. Accepted erased pages return all-0xff main data and OOB without an ECC failure or a raw reread. Also follow the vendor's all-zero-page override: when every ECC step reports an all-zero physical pattern, return zeroed data and OOB with an ECC failure, even if the hardware did not report one. Keep the ECC exception disabled in this mode so uniform data still undergoes decoding. Keep the original hardware-decoded main data and protected OOB on other ECC failures, and report the failure through the ECC statistics. Bad-block and BBT pattern scans inspect these buffers even after an ECC error; they must not see the physical randomized representation. Preserve the normal per-path representation of unprotected OOB bytes when they are requested. Share page classification between PIO and DMA, including subpage reads. Read the whole page for randomized-format subpage requests so that both paths see the same spare prefix and all-zero-page status. Defer statistics until OOB reads have succeeded, so a DMA-to-PIO retry is accounted once. The plain-marker format keeps its existing physical erased-chunk check. MTD_OPS_RAW behavior remains unchanged: raw accesses bypass both ECC and randomization and expose the physical representation. This changes marker handling on all supported controllers; the H6/H616 protected user-data placement is handled separately. Signed-off-by: James Hilliard --- drivers/mtd/nand/raw/sunxi_nand.c | 270 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 261 insertions(+), 9 deletions(-) diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index 40746686142b..725cc302df9f 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -265,6 +265,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 @@ -277,6 +278,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); }; @@ -328,6 +330,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; @@ -356,6 +359,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); }; /** @@ -861,12 +865,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, @@ -974,7 +984,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,7 +1046,8 @@ static void sunxi_nfc_hw_ecc_set_prot_oob_bytes(struct nand_chip *nand, u8 user_data[SUNXI_NFC_MAX_USER_DATA_SZ] = {}; /* 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; @@ -1103,6 +1115,37 @@ static int sunxi_nfc_hw_ecc_read_error(struct nand_chip *nand, return ret >= 0; } +/* Accumulate a whole randomized-OOB page before classifying its spare data. */ +struct sunxi_nfc_ecc_status { + u32 error_steps; + u32 zero_steps; + unsigned int corrected; + unsigned int max_bitflips; +}; + +static void sunxi_nfc_hw_ecc_record_status(struct nand_chip *nand, + struct sunxi_nfc_ecc_status *result, + int logical_step, int hw_step, u32 status, + u32 pattern_found) +{ + struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); + u32 count; + + if ((pattern_found & BIT(hw_step)) && + !(readl(nfc->regs + NFC_REG_PAT_ID(nfc)) & BIT(hw_step))) + result->zero_steps |= BIT(logical_step); + + if (status & NFC_ECC_ERR(hw_step)) { + result->error_steps |= BIT(logical_step); + return; + } + + count = readl(nfc->regs + NFC_REG_ECC_ERR_CNT(nfc, hw_step)); + count = NFC_ECC_ERR_CNT(hw_step, count); + result->corrected += count; + result->max_bitflips = max(result->max_bitflips, count); +} + static int sunxi_nfc_hw_ecc_correct(struct nand_chip *nand, u8 *data, u8 *oob, int hw_step, u32 status, u32 pattern_found, unsigned int user_data_sz, bool *erased) @@ -1145,7 +1188,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); @@ -1194,6 +1238,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); @@ -1295,6 +1349,153 @@ 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 = nand_change_read_column_op(nand, mtd->writesize + off, + nand->oob_poi + off, + ecc->bytes, false); + 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 = nand_change_read_column_op(nand, mtd->writesize + off, + nand->oob_poi + off, len, false); + 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_chunks_dma(struct nand_chip *nand, uint8_t *buf, int oob_required, int page, int nchunks) @@ -1304,6 +1505,7 @@ 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; + 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; @@ -1366,6 +1568,14 @@ static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, uint8_t *buf bool erased; int bitflips; + if (sunxi_nand->randomized_oob) { + sunxi_nfc_hw_ecc_record_status(nand, &result, i, i, status, + pattern_found); + sunxi_nfc_hw_ecc_get_prot_oob_bytes(nand, oob, i, !i, + page, user_data_sz); + continue; + } + bitflips = sunxi_nfc_hw_ecc_correct(nand, randomized ? data : NULL, oob_required ? oob : NULL, i, status, pattern_found, @@ -1393,6 +1603,10 @@ static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, uint8_t *buf sunxi_nfc_hw_ecc_update_stats(nand, &max_bitflips, bitflips); } + if (sunxi_nand->randomized_oob) + return sunxi_nfc_hw_ecc_finish_randomized_read(nand, buf, &result, + oob_required, true, page); + if (status & NFC_ECC_ERR_MSK(nfc)) { for (i = 0; i < nchunks; i++) { int data_off = i * ecc->size; @@ -1524,6 +1738,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; @@ -1546,13 +1761,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); @@ -1598,6 +1819,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); @@ -1618,7 +1843,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; } @@ -1637,6 +1862,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); @@ -2249,6 +2477,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]) { @@ -2317,6 +2549,10 @@ static int sunxi_nand_hw_ecc_ctrl_init(struct nand_chip *nand, sunxi_nand->ecc.ecc_ctl = NFC_ECC_MODE(nfc, ecc_mode) | NFC_ECC_EXCEPTION | NFC_ECC_PIPELINE | NFC_ECC_EN; + /* Run ECC on uniform data too, so the randomized spare bytes are decoded. */ + if (sunxi_nand->randomized_oob) + sunxi_nand->ecc.ecc_ctl &= ~NFC_ECC_EXCEPTION; + if (ecc->size == 512) { if (nfc->caps->has_ecc_block_512) { sunxi_nand->ecc.ecc_ctl |= NFC_ECC_BLOCK_512; @@ -2331,6 +2567,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; @@ -2340,6 +2578,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; @@ -2569,6 +2815,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++) { @@ -2847,6 +3096,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 = { @@ -2870,6 +3120,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 = { @@ -2896,6 +3147,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 Sun Sep 13 04:05: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: 3293 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 355FD1C2CE2 for ; Sun, 13 Sep 2026 06:06:33 +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-25850-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-25850-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 668362C675 for ; Sun, 13 Sep 2026 04:05:34 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id C6FC2392C29; Sun, 13 Sep 2026 04:05:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="i7OWBOGw" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-oi1-f173.google.com (mail-oi1-f173.google.com [209.85.167.173]) (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 52CB638F954 for ; Sun, 13 Sep 2026 04:05:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789272328; cv=none; b=hBuW4UGCJoJzMvECfwPH6dl3MVfoJNvVyEpBADvCe2XmTbp+aK3GUJwB/vOcELe745Ul3LHA/o9bIYx49VQqcHzF8nwOgmEQ83PbIZ8IXHPlnSCg+PBZ3r+Wq4JdVYa/qsZjgqGu/HTJSBSRarwujooB20wqBzjVrqB0kZ/+sNE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789272328; c=relaxed/simple; bh=/U35JMG7PN0VQxPSNjTNdzYGYwq4m+xXswxlipe9peU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZH80HF2KlXG1uf57wFm/S3YOTq4oJem7/+72kXPa03lEAt1Havu8xzzUNBsH1gR96+TzoSEIkPY9cgs7NNUo5jFwPTvb+4qeTqgpN0ZvojCYoEdvl52ELqJtav/h6b/G97qguER2WpxPWhjqBaCVwiLSjUq3Imzrf5kNr/N3Yv4= 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=i7OWBOGw; arc=none smtp.client-ip=209.85.167.173 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-f173.google.com with SMTP id 5614622812f47-4a451915d8aso2288526b6e.2 for ; Sat, 12 Sep 2026 21:05:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789272325; x=1789877125; 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=l3fsd5mFSYNbCICE0q+20FvucYtRM3opmhA2nF/SNd8=; b=i7OWBOGwH2IKc4W+e9ZUluNWunAyTFNVdFO04cuZvuAsWoxUL9ApvVfzB+F2kPNmpU 6I/pn5P/szYcwiDmnhNSRUf6+mtsEHp8kZytg3C2MRzjXaYWkEUtbMwlXxp+OWIHFhJH /K+XVgVr5ehnRhO4sZm0OnSWHi+vqIx6UXdGTzm23qEzejaHYZ03JYko28VFHFH/ZoYN 4XGJoTKHP0AHF52xXSWwQhCIvqK5K3+XLI4EOmRRUuCgoiFvU8jQMj7h6d6qvxOgoK43 BOuEDNuTjLO4zy3LH3X0hBnL7QxnIz/TGk0Df2qzOPQ7PNHY1CRWPCas6tyV3X5XLDGs o7PQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789272325; x=1789877125; 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=l3fsd5mFSYNbCICE0q+20FvucYtRM3opmhA2nF/SNd8=; b=Le21PuKpdCvm1qyMbsFCzegSRb/nNFx3Ux1w+HEvH7D+8cjh7OqvLfMkK6/hk6YIN+ F7b9taCjQN/iMuWldUU8tCNfBC1mMf/sx/JWqM/GISJeHd1Dt0QnRbxnK9uWMeI21g66 aPxpYJNPOkLVnplc1nC4bG+aiz0bI/utxHd7vNyEO/NaM7JRZrYJ3xeuSSrxyQpg6rTo psm/I8JgC04I7S/cTXZzsnAMfqK/Lqd0ASrUOgvK9GLYRvPRGjDNwVh2eTDU90QjsYbH BL3GE/4sZiJw57eGD+k2+cNciOj6aOkcvom5I+1LX+xA/cE8UQ1+flh8xHNRXcjKInNZ nxMA== X-Forwarded-Encrypted: i=1; AKwUvBxBX1JiJ6J4PDOHIO7rat+JezpR16DYtwMi35sbse2v7UKvEtZqDW4vpSRw96cjDZHScv+U5VKFbXEDlg==@lists.linux.dev X-Gm-Message-State: AFuF++knt3G7qJHrfFbM///oMuGGKQSJwYlL2DdM4Osi+aeZILy6Rin5 4nUFxmM77O2JrDROGevD7DkT2n8mdbKwFBjv0tMPzTE80WQTR8sR/3WD X-Gm-Gg: AYBFou02dmKVHx1X5NRUGVejKzGOkNX0dlW79UDUU9Rwt/dqLz4HRWQpYpMtYs41ku7 U/c9yf3qVR/JYugMp4BMZvi0fPRSjZuKTYY6RKeHtlBbIpdpFQTYHydwg10KSwGT1Vdbc8OZGME Xa9jRExKg6Ao2OKXiUGT0gJUyClAXKnwzXJBm6I22kAB9rpMmQdLyRWPfk+6gB7/daUBsORt24y V/nyth9U+iUUNuMww/lXXPEM5GyYxfVVy+wzUw1cCGsjHVb96lppR6tF/bSanV3XE/WxYjb1Qrv bBzfgMkSak7aJQN0jFftnVp+BSLkZNWNHkl8P8F4todXMKccl+QCWvYu4U/rETk3xXoJAppB+du 1lOb1TZTk+vrl7tA0JSsCkQRNA+HHV4UA2pKS5prsuTJTTjVOVuad/oV8/lMQXWB/sC3OOnqG3c I781vijVzPPIqwbxiSpEPl+lMPWN7vPFUESCOydphJp5m5k/FOogu+JCbwfB4wkHjWeUspH/+ly cREC8g5RDmjTX0ON1afNq2Oyi3xEarj7AearUYjSWFTRqf3k7Uc2HddwZpWFRZDbLpyfX8x4o5q fue1gf/qFRsCVdvB3Mb1cbPSN5DNlGoH/GA2fQnn4YzytDy8LmUPBDWUMLu7h1/CmzBOs8rCeJP yWPhASGhGYI6vn3uYHsnEvLukhWo8iGc= X-Received: by 2002:a05:6809:28e:20b0:4c3:7af9:f497 with SMTP id 5614622812f47-4c37af9fbbemr4704298b6e.38.1789272325105; Sat, 12 Sep 2026 21:05:25 -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 586e51a60fabf-47df8699647sm6011535fac.5.2026.09.12.21.05.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Sep 2026 21:05:24 -0700 (PDT) From: James Hilliard Date: Sat, 12 Sep 2026 22:05:03 -0600 Subject: [PATCH v4 12/17] 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: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-12-4a64bed94229@gmail.com> References: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-0-4a64bed94229@gmail.com> In-Reply-To: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-0-4a64bed94229@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)[104.64.211.4: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)[]; FROM_HAS_DN(0.00)[]; RCVD_COUNT_FIVE(0.00)[6]; PRECEDENCE_BULK(0.00)[]; TAGGED_RCPT(0.00)[dt]; FREEMAIL_CC(0.00)[lists.infradead.org,vger.kernel.org,lists.linux.dev,gmail.com]; RCPT_COUNT_TWELVE(0.00)[20]; FORGED_SENDER_MAILLIST(0.00)[]; FROM_NEQ_ENVFROM(0.00)[jameshilliard1@gmail.com,linux-sunxi@lists.linux.dev]; TAGGED_FROM(0.00)[bounces-25850-noreply=patchwork.local]; R_SPF_ALLOW(0.00)[+ip4:104.64.211.4]; 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:104.64.192.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: 355FD1C2CE2 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 725cc302df9f..97a4b4470dad 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -224,6 +224,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 * @@ -2360,8 +2363,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); @@ -2377,6 +2386,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) @@ -2437,6 +2452,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 @@ -2507,12 +2526,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 Sun Sep 13 04:05: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: 3303 Return-Path: X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from sea.lore.kernel.org (sea.lore.kernel.org [172.234.253.10]) by mxe881.netcup.net (Postfix) with ESMTPS id 204071C2CE2 for ; Sun, 13 Sep 2026 06:11:16 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=gmail.com; spf=pass (sender IP is 172.234.253.10) smtp.mailfrom=linux-sunxi+bounces-25852-noreply=patchwork.local@lists.linux.dev smtp.helo=sea.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 172.234.253.10 as permitted sender) client-ip=172.234.253.10; envelope-from=linux-sunxi+bounces-25852-noreply=patchwork.local@lists.linux.dev; helo=sea.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by sea.lore.kernel.org (Postfix) with ESMTP id 9B6EC3E701 for ; Sun, 13 Sep 2026 04:05:35 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 92420393DE2; Sun, 13 Sep 2026 04:05:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="elavoB/a" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-oi1-f182.google.com (mail-oi1-f182.google.com [209.85.167.182]) (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 658F1390610 for ; Sun, 13 Sep 2026 04:05:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789272329; cv=none; b=taYurhwQ/q3H8yxH1sNBddtfuayXu0ev4usak5cn9SNlQb/c+KJ9K6SstZB++xoyftJ1/5JUfX799rESrimFnaxPmhvfmoRdf93bgskXjmIGltbPonLYaKKC0+mQuEFxfWyeTXp+LYNXR8MvH8W2Z3FFnWGq9PX6YCUkiMRYGfE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789272329; c=relaxed/simple; bh=z2BPI/pmixq5cvuOueHRhY4+nASimyd7pRom7zs4YWM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=hztKR4nB8p16WJ2RH9yP0W6luKF3+CuWGWkcDe+zjYdSliDrGhS67lmtYTkFOHvsJXe198RfkizBJUAwwnoYR2sop1tnT1k+2HZl0vMzWtGWgDm3bkMhsbNosgBbqvmbYskPtohPwlRO+9JdxPDzLg9YgqXvkmGyuAQQAzwxXPM= 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=elavoB/a; arc=none smtp.client-ip=209.85.167.182 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-f182.google.com with SMTP id 5614622812f47-4c3eeefdf2bso2093890b6e.1 for ; Sat, 12 Sep 2026 21:05:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789272326; x=1789877126; 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=4QAhKpDJSEoLKbSmhwyQO7+fj2kwJfhM4m0kCMZtpNg=; b=elavoB/aHDOTrYHjnJ+WZumbOV+J4O7dsh7oMdnaF5LjdPUW88ydIOhAmoi+X+G/XB k69v+aBXAiyRCT7aBntSLay6vbf/Q0C+RlAMuQpOsLzQdniNDhhoj49LF76tL9Jamm8W 8wxa+l9SZPYZxqXpvvu3nBgeRxy98yy5BXg+wWWeOgpA2+P+KTaEkPLb8OqNOCMPwwX2 m+4jL+Wlz880OQJBJblZkrW7yqhwmwrqOycSR9xu1U2rSM+he9nYSulYugldOB9kZMg4 VqCk4HL4qzk9gBuh962n75NtXTFaqMu7mrsCRYE62DFPNVMGEBgiKVxSOG/SZN2KNooi enBA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789272326; x=1789877126; 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=4QAhKpDJSEoLKbSmhwyQO7+fj2kwJfhM4m0kCMZtpNg=; b=UMYk58qwI+i9Ew3I8Wv1gfn1LWW3KfaYQK5W1EWhRW506HSaEC6CpudHhf+SnVhHdu lSfuZxxk3kzxEC4VzCGWSdVvr3kn6pQ4Te2oOZ5zIH0M7X3VFUmu5zGOrjU6pfSmFpJU YQQkekk/gx+vAncfMzucYZuFC5yXyDd8Qd+SmIOecOAj4ggxQZydU9auoDeVSsat3rYL C+LD5HLO0eI4VLjEQxBH/QOqU8yc2Ag+b46QYLGlyzO30H3CJBNvGIIwBL8aTo/JLK4f g6snXkSZVu/91htRPU48Mds6r1+dHO+Pr8r9kMzM3sSDTvcTlJQL2UK+BR5QpbFL2/+Q Z9uw== X-Forwarded-Encrypted: i=1; AKwUvBygtDmmdkdXGB736m0iTpovYkjH/etmN3CHiGiEs+k2I9keQzgu6BcwCLX3xgd/odlb1AiqW8bx60XAMw==@lists.linux.dev X-Gm-Message-State: AFuF++k29eEuquzu33PFrdnXCEmuSHhb6iHKiGNHnkRLMq7+awwYx4i3 yEEwX8IynjFM23XQMwunPQoDi0liUjaE5sYCJzI90XJJ2qaAEGy+PD42 X-Gm-Gg: AYBFou2KT2mXEiw01mV4sXF6HiBl3jkiX4SAqcHWn72rPHXOm3fy2tJPLmrfQkFe0hx RjXCG+SG5NnczZApuO85SSIdUCbw0P6lPPvYN0tQHxJjT67yqvjK4b3OWzVe7pyWNzYpOhk15NZ E6NlVUz8o3PT5Eis7+7kJ+48xEbnzsqrRHq32TkZ/SVzPB+kiP/oBQS0lhkvU72nXU1Lekl9S0W yar+7W5aBdnu5SIUPeDqfiqxiXyWfb7PuBq55pSIaaEjTmOADUvc0bA/ae49InKq7BWy1veYti7 +mfp9BuBaxjJEIDgR+8qiBSEsYejnMzIJAy/ybbzmi9fEqJ9ARqGXo5FKDfHP2z4JPb8YtWZEnq gYaRkOrPcYLrJiHP9UmL4akXsGCxnZcPi3L7R7D3O4+5NbMaqBl1QnXNHn4AzURhIwiBWzLzWQS Id7k0TUuJn5OMVOxGWKe8FdPwFbq5Z9xC/O1WKMr3KnfSpKv2rCewonj8XAK+JL6eMcZOTDO7Lo g0k88pJDZtVH+gV+z/NbWYGZPD3wucBnG0xnutVm9e6EvwgnGmoP4GNOFfLNU20+AdWHkPzpEDx NOf62etCvMq5wq3uSQpK1X3urL8mBq13hq6xOEz9OuXAZTC2pNQLs7eUey+0mkuXM9UGO3+0FDF AJuaWfzHYFzTIoyX/ynbFCaB1KeusQQ== X-Received: by 2002:a05:6871:4082:b0:479:a30d:60e5 with SMTP id 586e51a60fabf-47deb6b21a2mr8028318fac.37.1789272326342; Sat, 12 Sep 2026 21:05:26 -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 586e51a60fabf-47df8699647sm6011535fac.5.2026.09.12.21.05.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Sep 2026 21:05:26 -0700 (PDT) From: James Hilliard Date: Sat, 12 Sep 2026 22:05:04 -0600 Subject: [PATCH v4 13/17] 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: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-13-4a64bed94229@gmail.com> References: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-0-4a64bed94229@gmail.com> In-Reply-To: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-0-4a64bed94229@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.234.253.10: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)[]; FREEMAIL_CC(0.00)[lists.infradead.org,vger.kernel.org,lists.linux.dev,gmail.com]; FORGED_SENDER_MAILLIST(0.00)[]; RCPT_COUNT_TWELVE(0.00)[20]; FROM_HAS_DN(0.00)[]; TAGGED_RCPT(0.00)[dt]; PRECEDENCE_BULK(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-25852-noreply=patchwork.local]; R_SPF_ALLOW(0.00)[+ip4:172.234.253.10]; 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.234.224.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: 204071C2CE2 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 | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index 97a4b4470dad..5fba3c111a4b 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -1424,15 +1424,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 = nand_change_read_column_op(nand, mtd->writesize + off, - nand->oob_poi + off, - ecc->bytes, false); + nand->oob_poi + off, len, false); 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, @@ -1443,10 +1456,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 = nand_change_read_column_op(nand, mtd->writesize + off, - nand->oob_poi + off, len, false); - 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 Sun Sep 13 04:05:05 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3304 Return-Path: X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from sea.lore.kernel.org (sea.lore.kernel.org [172.234.253.10]) by mxe881.netcup.net (Postfix) with ESMTPS id 4A6A21C2CE8 for ; Sun, 13 Sep 2026 06:11:46 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=gmail.com; spf=pass (sender IP is 172.234.253.10) smtp.mailfrom=linux-sunxi+bounces-25853-noreply=patchwork.local@lists.linux.dev smtp.helo=sea.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 172.234.253.10 as permitted sender) client-ip=172.234.253.10; envelope-from=linux-sunxi+bounces-25853-noreply=patchwork.local@lists.linux.dev; helo=sea.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by sea.lore.kernel.org (Postfix) with ESMTP id 136093F406 for ; Sun, 13 Sep 2026 04:05:45 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 10D3C395DBF; Sun, 13 Sep 2026 04:05:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="E7g/D/SN" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-oa1-f51.google.com (mail-oa1-f51.google.com [209.85.160.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1C61538F941 for ; Sun, 13 Sep 2026 04:05:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789272330; cv=none; b=tZ8qFiB7K1aSZ0wWSH/SftwuHvMt087KfwjjImoiVLv0792iDeOunK5mNas8xLm4dxKOcSSybeOhp5G+gbLRkoliM4dp60TqXbYJYYtFCqTObk/L06uVldboxVYTGIC6DYi4VUBhOwC7fwMtwYoudoli2K/V+0E2wMlNg+Fm7y0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789272330; c=relaxed/simple; bh=sHxgZAC22jRN5x+cGiwyrOUKu8MIdzjliuwZEPvI6DI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=lcauYjr6XJmNQYExJeVnRQWCbvDrgyMUVdnGfZc76NKFu2R+JFrzqf2B7BMZyVFex2TNhoTrMfewGk/7WmiR7MQ8K+P03ynbUrRwmqUxnsrKncqcInf6JoeFw1H2PxN2fmHWDApyzd1slaHyVs6SLwRhDHtG3zEfSWTruRz7GvM= 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=E7g/D/SN; arc=none smtp.client-ip=209.85.160.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-oa1-f51.google.com with SMTP id 586e51a60fabf-47a6c640bf7so1318172fac.0 for ; Sat, 12 Sep 2026 21:05:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789272328; x=1789877128; 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=I96nTr3z4iUIosSghVQixbz9aFa+jjKeIwLd+JYqRDI=; b=E7g/D/SNHnxO5AjB1bjl+oaJ8K+yAt4i36ix2i/q0Srtw6MM/xWNZd2JVNabQb2w+g BwkpbKq3NLPTXVpTgdRJvLONkxaKmwFoKVpGEha9Y7cH4MWgiriXCKxeAdT/Im1+KzcM WK7LgdZKvYX89MhuqGEMscCihdzlpPyj+/twimsvH8BiRgidiGnh3QWmLDfIdehc1em2 Dr4ORcLDgEHAW5B4JnalxMdPl9+5h6IW5a/kIam1R23QUJabRVIXPWeFKJrlNoNqfJ8O 0cfcscbFOgVUDHOrXmLKUWQbLRfET1h4px7BsEEKeuZuKJ2XsxC+K7N1lasBe3tEyHae 8cwA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789272328; x=1789877128; 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=I96nTr3z4iUIosSghVQixbz9aFa+jjKeIwLd+JYqRDI=; b=ZJYCMvVaS7pBLhZ58MJvcFRt0ckckyP9TVW+/MiGdjSQtaEF2q7Vq0KV/PwWW4KwpP B3lpqnb95CwNagWbPx+Njo8fCxlojdpfHbhGSrc6+DYIHUjay9taRkAnbr4MyFOYxfMm uGGz0mluJ1uffSH1y4zLpfLdqYw351oBlZSLtnOtdpqHIYefCDOeqcORZNcPn/CyEDFc +jau2/F54+KNhb7fGP1f5OeZumTsCzxtvdQ5TrotpOSNovF7epFuwpfdn/2NLZWH/6Dq T35euAG16YSy0Dl3giccXY5ezFnzBm1jOqIreo2trL9AvD/kngyxL1/QONJjpw6EhJwP IOJg== X-Forwarded-Encrypted: i=1; AKwUvBxarfDL/LbuEtyOT9yrCOOG6N1taNeQeEcPA+QNjuAX1srN+U+zEAIhkvD8Zk70z36Vg445puYf+g2CMw==@lists.linux.dev X-Gm-Message-State: AFuF++lAhZFR4BoSMQBVsXuZP/zjVZuMTd3s4GYLUxCemLq6tXqzyvqn ayQJ4k8Lz1CyO4DlQ+30SJHil5z6O3g8iYAMuv8qVgs6IiReNE98ILc/ X-Gm-Gg: AYBFou1lGF/5MmMQ3hdbDhMkWg3h+H9GG6gZQIYr2dMgvGMUnuK3bWmLambe4MJ316T W8tf2m0SvhzwZoOuOuIGb8aGWP9nsf5+N7qZeysdz7hJ+Ag/TI6oPy/8mS23i/jJVtvsshpzvOF ClqpDF5wIzX9Bff9c3uoluOwk5NvywAplGqthPCqTNMqm6a6q9IaT91NZmLqxRsKJk9f7WxeTHU YzhJbG6AYJpUBl9jcr3dVcGev3Jcdba69SJUaUzazXZ0CanzeeRDAHZbw6QFdiioJ3B9yPau4j6 w61FJnrBkrkfqYs1tyuExuoLBrNvfXJPl3eqB18NcM0i4zUfHoU9SxcRa/Lp9k9os2Vp/6gEtJY l27Yv35ua3Evm4UyN+anTOey34CPk3Tk9OJF2ff/HLyuZX2B6Ueo7PzZnwLGVaToHAUNIfM8ByO AXjJp0GmXD4GubgIp3r+08lXC/IJEB+ABWlsGgCFkjeI3vCgDeki3IVw0jVZd9NOD3IlRROVxfv gAn76X9YmMFUx2A/wzHYP7AJa46D2UV/bskRxNx9KDo/ztV4yYa59SA+tRGzRN7KPdv9nxYTKrp QiWGMCI606d8ZE9HDb3FzfpvEIyoZRsvZqk7pA6PI1io+38+C7Zra/ozOIAz8Xypajo+f3lVTwT DII4zroEv6lTbUaarkQBftjd6s+mXDg== X-Received: by 2002:a05:6870:d307:b0:47d:a38a:6218 with SMTP id 586e51a60fabf-47de9864d36mr7458245fac.25.1789272327784; Sat, 12 Sep 2026 21:05:27 -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 586e51a60fabf-47df8699647sm6011535fac.5.2026.09.12.21.05.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Sep 2026 21:05:27 -0700 (PDT) From: James Hilliard Date: Sat, 12 Sep 2026 22:05:05 -0600 Subject: [PATCH v4 14/17] 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: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-14-4a64bed94229@gmail.com> References: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-0-4a64bed94229@gmail.com> In-Reply-To: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-0-4a64bed94229@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.234.253.10: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)[]; RCPT_COUNT_TWELVE(0.00)[20]; FROM_HAS_DN(0.00)[]; FORGED_SENDER_MAILLIST(0.00)[]; ARC_ALLOW(0.00)[subspace.kernel.org:s=arc-20240116:i=1]; FREEMAIL_CC(0.00)[lists.infradead.org,vger.kernel.org,lists.linux.dev,gmail.com]; PRECEDENCE_BULK(0.00)[]; TAGGED_RCPT(0.00)[dt]; RCVD_COUNT_FIVE(0.00)[6]; ASN(0.00)[asn:63949, ipnet:172.234.224.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.234.253.10: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-25853-noreply=patchwork.local]; MID_RHS_MATCH_FROM(0.00)[]; RCVD_VIA_SMTP_AUTH(0.00)[] X-Rspamd-Queue-Id: 4A6A21C2CE8 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 5fba3c111a4b..84e1e04d0743 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -1755,8 +1755,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; @@ -1805,8 +1803,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; @@ -1835,8 +1831,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; @@ -1877,8 +1871,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; @@ -1902,8 +1894,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; @@ -1947,8 +1937,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 Sun Sep 13 04:05:06 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3305 Return-Path: X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from sea.lore.kernel.org (sea.lore.kernel.org [172.234.253.10]) by mxe881.netcup.net (Postfix) with ESMTPS id 6439E1C2CE2 for ; Sun, 13 Sep 2026 06:12:07 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=gmail.com; spf=pass (sender IP is 172.234.253.10) smtp.mailfrom=linux-sunxi+bounces-25854-noreply=patchwork.local@lists.linux.dev smtp.helo=sea.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 172.234.253.10 as permitted sender) client-ip=172.234.253.10; envelope-from=linux-sunxi+bounces-25854-noreply=patchwork.local@lists.linux.dev; helo=sea.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by sea.lore.kernel.org (Postfix) with ESMTP id D077C3FA26 for ; Sun, 13 Sep 2026 04:05:55 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 791C0399CFC; Sun, 13 Sep 2026 04:05:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="ZGapm6Xw" 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 13C043955F0 for ; Sun, 13 Sep 2026 04:05:30 +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=1789272332; cv=none; b=kHfSvPEGAntbp8WtchjQyLIOlB1kGufqSYhXl1GyDBd5I/Er0mUkKsQoxvmpBzCFmONYhACkSrc1rkYV+yfzh3FjXVYRsIJ3jGM4GBQWzdCP1WbzHQWlSdUBJbGHJkI9hro3dn7MoTWRb9IImIUN0oNh+YPI64aqkk8Fscgi4Ew= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789272332; c=relaxed/simple; bh=VjHE1JdFdVf9CJbf3YH4SKT7hC4rAP1wz6y0IHKu+vU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=XZk3wUe+G+mO5pAfgOPFBS9i3BxvHKPiptv563pNJA99UiHvbTfnQMRWyXwi5BYNQFXqdErZzZhSOvAXIQr2NfWCdBlD3Vf6+2yXCxGYICSjaVXYDIKCmBPGguASsrlB5S20QjsmRr2bNVUigwFmO3hqrA3mKrtXlAvTXWPAV9g= 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=ZGapm6Xw; 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-466ccdd77e2so360309fac.3 for ; Sat, 12 Sep 2026 21:05:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789272329; x=1789877129; 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=KdSItwmPertDTRkK8vqVEqMt7TRjoawR0JDQnwMenpk=; b=ZGapm6XwjheXn8MgHWseBhg57FwI7hkgWb94j8ieJgSj2lQ6ab4tp2X4BQs1ezMc56 sdPDSYYGWVldm+Io7DnXs8Rc4tWSS8d5UuK+l5ah+P/BYT1XdaVRrU2UOLuzZZbshO52 bYoSL2as14A5Et6BIG3pPnsMRTRNeMXwrhPsuiY7muGzBlBBOOrnNfqLXHFEHnj2+Rt9 D4MmswefZBi56Gxp8nzX+y++p5BwLSk27rJHl+Q1KjBXYrZYMzqtGoTPSW6SLzH5sal/ a5TD8JDVijOK/c86/30OBYkzn/IyeZ8DYfDpTp0+1whhQKbSdKEFpxgMLGbArWEgfknP Iipg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789272329; x=1789877129; 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=KdSItwmPertDTRkK8vqVEqMt7TRjoawR0JDQnwMenpk=; b=fR8uG4W7HcY6PlttsyBzs6zgILZ0NG4q6wpyk7HAufYkaoR0o6S6iKCxF5+nzFcsCz ypbxlP56KbqWvwzz4q2lCaNGzNohJ6ke9rNGSWNePd7phPXDWNOL2ojbJQLOPNAFwcMJ OQ7wSJ62xRzB0Le+4OAD8eEBFJ01SxXOqKof2AAdjGn3pM8H2cpErx3SiCGkB+tS9awB KW+LsJ3ZZpcmdAmD10LH6bdVfXaAI9hP6oE2j2OkMREI2e2J3hSjqwAOaP0MRXCzvrvt NGgMwfRHYHLzvTSXctam5mPlcOxB1scPp7XGT5/0Cq0za/eZ8ahz6Orar6X7gNBDbQ1e tYAw== X-Forwarded-Encrypted: i=1; AKwUvBzvOD50rbdTRGbaFE07Isn2w1BX58zcSyeWdreu5brsUGP8lTq8oWq5igj8rOtd7M59YlK3ZUt3T6yQEA==@lists.linux.dev X-Gm-Message-State: AFuF++lOPj4CalfIgeB/XC+EvG9IDEdU6vxhtzykGYBQ71va8z0OdUHA RwZjV+YGWkPpzGFryOXVgrLYd+2Wlbx/GMXfbzgl57TF0YrZ32ku38ky X-Gm-Gg: AYBFou32DC2R8HVooqR6TFlt07YWHUCYvcZ4u5mJY1odH++N7gAHxhWSmaY7AIiDt6O 45dvUeA2TztCJY2KSc69ERdmOrAurlPpDApz7bWQi5nuz6mSMeC4qHZDXM6nJ7c5J9mGCP8MAgv 4vbWiU6CsAT/1lW5SNEs8zEVldXv+7ej4X1Ota8VL1+2vDdYvORIHQmiLwYWiY/UUsWMxaFbKiJ B+3v1mDT3+rZVdavizOZlWap+FUekEkXTw7/oEXYMrOl+VgRjVCYLu7wbRoK73KVQ8hUDbG6b4E e8zkQEckbFx4MuVP6pkbSLK6wGDmXvFR6TQ0F5udtFZ+TCy5mh70czK9a2puulkvGat71H+m2uc OPVdHPCGtrQnNuPKiWkFptv/9s+sPrQWRRjsgadwxZi0z92n90pIXTwhfCCZxM5646pK6H5Aoah gF9qO4bxUPxK8ywNHMIFrXz08iVG1oa1ROFJHiDQsT6RPxNlH+IKNe3Wh8BayBWOgF3HFT5FXqk RFQCVJnjmqHbAiuFxTh0lbruSk6dy8n4gk5KzZqpwnZvqiqgQAYTDL04fLI4u1Oi9wlkRGRyNNj 7Yp8/4zffvvvDmd9BflUuwvSZH/O0h8gGSwlR5wduKR5GGhKvvgMgt1lNrLlaORk/N0sMqP1VZt 0C1sB/ZJmDZGR7O5QtVV2ytgD8+ozXg== X-Received: by 2002:a05:6820:61e:b0:6b7:46e9:96f5 with SMTP id 006d021491bc7-6c24e672089mr2838753eaf.37.1789272329061; Sat, 12 Sep 2026 21:05:29 -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 586e51a60fabf-47df8699647sm6011535fac.5.2026.09.12.21.05.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Sep 2026 21:05:28 -0700 (PDT) From: James Hilliard Date: Sat, 12 Sep 2026 22:05:06 -0600 Subject: [PATCH v4 15/17] 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: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-15-4a64bed94229@gmail.com> References: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-0-4a64bed94229@gmail.com> In-Reply-To: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-0-4a64bed94229@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.234.253.10: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)[]; FREEMAIL_CC(0.00)[lists.infradead.org,vger.kernel.org,lists.linux.dev,gmail.com]; FORGED_SENDER_MAILLIST(0.00)[]; RCPT_COUNT_TWELVE(0.00)[20]; FROM_HAS_DN(0.00)[]; TAGGED_RCPT(0.00)[dt]; PRECEDENCE_BULK(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-25854-noreply=patchwork.local]; R_SPF_ALLOW(0.00)[+ip4:172.234.253.10]; 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.234.224.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: 6439E1C2CE2 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 | 73 +++++++++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 26 deletions(-) diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index 84e1e04d0743..debef3f4f0dd 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -1008,35 +1008,59 @@ 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 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, 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, @@ -1225,7 +1249,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, @@ -1536,9 +1560,7 @@ static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, uint8_t *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, i), i); + sunxi_nfc_set_user_data_len_dma(nand, nchunks); sunxi_nfc_randomizer_config(nand, page, false); sunxi_nfc_randomizer_enable(nand); @@ -1694,7 +1716,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); @@ -1989,7 +2011,7 @@ static int sunxi_nfc_hw_ecc_write_page_dma(struct nand_chip *nand, if (ret) goto pio_fallback; - sunxi_nfc_reset_user_data_len(nfc); + sunxi_nfc_set_user_data_len_dma(nand, ecc->steps); 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); @@ -1997,7 +2019,6 @@ static int sunxi_nfc_hw_ecc_write_page_dma(struct nand_chip *nand, 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); } ret = nand_prog_page_begin_op(nand, page, 0, NULL, 0); From patchwork Sun Sep 13 04:05:07 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3290 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 3756D1C2CE3 for ; Sun, 13 Sep 2026 06:06:09 +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-25855-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-25855-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 D4BE6607873 for ; Sun, 13 Sep 2026 04:06:05 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 345FD3911BD; Sun, 13 Sep 2026 04:05:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="r+54E1Br" 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 B6F57399356 for ; Sun, 13 Sep 2026 04:05:31 +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=1789272334; cv=none; b=G8RqbqTaDAKY9Q5itPaQvIB/rAZ9GbpVdPujdoHIpIimd553xXkoAHX2vKYZjNzmHbokaIeph7GRyTpSSxjGdwcGltA6Cn61UCR1egy8RHhKL93cY3dElcfOsjUEWPgz3gRkBdtqrxRieoG2XifKdqBwbZFUv+w8sgnamG+XcE4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789272334; c=relaxed/simple; bh=+b9FVk7yg1ZvvCKVqsKXTOxCwWHm82NDo3cdNKjLRZc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=M7ARLW+9eYomgM8HvwxAFuaqBYF+nac9B8wtmDShTZZvA94hLTruMbqvshp14HcZQm0kXYRjuVU3szG1OXmajR0IeN0ob6frOgCy6rhuJDCbEU3feZUp4SdtXxaKZqNfVEIXn347aHHqNBqCT1xEi/BSSJD/Msz0eIjTjAj2hlw= 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=r+54E1Br; 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-466cc9ab667so1501987fac.0 for ; Sat, 12 Sep 2026 21:05:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789272330; x=1789877130; 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=8EW3/f+RzpimWbfDUvAx3KSD/RKaEHodr5Jfoelq2QM=; b=r+54E1BrljG8Unb20U9P1Zw2klE6Yni19vrTq6FRnBmOmNaU18fSqkSZJY7KHtNS+j pu2Ui+MqC+Kj7WZXKlUeK9oI5EENqlKBiAMYglJHKNAhjolpGpnEPKj2uLsKh3IoqcvW AQ3JHaKxxTdD3C0wAbPidtkN5SUhWgXwlmoSishoCNRh+TB7vPb3GseCnkBuVFAgPwMJ 46cN4Rly3bRElgbJ10zwhDvR9DaLIt/If6EeTx6wwaSjFz8dzO/tSicNjtRNwTdNQA95 lcl0yZ4S2dVXLkw4uU6STb8F7/yo1kC71i1BWoezTXqrGwPpU1ejwROPkVe1LimQUjQd kNBA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789272330; x=1789877130; 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=8EW3/f+RzpimWbfDUvAx3KSD/RKaEHodr5Jfoelq2QM=; b=hiC0nlh9uGYWvVi4UVP9eSXqcGusGe65bm0s4S/ZjDPw0TlC83n24OmbeiiYaAeGBm tvXYucgl170bKJpp7GRKaeDXUEq/UhjBW2WMGCFfDK2NukucjI4iap1X9b//oz3KkEuw SLkQZfua2e3wP2bOmv+djH+1M977w2uIe/RtZ8yS6e8wQ7rJlOImF3HvyWI22hkuQd6T 9TD7Q4A/vEWe7+v0hFEdJCJP7FpqGu1pndSpTnkahJegrDpN2qwisABXEwA9wnOGMOxo 9dyX5uTuhvVBedu5E7ixg4NTpiNUZlIzXMONCaiRhXEnuIbVtPY3NNsqwPzy5jMZdFUd /l0Q== X-Forwarded-Encrypted: i=1; AKwUvBwiTeYYcY9MvZM3vh/YyoQ0VvXtSlZTvoTeltISnWxH8cLoAQnJABG08ceEQEYvRimxbwCAnuucQ/u/Gg==@lists.linux.dev X-Gm-Message-State: AFuF++k/26TAF//0ycjV5dqrBsmc9EEcRwhNJeSlyy/QLxzepdvNMn6y RDxh3bkrmo4+PamGbDEnTRnpLlxJPlBzo4MT/1DnGllTwgoPTprdRFsd X-Gm-Gg: AYBFou30JkCsTf6GdBw7nf9AfPlZEmofAYZentaVTEvQZuHvst75iYJtNcLOCA2M8zb uighbMukgXm5fPNakywKluUnRZjjPIwobA59Oa9G+4+Heea/O62YPHZBWjjWCcdNayRD/m+Pi65 d3VWsb17iMPdHCYfR5NiEhh3HpU6qC72JUc99OFp0EBQyYBiwJ5io4sTOxT3gtVN9gbxFv2wvLc fVAoVZgPdytGfkUuta9aIuQHjssdsm3pTz0R1KVRkFSKnzpGO9gb6saYY7/d5uOEIhPmAE0dQmr KkO7uWeQVmnv62KgxkVYjB6uYuJ2ti39Qu0q7yJY49ZzYexwu7c7XGdrYBgpEHXYjvS+IL8Rw6C ydAnhdrMy0zqEXy9AUBuV45qEg0bcoO/CrmkEKN5wmw1CHcC8nh9A5IMDjVpRnk6T0XGhN/lD5n 07barDdfAJUQ/Io3wSm9TOzhvOOYHJYEzodrtkkDN5W4C+gTsEAXBuwFoDpczNpFBYrz3Ae0LEH Hg2Ey3rDDmmAOa3S3M3gwvcIFgigZNJ7CQ3yPAqHIEbjWsMBvfwPdbG31brqJkAI9ZC+pyJatyX R9To121XJ1ZfRkf+CdcxMwBL8AES+/2fwEXy3qf91f8pvo6yPCK8an5D3RBu2ldh0SjDz2vg6D9 w7o8kbxkp9+qjBoEWZDxy5AGRlqkXrYsNVn34xV6n X-Received: by 2002:a05:6820:8187:b0:6b7:46fa:16a7 with SMTP id 006d021491bc7-6c0bd874de9mr6693573eaf.60.1789272330523; Sat, 12 Sep 2026 21:05:30 -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 586e51a60fabf-47df8699647sm6011535fac.5.2026.09.12.21.05.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Sep 2026 21:05:29 -0700 (PDT) From: James Hilliard Date: Sat, 12 Sep 2026 22:05:07 -0600 Subject: [PATCH v4 16/17] 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: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-16-4a64bed94229@gmail.com> References: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-0-4a64bed94229@gmail.com> In-Reply-To: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-0-4a64bed94229@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 | 100 +++++++++++++++++++++++++------------- 1 file changed, 67 insertions(+), 33 deletions(-) diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index debef3f4f0dd..1303dca74cf9 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -1150,46 +1150,87 @@ struct sunxi_nfc_ecc_status { unsigned int max_bitflips; }; +struct sunxi_nfc_ecc_snapshot { + u32 status; + u32 pattern_found; + u32 pattern_id; + u32 count_reg; + u32 count; +}; + +static void sunxi_nfc_hw_ecc_read_status(struct nand_chip *nand, + struct sunxi_nfc_ecc_snapshot *snapshot) +{ + struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); + u32 pattern_found; + + pattern_found = readl(nfc->regs + nfc->caps->reg_pat_found); + snapshot->pattern_found = field_get(NFC_ECC_PAT_FOUND_MSK(nfc), pattern_found); + if (nfc->caps->reg_pat_found == NFC_REG_ECC_ST) + snapshot->status = pattern_found; + else + snapshot->status = readl(nfc->regs + NFC_REG_ECC_ST); + snapshot->pattern_id = 0; + if (snapshot->pattern_found && + (to_sunxi_nand(nand)->randomized_oob || + (snapshot->pattern_found & ~snapshot->status))) + snapshot->pattern_id = readl(nfc->regs + NFC_REG_PAT_ID(nfc)); + /* A new operation, including every PIO step, invalidates the count word. */ + snapshot->count_reg = ~0U; +} + +static unsigned int +sunxi_nfc_hw_ecc_read_count(struct nand_chip *nand, + struct sunxi_nfc_ecc_snapshot *snapshot, int hw_step) +{ + struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); + u32 reg = NFC_REG_ECC_ERR_CNT(nfc, hw_step); + + /* Four consecutive DMA steps share one error-counter register. */ + if (snapshot->count_reg != reg) { + snapshot->count = readl(nfc->regs + reg); + snapshot->count_reg = reg; + } + + return NFC_ECC_ERR_CNT(hw_step, snapshot->count); +} + static void sunxi_nfc_hw_ecc_record_status(struct nand_chip *nand, struct sunxi_nfc_ecc_status *result, - int logical_step, int hw_step, u32 status, - u32 pattern_found) + int logical_step, int hw_step, + struct sunxi_nfc_ecc_snapshot *snapshot) { - struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); u32 count; - if ((pattern_found & BIT(hw_step)) && - !(readl(nfc->regs + NFC_REG_PAT_ID(nfc)) & BIT(hw_step))) + if ((snapshot->pattern_found & BIT(hw_step)) && + !(snapshot->pattern_id & BIT(hw_step))) result->zero_steps |= BIT(logical_step); - if (status & NFC_ECC_ERR(hw_step)) { + if (snapshot->status & NFC_ECC_ERR(hw_step)) { result->error_steps |= BIT(logical_step); return; } - count = readl(nfc->regs + NFC_REG_ECC_ERR_CNT(nfc, hw_step)); - count = NFC_ECC_ERR_CNT(hw_step, count); + count = sunxi_nfc_hw_ecc_read_count(nand, snapshot, hw_step); result->corrected += count; result->max_bitflips = max(result->max_bitflips, count); } static int sunxi_nfc_hw_ecc_correct(struct nand_chip *nand, u8 *data, u8 *oob, - int hw_step, u32 status, u32 pattern_found, + int hw_step, struct sunxi_nfc_ecc_snapshot *snapshot, unsigned int user_data_sz, bool *erased) { - struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); struct nand_ecc_ctrl *ecc = &nand->ecc; - u32 tmp; *erased = false; - if (status & NFC_ECC_ERR(hw_step)) + if (snapshot->status & NFC_ECC_ERR(hw_step)) return -EBADMSG; - if (pattern_found & BIT(hw_step)) { + if (snapshot->pattern_found & BIT(hw_step)) { u8 pattern; - if (unlikely(!(readl(nfc->regs + NFC_REG_PAT_ID(nfc)) & BIT(hw_step)))) { + if (unlikely(!(snapshot->pattern_id & BIT(hw_step)))) { pattern = 0x0; } else { pattern = 0xff; @@ -1205,9 +1246,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, @@ -1222,7 +1261,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; @@ -1262,13 +1301,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); @@ -1276,8 +1313,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; @@ -1542,13 +1578,14 @@ static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, uint8_t *buf struct mtd_info *mtd = nand_to_mtd(nand); struct nand_ecc_ctrl *ecc = &nand->ecc; struct sunxi_nfc_ecc_status result = {}; + struct sunxi_nfc_ecc_snapshot snapshot; unsigned int corrected = mtd->ecc_stats.corrected; unsigned int failed = mtd->ecc_stats.failed; unsigned int max_bitflips = 0; bool erased_chunk_found = false; int ret, i; struct scatterlist sg; - u32 status, pattern_found, wait; + u32 wait; ret = sunxi_nfc_wait_cmd_fifo_empty(nfc); if (ret) @@ -1589,9 +1626,7 @@ static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, uint8_t *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++) { int data_off = i * ecc->size; @@ -1603,8 +1638,7 @@ static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, uint8_t *buf int bitflips; if (sunxi_nand->randomized_oob) { - sunxi_nfc_hw_ecc_record_status(nand, &result, i, i, status, - pattern_found); + sunxi_nfc_hw_ecc_record_status(nand, &result, i, i, &snapshot); sunxi_nfc_hw_ecc_get_prot_oob_bytes(nand, oob, i, !i, page, user_data_sz); continue; @@ -1612,7 +1646,7 @@ static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, uint8_t *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. */ @@ -1641,7 +1675,7 @@ static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, uint8_t *buf return sunxi_nfc_hw_ecc_finish_randomized_read(nand, buf, &result, oob_required, true, page); - if (status & NFC_ECC_ERR_MSK(nfc)) { + if (snapshot.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); @@ -1649,7 +1683,7 @@ 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; - if (!(status & NFC_ECC_ERR(i))) + if (!(snapshot.status & NFC_ECC_ERR(i))) continue; ret = sunxi_nfc_hw_ecc_read_error(nand, data, data_off, oob, From patchwork Sun Sep 13 04:05:08 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3299 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 BC96E1C2CE2 for ; Sun, 13 Sep 2026 06:09:58 +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-25856-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-25856-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 3972E2EAB5 for ; Sun, 13 Sep 2026 04:06:33 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id F2A0138DC67; Sun, 13 Sep 2026 04:05:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="aVMbiS1B" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-oo1-f43.google.com (mail-oo1-f43.google.com [209.85.161.43]) (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 4471D38C410 for ; Sun, 13 Sep 2026 04:05:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.161.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789272344; cv=none; b=Tetqr0c7YPQmdpilFQrAaP5/rUWMw/tSjaXnPoX/+7bo4B187qRIcJ/XRcEyQwTVzsfaGaaWSAVPLD52YRe3xvPY+6bLXxnohguaFjXVRIwKklPy8kkUH4qxRX2eGbux5XQVtoJm9ABbTPj9IVmpemdCD9hEOGeTM2wMHq4LEa0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789272344; c=relaxed/simple; bh=3HfrlOISvouvOHb/zDf0DeWxK38QXA8QpUUxCtZMkLI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=T5mqf0TRjQRj/QqHgJQ0b3OgL8SLgBaOEUc0HMWeT51P9p/fHWa+4XHLA7G4pyRTHgN69NSnb34mHegCzJZ6bqJ9/Q8wYG3fZXjPtTZaEULJI+z6OZz3Tg6PzPnj9a7RJfLUZMfg4tYAfuelfEDvCOjs70pY4YcVSzr6bdrxLNE= 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=aVMbiS1B; arc=none smtp.client-ip=209.85.161.43 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-f43.google.com with SMTP id 006d021491bc7-6aa9606ddadso1908703eaf.0 for ; Sat, 12 Sep 2026 21:05:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789272332; x=1789877132; 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=5rmncXijitRcj9RxOard0Heg+Nrz/VMzyCWVR9VWKLw=; b=aVMbiS1B89WosUVQVJDtXXAXOIZiW+JvYoha9vR7Sx7trxbGgbuFmlRe9cWVYWfW3x 58J21f49xUYt1aVqCw8zIlRuEnj5QWpPRik8uWVUXdQ3AkIe1vS9XyWFrywRFV3mQ4ze qIq9KKyE7Zh3hnz1NimCISqkh2upajHMH3Bso4P/s+soQUFXk/MhNN9ezjbd2I5uGiiV qVSoUSYZet/wD6SRLkPlY3/efFwZV6lnOvcO6Vv1pi3O07iICe4lHIf5Mr9aLILFkmT8 KFhCv5zgcD6AVjI3rHuU80ZzBLUNypqtUXYEot+hhYBG58XMCsQ4pwuou/xHYrdallA1 dCgg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789272332; x=1789877132; 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=5rmncXijitRcj9RxOard0Heg+Nrz/VMzyCWVR9VWKLw=; b=jnAXmoRlYYnJlFoMNfbk3lNBr4uT6HTmQKYtECNnzHlv9IiP9of3277CjuprE6XZKR 4dTXI7CDDV0WMaFRQHQ9wXF82Rs/A5mD/1lydGFfqVOCJckhz5e7FGHCrAN66BEB98+X nKXN1QXPHBbXufBzY/hE3TzDc+ev+hgVksZShx/51ZWW5afywodHVJtmMo0ml/M3fSZM kk6SQQmKH0owhJg6KtRgAERUMZtRc4ly//verFT8z+6HoWcdl3uwpJhhK29yHl8D/5HB i0x8VEwVvL+mwA/gP7namDZ9TyRWYWlsg7i7ZWdWjbMVuY9jqf7LZAzp5aq0gNsMcgoz 8hMw== X-Forwarded-Encrypted: i=1; AKwUvBxgP5WIgNbX3uNWpPyqmOEyQouG6V+6s/5+ViU3oOctgwi1j2gBNeEEm4V2W6mVGHaGTNz7cnH4jDhtaw==@lists.linux.dev X-Gm-Message-State: AFuF++lpq1Zt41NAd7mYWbuN4R2l7EJx3+Y2gxMWpduhzvxc0dTV4tJq m//Nnso9X3XiCU3OO2lKl/0BbhMogWj42KoayrZp34QCAX6orpOjplE5 X-Gm-Gg: AYBFou2KU7ARkRvlNfti1Hp2lTSYsyaaAnK+po5R4dHfnNgg2vOH4hc83BX3qmsps+E tORGs4kYBwN+x4u3NUYpL2/v5SZx8C5zVOTQKQ/Dcd599VBnDaxbwW/FWt/2/glVFAcOEJ1NJNB 9JH8V3eliWYlhCgj3f8WzDZAO4cQEC1F1rZcaxkvK1f1G2gTPoL8kHnKncRLyAlquTaUwspABn9 mJGesrWXNok5/rTSQ02JoGQSoVAxeo1Ol4CjkgdgUolZ7WAy/5IfoXdXHcCRZkn23b9iZMorXJg QxzEN/VIZsfOxcfZhabk+JSZVVK9cLps/TVA0G7P7VUmlqSdU0XwlN1GszpPXvIftVeyIzYqQBa vywpiS+q5IjznCll3XfJTG+qU0WORDKN3lfS2gs83C2DdXdo/GS/AV+F6jlIW40S3CCWO/Qi+Xd xjDcRweVN1GavWZHvtKKRTe2olHDa5aL82eF6bcN6AcXf28Dp53usbAz/PqUPSZ26gEQTW8HjQG aZiCbsn8vRa+Rp6DgkEFIGYiJ/LBkeO3IThkFS+biNTqSKjo5kOxXsxl//4jvxBUSahXmdPijnH JtTMNBAyq277c/1SwvyiDOB1i3HfiLaigHVSbS0B0LpRWZB4oXz8iMsTRKBuLvTYaSxWiCbpBEw 2EFKZj1Cl5nMXJ3D2F4+tdfinIoX4BQ== X-Received: by 2002:a4a:ec4c:0:b0:6be:4eb3:e1c7 with SMTP id 006d021491bc7-6c0b985e1d1mr6850526eaf.14.1789272332039; Sat, 12 Sep 2026 21:05:32 -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 586e51a60fabf-47df8699647sm6011535fac.5.2026.09.12.21.05.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Sep 2026 21:05:31 -0700 (PDT) From: James Hilliard Date: Sat, 12 Sep 2026 22:05:08 -0600 Subject: [PATCH v4 17/17] 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: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-17-4a64bed94229@gmail.com> References: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-0-4a64bed94229@gmail.com> In-Reply-To: <20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-0-4a64bed94229@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)[104.64.211.4: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)[]; FREEMAIL_CC(0.00)[lists.infradead.org,vger.kernel.org,lists.linux.dev,gmail.com]; FORGED_SENDER_MAILLIST(0.00)[]; RCPT_COUNT_TWELVE(0.00)[20]; FROM_HAS_DN(0.00)[]; TAGGED_RCPT(0.00)[dt]; PRECEDENCE_BULK(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-25856-noreply=patchwork.local]; R_SPF_ALLOW(0.00)[+ip4:104.64.211.4]; 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:104.64.192.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: BC96E1C2CE2 X-MORS-Enabled: yes X-MORS-DOMAIN: patchwork.local X-MORS-HOSTING: hosting172546 X-MORS-USER: hosting172546 X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= The H6/H616 controller concatenates protected user data in a bank of 32 four-byte registers. The default layout can allocate more than 128 bytes across a page, even though each ECC step fits its individual length limit. DMA transfers then access beyond the user-data register bank. For example, a 16 KiB page with 1280 OOB bytes and BCH40/1024 has 160 user-data bytes, while a 16 KiB page with 1664 OOB bytes can allocate 512 bytes. Do not cap that allocation: changing the lengths would move ECC offsets and make existing pages written through PIO incompatible. Instead, split DMA transfers into batches whose aggregate user data fits the bank. Reuse hardware slots and user-data registers from zero in each batch, retaining the original logical main-data and OOB offsets. Reposition the main column and spare-area base before subsequent batches. Keep pages whose user data already fits on the existing single-batch path. Pass the user-data register index directly to the protected-OOB helpers and program length fields from the batch's logical starting step. Collect each batch's ECC status and protected OOB before reusing the registers. Keep ECC accounting, erased-page classification and the trailing-OOB read page-wide, and 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 | 270 +++++++++++++++++++++++--------------- 1 file changed, 161 insertions(+), 109 deletions(-) diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index 1303dca74cf9..c43d2d268d84 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 */ @@ -946,44 +947,40 @@ static u8 sunxi_nfc_user_data_sz(struct sunxi_nand_chip *sunxi_nand, return sunxi_nand->user_data_bytes[logical_step]; } -/* - * Variable-length user data is concatenated in four-byte registers. - * PIO uses hardware step zero; DMA slots follow the logical page steps. - */ -static unsigned int -sunxi_nfc_user_data_reg_index(struct sunxi_nand_chip *sunxi_nand, int hw_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) { - unsigned int byte_offset = 0; + 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; - for (i = 0; i < hw_step; i++) - byte_offset += sunxi_nfc_user_data_sz(sunxi_nand, i); + if (!nfc->caps->reg_user_data_len) + return end_step - first_step; + + for (i = first_step; i < end_step; i++) { + user_data_sz += sunxi_nfc_user_data_sz(sunxi_nand, i); + if (user_data_sz > NFC_H6_USER_DATA_REGS * sizeof(u32)) + break; + } - return byte_offset / 4; + 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 hw_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) { - user_data = readl(nfc->regs + NFC_REG_USER_DATA(nfc, hw_step)); - sunxi_nfc_user_data_to_buf(user_data, oob); - } else { - unsigned int reg_index = sunxi_nfc_user_data_reg_index(sunxi_nand, hw_step); - unsigned int reg_off; - u8 *ptr = oob; - unsigned int i; - - for (i = 0; i < user_data_sz / 4; i++, ptr += 4) { - reg_off = NFC_REG_USER_DATA(nfc, reg_index + 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); } /* Undo hardware de-randomization for a plain on-flash BBM. */ @@ -1038,7 +1035,8 @@ static void sunxi_nfc_set_user_data_len_pio(struct sunxi_nfc *nfc, int len) nfc->regs + NFC_REG_USER_DATA_LEN(nfc, 0)); } -static void sunxi_nfc_set_user_data_len_dma(struct nand_chip *nand, int nchunks) +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); @@ -1054,7 +1052,7 @@ static void sunxi_nfc_set_user_data_len_dma(struct nand_chip *nand, int nchunks) val = 0; for (step = first; step < nchunks && step < first + NFC_REG_USER_DATA_LEN_CAPACITY; step++) { - len = sunxi_nfc_user_data_sz(sunxi_nand, 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); @@ -1064,13 +1062,14 @@ static void sunxi_nfc_set_user_data_len_dma(struct nand_chip *nand, int nchunks) } static void sunxi_nfc_hw_ecc_set_prot_oob_bytes(struct nand_chip *nand, - const u8 *oob, int hw_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; /* Pre-randomize the BBM so the hardware writes it plain on flash. */ if (bbm && (nand->options & NAND_NEED_SCRAMBLING) && @@ -1080,18 +1079,9 @@ static void sunxi_nfc_hw_ecc_set_prot_oob_bytes(struct nand_chip *nand, oob = user_data; } - if (!nfc->caps->reg_user_data_len) { - writel(sunxi_nfc_buf_to_user_data(oob), - nfc->regs + NFC_REG_USER_DATA(nfc, hw_step)); - } else { - unsigned int reg_index = sunxi_nfc_user_data_reg_index(sunxi_nand, hw_step); - const u8 *ptr = oob; - unsigned int i; - - 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, reg_index + 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)); } } @@ -1374,7 +1364,7 @@ static int sunxi_get_ecc_offset(struct sunxi_nand_chip *sunxi_nand, struct nand_ecc_ctrl *ecc, int logical_step) { return sunxi_get_oob_offset(sunxi_nand, ecc, logical_step) + - sunxi_nfc_user_data_sz(sunxi_nand, logical_step); + sunxi_nfc_user_data_sz(sunxi_nand, logical_step); } static int sunxi_nfc_hw_ecc_read_extra_oob(struct nand_chip *nand, @@ -1568,36 +1558,47 @@ sunxi_nfc_hw_ecc_finish_randomized_read(struct nand_chip *nand, u8 *buf, return result->max_bitflips; } -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, + struct sunxi_nfc_ecc_status *result, + bool *erased_chunk_found) { 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; - struct sunxi_nfc_ecc_status result = {}; struct sunxi_nfc_ecc_snapshot snapshot; - 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; - bool erased_chunk_found = false; int ret, i; struct scatterlist sg; u32 wait; + if (first_step) { + ret = nand_change_read_column_op(nand, first_step * ecc->size, + NULL, 0, false); + 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; sunxi_nfc_hw_ecc_enable(nand); - sunxi_nfc_set_user_data_len_dma(nand, nchunks); + 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), + nfc->regs + NFC_REG_SPARE_AREA(nfc)); sunxi_nfc_randomizer_config(nand, page, false); sunxi_nfc_randomizer_enable(nand); @@ -1628,18 +1629,21 @@ static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, uint8_t *buf sunxi_nfc_hw_ecc_read_status(nand, &snapshot); - 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); + if (sunxi_nand->randomized_oob) { - sunxi_nfc_hw_ecc_record_status(nand, &result, i, i, &snapshot); - sunxi_nfc_hw_ecc_get_prot_oob_bytes(nand, oob, i, !i, + 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; } @@ -1659,44 +1663,73 @@ static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, uint8_t *buf oob, ecc->bytes + user_data_sz, false); 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) - erased_chunk_found = true; + *erased_chunk_found = true; sunxi_nfc_hw_ecc_update_stats(nand, &max_bitflips, bitflips); } if (sunxi_nand->randomized_oob) - return sunxi_nfc_hw_ecc_finish_randomized_read(nand, buf, &result, - oob_required, true, page); + return 0; if (snapshot.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 (!(snapshot.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); if (ret < 0) - goto err_stats; + return ret; if (ret) - erased_chunk_found = true; + *erased_chunk_found = true; } } + 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 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; + 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, &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); @@ -2029,68 +2062,87 @@ 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_set_user_data_len_dma(nand, ecc->steps); - 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_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); + 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); + 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 ? */