From patchwork Thu Oct 15 01:34: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: 3620 Return-Path: X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from tor.lore.kernel.org (tor.lore.kernel.org [172.105.105.114]) by mxe881.netcup.net (Postfix) with ESMTPS id 9B8211C2272 for ; Thu, 15 Oct 2026 03:35:53 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=gmail.com; spf=pass (sender IP is 172.105.105.114) smtp.mailfrom=linux-sunxi+bounces-26662-noreply=patchwork.local@lists.linux.dev smtp.helo=tor.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 172.105.105.114 as permitted sender) client-ip=172.105.105.114; envelope-from=linux-sunxi+bounces-26662-noreply=patchwork.local@lists.linux.dev; helo=tor.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by tor.lore.kernel.org (Postfix) with ESMTP id 8E8923CCAA for ; Thu, 15 Oct 2026 01:34:47 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 257D3347BC4; Thu, 15 Oct 2026 01:34:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="iWRyCeVp" 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 26FFF353A99 for ; Thu, 15 Oct 2026 01:34:39 +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=1792028082; cv=none; b=hBZ/hEZ+PqK1DA2uqPSnfPWHdAE3E4P22u0j83U2FQth2KlkpSCAcfpEMR7u3FIn0cmMxFt9ce4CGXWDcb8fveWfAsPyw6/wJcHAakFNfph/z/bmtgifilPT3zaaj1oZ732zzdX2qiacPKDeY4KUBFHh3zRZDXPF0U7teoDlYaQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792028082; c=relaxed/simple; bh=FgRIeZq0vBdVC5LoWFzee1DIYH44/aMP7otHatXZZIM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=P8KwAtjbfe+m/4ybee70idWyWpcxDbBC0mHXmIx0hcYFMNxESfxd8OBPaC+zkJLTWrSY+bylFHLwBSlHcbbN1ffqd7yXTP4Gwz1VLLW9DtgBHM6v762tKyG5yI+fqhD+sW7MJfHZZozxRHELPsDUBqwu1d22ymz437Ug5+SczPM= 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=iWRyCeVp; 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-4932b13c4ccso650095fac.3 for ; Wed, 14 Oct 2026 18:34:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1792028078; x=1792632878; 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=UFOJulppXNuW58TbWJxKvDHpAzEnFrxmkp8urYvlaAM=; b=iWRyCeVpKsVookjLU9n/JCGpN6+o7bGgZDA24cDipxJ6qWpojygmf0DG/8tGvb89ID 1LEDd8OEHg+1JJiI6PvoHkH1QBjC/YHw/A5d7D2+9uWUEGe1O9BkApyosLpwNYHM2Q48 eFYKR11OA3ldsE/6+OBCgH6NzfnQugF6aCMgMjhpgWId42fM7y9yq+i94CTraGiUD09J 9gYHPzDBh9ZmC6A42I4s85dgwzWmnPCsqHvC8KxsEYpXCQwHOAAFaJkIOvk+thsV6xr4 t8EhgjMkx0/O0ghvzB6LzaJsnkxnIMUrxDPrfaQXnUEJpTsXFL0HnFkYxrxWTihikQhc fYuA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1792028078; x=1792632878; 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=UFOJulppXNuW58TbWJxKvDHpAzEnFrxmkp8urYvlaAM=; b=bHcfAeYto3VrBwjvTV+woA3iAF9BOsf8K+wtLEY5Q6/C7mmdilGAtqEphGsGBnMs/B RYNKMzzN7D098grzWwS3uBgIozMXNpb1NctQsHuhCDIyefOPKEU6mCjulRHigdp2k5h9 JIqRtqjFBWinEMxfM9ywLQqCR91XK1tlbAzX25yJgLWsr4+kI7teluRqcSJbuO6WpQ5c AGm6mqmslbaoWDIK5hsSbDelCRVH/WkbSVWP8ExDuoYNUVhjjSv1oo2DGO9wWG5yX4D7 Y/1Ot0qCaDRg//ap2qCHM1uH38Q03FcNkkQ+25CRMp0/5IGwx0EdY8SG5r4a0e2UEpkc aN9g== X-Forwarded-Encrypted: i=1; AKwUvBw2HI1C5EpqgewEKMPfuZTrD+CaR/coBgngPN2Y5oSOzMQPav7DGrPkMSjDKVle+OxPxZIKQImGv/3r3w==@lists.linux.dev X-Gm-Message-State: AFq9FYIcDxridHrSUpgfV4zTQIdEfbmPK6gYNCROkpizlvoWHXFggySv Ci71XDFA9VWRTu30yvIHkPn9OUqZUMarx/hI2eUMeR+7vmBm2c13w8Z4o4yHF7vr X-Gm-Gg: AYBFou3VpNxmDlDu8zi+EIaV7vkwYM7/UHNYwB6n5vBaUwozmD7OZap1bYKARdD1yL3 6FOt4pdF2X9mSkW4TAYWPKQHJEB2HaIyhIORPnT+G90mQUMMC46Nf2/JsKnGDN9217luOHCAO2S QUeHmyw9lbhHr68IANrmoIuCTzHcBHCJcKd2RyQRgkPrhD3o+UMemvvw7K1E0g65GxvGC0KlYe4 +4yBKL/+QKNL5Gpe+xEYc/4bv5os8gHPb+gP2w4Ip4h3eLz108EcOQy9GG7MVLdnP8aWmzvrtbL SjMaTaTk8Fi1QYq9iYZzYieLcGwFULsvZAHhqec862h1IYJKueEvrjh5adsoERIBWKxuRkHrYOZ 7GqfLH4HE9UWxrURNt+AF2XT1aeC3z1b1A8+NN0bF9l0clBxba0XgjBmaz3IlMPBkFsptWGossf JjqvoEJtyi7kCHZqDiC8xWNTOF6OkgPWxE0+sVxUQVFhb7oZEnKAe/CmG/szIJPXf3dkT82QdNC +x82oOG0aUpDe+bXGpNiLZ6d5uuvYR56Bt5EfmjvsckJg6jP1ciQS6B6BjQuZhksCadwuPHtSqq gJH4LMaJ1mvvQFHEcyLBlrpK/LouSxhTngcTgz6FJza3hOx90iUeRvPHuN0mApxwaAuxHBfntCD HunmfQ/NuyArvyKDLxLcUrdnWZMiAA2g= X-Received: by 2002:a05:6870:b3ca:b0:47b:7709:5568 with SMTP id 586e51a60fabf-4a2a89dc998mr15538918fac.10.1792028077989; Wed, 14 Oct 2026 18:34:37 -0700 (PDT) Received: from [127.0.1.1] (174-29-1-49.hlrn.qwest.net. [174.29.1.49]) by smtp.gmail.com with ESMTPSA id 586e51a60fabf-4a6dfb41452sm3428139fac.4.2026.10.14.18.34.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Oct 2026 18:34:37 -0700 (PDT) From: James Hilliard Date: Wed, 14 Oct 2026 19:34:01 -0600 Subject: [PATCH v7 14/16] 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: <20261014-submit-sunxi-nand-vendor-oob-layout-v1-v7-14-5d3fc6ad2da1@gmail.com> References: <20261014-submit-sunxi-nand-vendor-oob-layout-v1-v7-0-5d3fc6ad2da1@gmail.com> In-Reply-To: <20261014-submit-sunxi-nand-vendor-oob-layout-v1-v7-0-5d3fc6ad2da1@gmail.com> To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Sebastian Andrzej Siewior , Clark Williams , Steven Rostedt , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Maxime Ripard , Richard Genoud , Boris Brezillon , Masahiro Yamada , Brian Norris , linux-mtd@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, linux-rt-devel@lists.linux.dev, devicetree@vger.kernel.org, James Hilliard X-Mailer: b4 0.15.2 X-Rspamd-Server: rspamd-worker-8404 X-Spamd-Result: default: False [-1.16 / 15.00]; BAYES_HAM(-5.50)[100.00%]; RBL_SENDERSCORE(2.00)[172.105.105.114:from]; SUSPICIOUS_RECIPS(1.50)[]; DMARC_POLICY_SOFTFAIL(1.00)[gmail.com : SPF not aligned (relaxed), No valid DKIM,none]; MAILLIST(-0.15)[generic]; BAD_REP_POLICIES(0.10)[]; MIME_GOOD(-0.10)[text/plain]; HAS_LIST_UNSUB(-0.01)[]; FORGED_SENDER_MAILLIST(0.00)[]; ARC_ALLOW(0.00)[subspace.kernel.org:s=arc-20240116:i=1]; FROM_HAS_DN(0.00)[]; RCPT_COUNT_TWELVE(0.00)[24]; PRECEDENCE_BULK(0.00)[]; FREEMAIL_CC(0.00)[kernel.org,gmail.com,sholland.org,bootlin.com,socionext.com,lists.infradead.org,lists.linux.dev,vger.kernel.org]; TAGGED_RCPT(0.00)[dt]; DBL_BLOCKED_OPENRESOLVER(0.00)[tor.lore.kernel.org:rdns,tor.lore.kernel.org:helo]; RCVD_COUNT_FIVE(0.00)[6]; ASN(0.00)[asn:63949, ipnet:172.105.96.0/20, country:SG]; FREEMAIL_FROM(0.00)[gmail.com]; R_SPF_ALLOW(0.00)[+ip4:172.105.105.114]; TO_DN_SOME(0.00)[]; RBL_SPAMHAUS_BLOCKED_OPENRESOLVER(0.00)[172.105.105.114:from]; RECEIVED_SPAMHAUS_BLOCKED_OPENRESOLVER(0.00)[100.90.174.1:received]; FROM_NEQ_ENVFROM(0.00)[jameshilliard1@gmail.com,linux-sunxi@lists.linux.dev]; FORGED_RECIPIENTS_MAILLIST(0.00)[]; MIME_TRACE(0.00)[0:+]; TAGGED_FROM(0.00)[bounces-26662-noreply=patchwork.local]; RECEIVED_SPAMHAUS_PBL(0.00)[174.29.1.49:received]; MID_RHS_MATCH_FROM(0.00)[]; RCVD_TLS_LAST(0.00)[]; RCVD_VIA_SMTP_AUTH(0.00)[] X-Rspamd-Queue-Id: 9B8211C2272 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?= H6/H616 pack eight ECC steps' user-data length codes into each 32-bit register. DMA currently clears all these registers, then read-modify-writes one field per step, repeatedly accessing the same words. Code zero means no user data; the other codes select lengths from the controller's table. Build each packed value in memory and write it once per DMA batch, including zeros for unused slots. Take each length from the batch's logical step but encode it in the corresponding batch-local hardware slot. Rewrite every register on each batch rather than caching values across resets or changes of chip. Share the encoding with a PIO setter. PIO always uses hardware slot zero, and its page callbacks clear all length registers before the chunk loop. It can therefore write the slot-zero code directly, without a read-modify-write. Keep the page-level clearing so unused slots are also cleared after a DMA-to-PIO fallback. Older controllers without length registers remain unaffected, and the chosen lengths and on-flash layout do not change. Signed-off-by: James Hilliard --- drivers/mtd/nand/raw/sunxi_nand.c | 79 +++++++++++++++++++++++++-------------- 1 file changed, 50 insertions(+), 29 deletions(-) diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index 4e6fcf1e7aaf..601c272d8c54 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -57,7 +57,7 @@ #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 */ +/* Each USER_DATA_LEN register holds eight 4-bit ECC-step user-data length codes. */ #define NFC_REG_USER_DATA_LEN_CAPACITY 8 #define NFC_REG_USER_DATA_LEN(nfc, step) \ (nfc->caps->reg_user_data_len + \ @@ -1018,35 +1018,60 @@ static void sunxi_nfc_reset_user_data_len(struct sunxi_nfc *nfc) writel(0, nfc->regs + NFC_REG_USER_DATA_LEN(nfc, i)); } -static void sunxi_nfc_set_user_data_len(struct sunxi_nfc *nfc, - int len, int 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, step)); + /* PIO uses slot zero; the page callback clears all other slots. */ + writel(FIELD_PREP(NFC_USER_DATA_LEN_MSK(0), code), + nfc->regs + NFC_REG_USER_DATA_LEN(nfc, 0)); +} + +static void sunxi_nfc_set_user_data_len_dma(struct nand_chip *nand, + int first_step, int nchunks) +{ + struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); + struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); + int first, step, len, code; + u32 val; + + if (!nfc->caps->reg_user_data_len) + return; - val &= ~NFC_USER_DATA_LEN_MSK(step); - val |= field_prep(NFC_USER_DATA_LEN_MSK(step), i); - writel(val, nfc->regs + NFC_REG_USER_DATA_LEN(nfc, step)); + /* Write each packed register once, including zeroes for unused slots. */ + for (first = 0; first < nfc->caps->max_ecc_steps; + first += NFC_REG_USER_DATA_LEN_CAPACITY) { + val = 0; + for (step = first; step < nchunks && + step < first + NFC_REG_USER_DATA_LEN_CAPACITY; step++) { + len = sunxi_nfc_user_data_sz(sunxi_nand, first_step + step); + code = sunxi_nfc_user_data_len_code(nfc, len); + if (code >= 0) + val |= field_prep(NFC_USER_DATA_LEN_MSK(step), code); + } + writel(val, nfc->regs + NFC_REG_USER_DATA_LEN(nfc, first)); + } } static void sunxi_nfc_hw_ecc_set_prot_oob_bytes(struct nand_chip *nand, @@ -1417,7 +1442,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, 0); + 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, @@ -1446,7 +1471,7 @@ static int sunxi_nfc_hw_ecc_read_batch_dma(struct nand_chip *nand, struct sunxi_nfc_ecc_snapshot snapshot; struct scatterlist sg; int page = read->page; - int ret, i; + int ret; u32 wait; if (first_step) { @@ -1467,10 +1492,7 @@ static int sunxi_nfc_hw_ecc_read_batch_dma(struct nand_chip *nand, return ret; sunxi_nfc_hw_ecc_enable(nand); - sunxi_nfc_reset_user_data_len(nfc); - for (i = 0; i < nchunks; i++) - sunxi_nfc_set_user_data_len(nfc, - sunxi_nfc_user_data_sz(sunxi_nand, first_step + i), i); + sunxi_nfc_set_user_data_len_dma(nand, first_step, nchunks); /* exec_op() restores the page's spare base during column changes. */ if (first_step) writel(mtd->writesize + sunxi_get_oob_offset(sunxi_nand, ecc, first_step), @@ -1580,7 +1602,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, nfc_step); + sunxi_nfc_set_user_data_len_pio(nfc, user_data_sz); sunxi_nfc_hw_ecc_set_prot_oob_bytes(nand, oob, nfc_step, bbm, page, user_data_sz); @@ -1847,7 +1869,7 @@ static int sunxi_nfc_hw_ecc_write_page_dma(struct nand_chip *nand, goto pio_fallback; } - sunxi_nfc_reset_user_data_len(nfc); + sunxi_nfc_set_user_data_len_dma(nand, first_step, batch_steps); for (i = first_step; i < first_step + batch_steps; i++) { unsigned int user_data_sz = sunxi_nfc_user_data_sz(sunxi_nand, i); int oob_off = sunxi_get_oob_offset(sunxi_nand, ecc, i); @@ -1855,7 +1877,6 @@ static int sunxi_nfc_hw_ecc_write_page_dma(struct nand_chip *nand, sunxi_nfc_hw_ecc_set_prot_oob_bytes(nand, oob, reg_index, !i, page, user_data_sz); - sunxi_nfc_set_user_data_len(nfc, user_data_sz, i - first_step); reg_index += user_data_sz / 4; }