[PATCH v6 00/18] mtd: rawnand: sunxi: support the Allwinner randomized OOB format
From: James Hilliard
Date: Mon Sep 14 2026 - 17:10:21 EST
Allwinner NAND firmware leaves the bad-block marker in the randomizer
data stream. On H6/H616 it also places all protected user data before the
first ECC step. These choices differ from the mainline format, which
keeps the physical marker plain and maximizes the H6/H616 user-data area.
Add allwinner,randomized-oob to select the firmware format for the
configured hardware-ECC geometry. Older controllers keep their fixed
four-byte-per-step user-data layout; H6/H616 use four bytes per 1 KiB
step, capped at 16 bytes, packed before the first ECC step. Without the
property, retain the existing marker handling and OOB layout.
Normal hardware-ECC accesses use the controller randomizer. MTD_OPS_RAW
continues to bypass both ECC and randomization and expose physical data
and OOB, including randomized markers stored by firmware.
Address the ECC-error paths as well. In randomized-OOB mode, use the
controller-specific vendor spare-byte erased-page heuristic on the
protected user data from the original hardware read. Older controllers
use exact erased-spare checks, including their first-page and page-127
signatures; H616 requires byte zero and at least nine of ten spare bytes
to be 0xff. Accepted erased pages return all-0xff data and OOB without a
raw reread. An all-zero physical page instead returns a bad marker and
an ECC failure.
Keep ECC exception mode enabled for physical-pattern reporting. Uniform
physical steps can suppress hardware ECC errors, so classify them with the
vendor page check too and exclude their correction counters.
Other ECC failures retain the original decoded data and protected OOB for
bad-block and flash-BBT pattern scans. PIO and DMA share this page-wide
classification, including randomized-format subpage reads. Plain-marker
mode keeps its existing physical erased-chunk check.
Start with fixes for interrupt/completion ordering, PIO OOB lengths,
per-step pattern IDs, read/write error handling, duplicate OOB program
confirms and the extra-OOB cursor. Follow these with the small-page
command fix and the DMA register-bank fix, then the OOB-helper cleanup,
binding and randomized-format support.
Use page-addressed reads to reposition small-page NAND in hardware-ECC
read paths, retaining transport errors and the existing geometry checks.
Select PIO for those pages because the DMA sequencer uses large-page
random-column commands. Large-page DMA and the on-flash layout are unchanged.
Bound H6/H616 DMA batches by the 128-byte user-data register bank.
Keep the existing default OOB allocation and ECC offsets. Fill the first
batch to the bank limit, then use one hardware slot per remaining logical
step: PAGE_OP generates later main-data columns independently of the initial
column. Preserve page-wide ECC accounting, DMA support and a single final
program confirm.
All of these fixes apply without the randomized-OOB property.
Finish with optimizations to combine contiguous unprotected OOB reads and
reduce repeated chip setup and register accesses without changing the
page format.
Assisted-by: Codex:gpt-6-astra
Signed-off-by: James Hilliard <james.hilliard1@xxxxxxxxx>
---
Changes in v6:
- retain the bank-sized first DMA batch, but transfer later logical steps
individually to avoid PAGE_OP's absolute internally generated main columns
- keep ECC exception mode enabled for randomized reads on all supported
controllers, using the shared physical-pattern classifier
- classify uniform-pattern steps even when hardware suppresses their ECC
errors; skip their correction counters and preserve decoded buffers unless
the page-wide zero override or vendor spare predicate accepts the page
- Link to v5: https://patch.msgid.link/20260913-submit-sunxi-nand-vendor-oob-layout-v1-v5-0-7d711076a6f7@xxxxxxxxx
Changes in v5:
- add a separate small-page command-handling fix: use READ0/READ1/READOOB
with the page address for rereads and normal OOB access, and select PIO
instead of the large-page DMA sequencer
- keep physical reread errors visible, preserve the OOB cursor and retain
the existing ECC geometry requirements, including rejection of 512+16
with controller ECC
- group the small-page fix and the DMA register-bank fix with the opening
fixes, ahead of cleanups, bindings, format support and optimizations
- make the DMA register-bank fix independent of randomized-OOB support
and the later register-access optimizations
- Link to v4: https://patch.msgid.link/20260912-submit-sunxi-nand-vendor-oob-layout-v1-v4-0-4a64bed94229@xxxxxxxxx
Changes in v4:
- prepend an independent fix for completion reuse and IRQ timeout races:
initialize the completion once, finish IRQ register updates before
signalling success, and drain timed-out handlers before clearing their
interrupt state
- add a separate fix for aggregate protected-user-data register overflow
by splitting DMA transfers into bounded batches, retaining the existing
OOB layout, ECC offsets and DMA support
- distinguish logical page steps from batch-local hardware slots, retain
page-wide ECC accounting and avoid retrying partially transferred writes
- Link to v3: https://patch.msgid.link/20260909-submit-sunxi-nand-vendor-oob-layout-v1-v3-0-838cb0ba1547@xxxxxxxxx
Changes in v3:
- add a prerequisite fix for the logical OOB length used by PIO transfers
- clarify logical ECC steps versus hardware slots and share protected-OOB
register indexing
- select the controller-specific vendor spare-byte erased-page check from
the SoC capabilities, only in randomized-OOB mode and without rereading
the main data
- retain hardware-decoded data and protected OOB on other ECC failures
for bad-block and BBT pattern scans (reported by Miquel Raynal)
- retain a bad marker and ECC failure for all-zero physical pages, and
disable the ECC exception for the vendor format
- share page classification between PIO and DMA, reading complete pages
for randomized-format subpage requests
- propagate OOB read errors and defer randomized-format ECC accounting
until those reads have succeeded
- propagate read/program setup, column-change and buffer-transfer errors,
including extra OOB; stop failed writes and disable ECC and randomization
- discard partial DMA ECC statistics before retrying in PIO, and keep
correction counts separate from successful OOB-transfer status
- select the current hardware step's pattern ID instead of slot zero
- avoid a second program confirm after an OOB-only write
- avoid redundant column changes before writing extra OOB bytes
- reject oversized ECC steps in randomized-OOB mode before the core can
fall back to software ECC
- combine adjacent parity and trailing OOB reads in randomized-OOB mode
- remove duplicate chip setup immediately before core page commands
- program each packed DMA user-data length register once per operation,
and write PIO slot zero directly without read-modify-write
- reuse pattern IDs and packed error counters within a DMA read, while
refreshing the snapshot after every PIO ECC operation
- Link to v2: https://patch.msgid.link/20260904-submit-sunxi-nand-vendor-oob-layout-v1-v2-0-b12074f4aca7@xxxxxxxxx
Changes in v2:
- rebase on the current MTD nand/next branch
- retain the merged protected-OOB allocation, BBM reservation and
stack-buffer fixes
- clarify that randomization is part of the normal hardware-ECC page
format while MTD_OPS_RAW continues to expose physical bytes
- explain why a BSP-compatible BBM remains randomized in physical raw data
- document the decoded bad-block and flash-BBT access paths
- reject the firmware OOB format with software or disabled ECC
- document the BSP page-format compatibility contract and the
older-controller format audit
- Link to v1: https://patch.msgid.link/20260810-submit-sunxi-nand-vendor-oob-layout-v1-v1-0-463853a14ad9@xxxxxxxxx
To: Miquel Raynal <miquel.raynal@xxxxxxxxxxx>
To: Richard Weinberger <richard@xxxxxx>
To: Vignesh Raghavendra <vigneshr@xxxxxx>
To: Chen-Yu Tsai <wens@xxxxxxxxxx>
To: Jernej Skrabec <jernej.skrabec@xxxxxxxxx>
To: Samuel Holland <samuel@xxxxxxxxxxxx>
To: Richard Genoud <richard.genoud@xxxxxxxxxxx>
To: Rob Herring <robh@xxxxxxxxxx>
To: Krzysztof Kozlowski <krzk+dt@xxxxxxxxxx>
To: Conor Dooley <conor+dt@xxxxxxxxxx>
To: Maxime Ripard <mripard@xxxxxxxxxx>
To: Masahiro Yamada <yamada.masahiro@xxxxxxxxxxxxx>
To: Boris Brezillon <bbrezillon@xxxxxxxxxx>
To: Brian Norris <computersforpeace@xxxxxxxxx>
Cc: linux-mtd@xxxxxxxxxxxxxxxxxxx
Cc: linux-arm-kernel@xxxxxxxxxxxxxxxxxxx
Cc: linux-sunxi@xxxxxxxxxxxxxxx
Cc: linux-kernel@xxxxxxxxxxxxxxx
Cc: devicetree@xxxxxxxxxxxxxxx
---
James Hilliard (18):
mtd: rawnand: sunxi: drain interrupts before reusing the completion
mtd: rawnand: sunxi: use the logical step's OOB length in PIO
mtd: rawnand: sunxi: propagate page-setup and erased-check errors
mtd: rawnand: sunxi: stop failed program operations and disable ECC
mtd: rawnand: sunxi: select the pattern ID for the current ECC step
mtd: rawnand: sunxi: propagate buffer and column transfer errors
mtd: rawnand: sunxi: avoid a second program confirm for OOB writes
mtd: rawnand: sunxi: avoid redundant column changes for extra OOB
mtd: rawnand: sunxi: use page reads to reposition small-page NAND
mtd: rawnand: sunxi: bound DMA batches by the user-data register bank
mtd: rawnand: sunxi: clarify OOB register and step handling
dt-bindings: mtd: sunxi: Add randomized OOB flag
mtd: rawnand: sunxi: support randomized OOB formats
mtd: rawnand: sunxi: select the packed H6/H616 OOB layout
mtd: rawnand: sunxi: combine contiguous unprotected OOB reads
mtd: rawnand: sunxi: avoid duplicate chip setup before page commands
mtd: rawnand: sunxi: reduce user-data length register accesses
mtd: rawnand: sunxi: reuse ECC status within each DMA read
.../bindings/mtd/allwinner,sun4i-a10-nand.yaml | 10 +
drivers/mtd/nand/raw/sunxi_nand.c | 1178 ++++++++++++++------
2 files changed, 846 insertions(+), 342 deletions(-)
---
base-commit: 7e874b1750a40f3dc9a629aeb72eba09c77f77e9
change-id: 20260810-submit-sunxi-nand-vendor-oob-layout-v1-e3114d10cc9c
Best regards,
--
James Hilliard <james.hilliard1@xxxxxxxxx>