Skip to content

novatek: SPI NAND images for the NT98560, NT98562, NT98566 and NT98525 - #101

Merged
dimerr merged 5 commits into
openipc-novatekfrom
novatek/spi-nand
Nov 4, 2026
Merged

dimerr merged 5 commits into
openipc-novatekfrom
novatek/spi-nand

Conversation

@dimerr

@dimerr dimerr commented Nov 4, 2026

Copy link
Copy Markdown
Collaborator

Adds SPI NAND images for the NT98560, NT98562 and NT98566 (NA51089) and the NT98525 (NA51055). bash build.sh <soc>-nand builds output/u-boot-<soc>-nand.bin. The NOR images are unchanged.

Layout

This is the vendor SDKs' NAND board layout (cfg_*_IPCAM1_EVB), in 128 KiB blocks:

Offset Contents
0x0 loader, built with STORAGEINT=NandSpi
0x40000 device tree
0x80000 copy of the device tree (fdt.restore)
0xC0000 U-Boot, LZMA BCL1 (a 2 MiB partition)
0x2C0000 environment (two blocks, for one bad)
0x300000 UBI

The kernel gets mtdparts=spi_nand.0:2816k(boot),256k(env),-(ubi), and the environment works the same way as on the other OpenIPC SPI NAND targets (ubwrite/urwrite/loadkernel). The image file is 1 MiB. ${ubwrite} erases the 2816 KiB boot area and writes the image at 0.

Changes

  • nvt_spinand.c: the NT98633 driver gains the NA51089/NA51055 clock, reset, pin, pad and PHY-delay setup, following the vendor spinand.c drv_nand_reset() ("52x, 560" branch) and nand_phy_config(). The clock comes from the tree's /nand node (40 MHz).
  • Device trees: openipc/<soc>-nand.dts is the board's tree plus openipc/nvt-nand.dtsi. That file puts the partitions and the nvtpack index in /nand, where the NandSpi loader looks for them, disables and empties /nor, and sets nvt_info EMBMEM.
  • Image and config: nvt-image.py --nand packs the NAND layout. openipc/nand_config adds NAND, UBI and UBIFS and an 8 MiB malloc, and novatek.h holds the offsets.
  • NT98525 loader: built for NAND it is 34.5 KiB, over its 32 KiB limit, so it is built without its own SD card update (STORAGEEXT=NONE), as the NT98528's already is. U-Boot's SD recovery is unaffected.

Testing

Nothing has been tested on real hardware yet. Everything below was run in QEMU (qemu-hisilicon), where a 128 MiB image is a W25N01 and the mask ROM model runs the NandSpi loader from block 0:

  • All 20 images, NOR/NVR and NAND, pass the two-boot smoke test.
  • On each NAND SoC: a 3 MB nand write/read and a 2 MB ubi create/write/read compare equal. run ub (the image over TFTP), then reset, boots the rewritten image and the volume is still there.
  • On NT98562, run ur with a UBIFS rootfs carrying /boot/uImage (built from the nt98562 lite firmware), then bootflash, loads the kernel from UBIFS and starts it. The kernel then panics at the rootfs mount: the lite kernel is a NOR-only build with no SPI NAND or UBI drivers. A full NAND boot needs OpenIPC firmware built with them.

The CI legs are in a separate PR against openipc.

The same flash controller as NA51090's. Set its clock, reset, pins,
pads and PHY delay up as the camera SDKs' spinand.c drv_nand_reset()
("52x, 560") and nand_phy_config() do: CLKEN0/RSTN0 bit 0, the pins in
TOP+0x04 bit 13, the divider in CG+0x40, the controller's SRAM on, at
the tree's /nand clock (40 MHz); NA51089's sampling delay of 5, none on
NA51055 up to 96 MHz.
build.sh <soc>-nand builds u-boot-<soc>-nand.bin in the SDKs' NAND
layout (cfg_*_IPCAM1_EVB), 128 KiB blocks: the loader, built with
STORAGEINT=NandSpi, at 0; the tree at 0x40000 and its copy at 0x80000;
U-Boot at 0xC0000. The environment follows at 0x2C0000 and UBI from
0x300000, spi_nand.0:2816k(boot),256k(env),-(ubi), as on openipc-hisilicon.

The NAND trees are the boards' plus nvt-nand.dtsi: the loader takes its
partitions from /nand. The NT98525's NAND loader is 34.5 KiB with its SD
card update and goes without it (STORAGEEXT=NONE), as the 528 model's.
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Add SPI NAND boot images for four Novatek SoCs

✨ Enhancement ⚙️ Configuration changes 📝 Documentation 🕐 40+ Minutes

Grey Divider

AI Description

• Add SPI NAND boot images for NT98560, NT98562, NT98566, and NT98525 without changing NOR images.
• Extend controller initialization and align NAND device trees, partitions, and U-Boot configuration
 with vendor layouts.
• Document QEMU validation; physical-hardware testing remains outstanding.
Diagram

graph TD
  A["build.sh"] --> B["NAND config"] --> E["Image packer"] --> F[("SPI NAND")] --> G["NAND driver"] --> H["UBI boot"]
  A --> C["NandSpi loader"] --> E
  A --> D["NAND device tree"] --> E
  D --> G
  B --> G
Loading
High-Level Assessment

Extending the existing SPI NAND driver and image packer, while sharing a NAND device-tree include and config fragment, is preferable to duplicating those components per SoC. It preserves the NOR path and keeps the vendor layout defined consistently across targets. Hardware validation is still needed.

Files changed (12) +296 / -43

Enhancement (3) +136 / -34
build.shAdd four NAND build targets +41/-8

Add four NAND build targets

• Selects NAND-specific configuration, device trees, loader storage, image packing, and output paths for supported SoCs. Builds the NT98525 NAND loader without its SD update to meet its size limit.

build.sh

nvt_spinand.cInitialize SPI NAND hardware on NA51089 and NA51055 +63/-5

Initialize SPI NAND hardware on NA51089 and NA51055

• Adds die-specific clock, reset, pin, pad, SRAM, and PHY-delay setup while retaining the NA511XX path. Reads the requested clock from the NAND device-tree node.

drivers/mtd/nand/raw/nvt_spinand.c

nvt-image.pyPack images using the SPI NAND layout +32/-21

Pack images using the SPI NAND layout

• Adds NAND block sizing and offsets, writes a second device-tree copy, and ends NAND images at the packed U-Boot block boundary. Keeps the existing NOR layout as the default.

openipc/nvt-image.py

Documentation (1) +27 / -3
CLAUDE.mdDocument NAND layout, builds, and QEMU checks +27/-3

Document NAND layout, builds, and QEMU checks

• Describes the SPI NAND boot layout and build targets. Records QEMU smoke and NAND/UBI checks alongside the existing NOR guidance.

CLAUDE.md

Other (8) +133 / -6
KconfigEnable Novatek SPI NAND on additional dies +5/-5

Enable Novatek SPI NAND on additional dies

• Broadens the driver's Kconfig dependencies and help text to include NA51089 and NA51055 targets.

drivers/mtd/nand/raw/Kconfig

novatek.hDefine camera SPI NAND boot offsets +13/-1

Define camera SPI NAND boot offsets

• Adds the NAND boot-area erase/write command, partition list, and device count for the new camera targets.

include/configs/novatek.h

nand_configConfigure NAND environment and UBI boot support +26/-0

Configure NAND environment and UBI boot support

• Switches the NAND variants away from SPI NOR and enables raw NAND, partitions, UBI, and UBIFS. Sets the environment offset and range and raises the malloc allocation to 8 MiB.

openipc/nand_config

nt98525-nand.dtsAdd NT98525 NAND board tree +4/-0

Add NT98525 NAND board tree

• Combines the NT98525 board tree with the shared NAND boot-layout definitions.

openipc/nt98525-nand.dts

nt98560-nand.dtsAdd NT98560 NAND board tree +4/-0

Add NT98560 NAND board tree

• Combines the NT98560 board tree with the shared NAND boot-layout definitions.

openipc/nt98560-nand.dts

nt98562-nand.dtsAdd NT98562 NAND board tree +4/-0

Add NT98562 NAND board tree

• Combines the NT98562 board tree with the shared NAND boot-layout definitions.

openipc/nt98562-nand.dts

nt98566-nand.dtsAdd NT98566 NAND board tree +4/-0

Add NT98566 NAND board tree

• Combines the NT98566 board tree with the shared NAND boot-layout definitions.

openipc/nt98566-nand.dts

nvt-nand.dtsiShare loader-visible NAND partitions across boards +73/-0

Share loader-visible NAND partitions across boards

• Defines the loader, primary and restore device trees, and U-Boot partitions and pack index under '/nand'. Disables the NOR node and sets NAND EMBMEM metadata.

openipc/nvt-nand.dtsi

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Nov 4, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. A bad block in the boot area bricks the camera on update ✓ Resolved
Description
OPENIPC_UBWRITE writes the entire fixed-layout 1 MiB image with one nand write from offset 0,
allowing a skipped bad block to shift later components beyond their assigned partitions. If a block
before the device tree or U-Boot is bad, the loader still reads from the fixed offsets in /nand
and can encounter padding or the wrong data on the next boot.

Grey Divider

Tip of the day
💡 Did you know, you can commit Qodo's fix in one click with committable suggestions (GitHub & GitLab)

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

nand write skips a bad block and goes on in the next, so one write of
the whole image let a bad block in the boot area shift the device tree
or U-Boot off the offsets the loader reads. Write the loader, both
trees and U-Boot each at its partition's start, only as long as it is,
and have nvt-image.py leave every partition a spare block. Refuse an
image that is not past 0xC0000 (a NOR one) before erasing anything.

Under qemu, with block 0x40000 or 0xC0000 marked bad, run ub and reset
boot: the loader skips the bad block too.
@dimerr
dimerr merged commit 1fb2cdf into openipc-novatek Nov 4, 2026
36 checks passed
@dimerr
dimerr deleted the novatek/spi-nand branch November 4, 2026 05:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant