Repository navigation
Conversation
Single Cortex-A9 NVR/DVR SoC. Boots on real hardware (XiongMai NBD6808T-PL) from the stock 2010 U-Boot with an appended DTB, to an OpenIPC userspace shell on ttyAMA0. Addresses and interrupts follow the vendor 3.0.8 BSP. Details that differ from the existing QEMU-only 4.9 port: - The UARTs run from bus/4 (82.5 MHz with the APB source the bootloader selects in PERI_CRG57), not from the 24 MHz crystal. - 0x20700000 is HiSilicon's own L2 controller (vendor "hil2v200"), not a PL310: its ID register reads 0 and treating it as a PL310 hangs the boot. The bootloader leaves it off; no driver yet. - The SP805 watchdog at 0x20040000 runs at 3 MHz (measured). Clocks are fixed-clocks until there is a CRG driver.
The MAC reset line is only asserted and released around probe, and the reset API treats a missing optional reset as a no-op. SoCs without a reset controller driver yet (Hi3520DV200, whose "hieth-sf" up port is register-compatible with this MAC) can then probe the driver, as the PHY reset already allows.
bjorns163
force-pushed
the
hi3520dv200
branch
from
October 15, 2026 19:53
e028acd to
b493827
Compare
The Hi3520DV200's internal PHY answers at the address held in the low five bits of a system-control register, which reads 0 after power-on. Add a compatible for it, with that register as a second reg entry.
The Hi3520DV200's internal PHY answers at the address in bits 4:0 of
SYS_CTRL PERI24 (0x20050094). The register is 0 after power-on and only
the bootloader's network code sets it, so a kernel booted straight from
flash finds nothing at the address in the DT ("MDIO device at address 3
is missing", no eth0). Booting after a TFTP transfer hid this.
The existing internal-PHY path writes the address too, but then runs the
festa PHY trim, and this SoC has no trim data and a different PHY (id
0x001cc816). Its compatible therefore takes an address-only path: with
the register as the second reg entry, the driver writes the PHY address
from the DT before the bus is scanned.
Tested on an NBD6808T-PL by clearing the register in U-Boot before bootm:
the PHY is found at address 3 and the link comes up at 100 Mbps.
The Hi3520DV200 "hieth-sf" switch-fabric MAC has an up port at the block base and a down port at +0x2000, sharing global registers at +0x1300 and an MDIO controller at +0x1100. The up port's registers and bit layout match hisi-femac (MAC_PORTSEL/PORTSET/SET, the queue registers, and the up-port bits in FWCTRL, MACTCTRL, IRQ_ENA and the MAC filter), so it is described as a hisi-femac with the global block as its second region. On the NBD6808T-PL the RJ45 is on the up port through the SoC's internal PHY at MDIO address 3 (id 0x001cc816). Link comes up at 100 Mbps full duplex, with ping and bulk TCP transfers working.
The SPI-NOR controller in HiSilicon's Hi3520DV200 (hardware version 0x350) has the register layout of the v3xx parts this driver handles: GLB_CFG at 0x100 with the address-mode bit, interrupts at 0x120-0x12c, CMD_CFG/INS/ADDR at 0x300-0x30c with the same CMD_CFG fields, and the data buffer at 0x400 (16 words, which the driver already picks for versions below 0x351). Add an OF match for it, let it build on ARCH_HISI_BVT, and take the number of chip selects from the generic "num-cs" property: the ACPI parts expose one, while the Hi3520DV200 boards put their flash on CS1. Tested on a XiongMai NBD6808T-PL (8 MB MX25L6406E on CS1): reading every partition back gives the same bytes as a dump taken with the vendor bootloader; a full 8 MB read takes about 4.4 s in polling mode.
Describe the SFC v350 at 0x10010000 (driven by spi-hisi-sfc-v3xx) and, on the NBD6808T-PL, the 8 MB MX25L6406E on chip select 1 with the stock firmware's partition layout. All partitions are read-only while the board still carries its vendor firmware.
The Hi3520DV200's SATA controller is a standard two-port AHCI block, but its PHYs have to be clocked, released from reset and programmed before the AHCI core sees a link. Port the vendor 3.0.8 BSP's sequence (CONFIG_HI_SATA, 1.5 Gbps mode): clocks and the per-port bug-bypass setting, bus and PHY out of reset, PHY control/OOB values, the port PHY configuration, a PHY reset pulse and the core resets. The port PHY value defaults to HiSilicon's Hi3520D reference value and can be overridden with "hisilicon,phy-config"; XiongMai boards need the Hi3531/Hi3521 value their vendor firmware writes, without which the link keeps resetting. Tested on a XiongMai NBD6808T-PL with a 2.5" 320 GB disk: detected on the first attempt at boot, 63 MB/s writing and 75 MB/s reading 256 MB through ext4; with no disk both ports report link down within a second.
SATA at 0x10080000 with PERI_CRG45 as its clock/reset register, driven by ahci-hi3520dv200; the NBD6808T-PL uses the PHY value its vendor firmware writes. EHCI and OHCI at 0x100b0000/0x100a0000 are generic platform controllers; the bootloader already enables their clock and PHY (PERI_CRG46, PERI_USB) exactly as the vendor kernel does.
The Hi3520DV200's L2 cache at 0x20700000 is HiSilicon's own controller (the vendor BSP's "hil2v200"), not a PL310: maintenance is by physical address through INVALID/CLEAN registers or by whole way through an AUTO register, and a read of SYNC drains it. Port the vendor 3.0.8 driver as an outer cache (128 KB, 8 ways, 32-byte lines), brought up from the machine's init_irq where the core would initialise a PL310. Large clean and flush ranges fall back to whole-cache operations; invalidates never do. "nol2" on the command line leaves it off. On a XiongMai NBD6808T-PL, with the L2 on, DMA data stays intact (TFTP download, a random file written to SATA and read back after dropping caches, SPI-NOR reads and a 50 MB TCP send all match), and compared to nol2 on the same kernel gzip of 8 MB takes 4.99 s instead of 8.40 s and 256 MB ext4 writes run at 73 instead of 53 MB/s.
The restart handler loads 0 to make the watchdog fire at once. The SP805 in HiSilicon's Hi3520DV200 never resets the system with a load of 0: reboot ends in "Reboot failed -- System halted", and the board then stays hung even though a timeout had been running before the restart handler reprogrammed it. Loaded with 1 (LOAD_MIN, the smallest value wdt_setload() itself would program), the same watchdog resets the board immediately. Tested on a XiongMai NBD6808T-PL: "reboot -f" and a sysrq-triggered panic with panic=20 both come back to the bootloader.
A configuration for Hi3520DV200 NVR boards that fits the 2048 KB kernel partition of an 8 MB NOR layout (1537 KB zImage, xz, DTB appended for bootloaders without DT support): serial console, Ethernet, SPI-NOR with JFFS2/squashfs/overlayfs, SATA and USB storage with ext4/vfat, the hil2v200 L2 cache and the SP805 watchdog, with debugging aids, IPv6, VT and input left out. xz is 88 KB smaller than LZMA here and takes the same ~1 s to unpack.
The vendor bootloader can drive the display controller: "startvo 0 4 10" opens VGA at 1080p60 and "startgx 0 0x8f000000 3840 0 0 1920 1080" scans graphics layer 0 out of a buffer at 0x8f000000, as ARGB1555 with the alpha bit ignored. Describe that buffer as a simple-framebuffer (x1r5g5b5) and reserve it, so Linux can draw on the VGA output without a display driver. Without those bootloader commands the buffer is ordinary reserved memory and nothing is shown. Tested on the NBD6808T-PL: fbcon shows the kernel log at 240x67 on a VGA monitor and data written to /dev/fb0 appears on screen.
Enable simplefb with /dev/fb0, the VT and the framebuffer console, so a monitor on the VGA output shows the console when the bootloader has set the display up. 107 KB more: the zImage is 1644 KB of the 2048 KB partition.
Bootloaders on Hi3520DV200 boards (the vendor's and OpenIPC's) pass the flash layout as "mtdparts=hi_sfc:...", which the command-line partition parser only applies to an MTD device of that name. Through spi-mem the flash is named after the SPI device instead. Provide a get_name hook that returns the flash node's "label" when it has one, and the default name otherwise, so ACPI parts are unaffected.
Both the vendor and the OpenIPC bootloader describe this board's flash as "mtdparts=hi_sfc:...". With the label the command-line layout applies; the stock partitions in the DT remain as the fallback when the bootloader passes none.
Enable MTD_CMDLINE_PARTS so the bootloader's "mtdparts=" layout is used (the flash images OpenIPC builds rely on it), and WireGuard for remote access without exposing other services. WireGuard is a module, as on the other OpenIPC boards, so their userspace (which runs "modprobe wireguard") works unchanged; that needs MODULES and MODULE_UNLOAD. The zImage is 1712 KB of the 2048 KB partition, with 133 KB of modules on the root filesystem.
bjorns163
force-pushed
the
hi3520dv200
branch
from
October 18, 2026 14:06
b493827 to
b3b5c78
Compare
PROC_SYSCTL went with the other EXPERT trims, which left no /proc/sys:
OpenIPC's sysctl start-up failed ("Running sysctl: FAIL"), mdev could
not register as the hotplug helper, and nothing could set
net.ipv4.ip_forward, which routing over WireGuard needs. 18 KB: the
zImage is 1731 KB of the 2048 KB partition.
The board has 256 MB. The vendor firmware gave Linux the first 128 MB (mem=132M) and the rest to the MPP's media memory zone, and the DT copied that split. Without the MPP all of it is ordinary memory, apart from the VGA framebuffer at 0x8f000000, which is already reserved no-map. With 128 MB, eight camera streams through go2rtc left the system out of memory. With 256 MB, Linux reports 249560K available; 150 MB of random data in tmpfs reads back identical, and the framebuffer still registers.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds the Hi3520DV200, a single Cortex-A9 NVR/DVR SoC, to
upstream-patches, with a board DT for the XiongMai NBD6808T-PL (PCB MBD0157, 8 MB MX25L6406E). Unlike the other mach-hibvt ports, this one was brought up and tested on real hardware rather than in QEMU. It boots from the board's stock 2010 U-Boot (DTB appended, ATAGs) to the OpenIPC userspace.Nineteen commits:
arch/arm/mach-hi3520d), not from the existing 4.9 port. That port was QEMU-only and has two mistakes that stop real hardware:0x20700000is not a PL310. Its ID register reads 0, and probing it asarm,pl310-cachehangs the boot right after the errata line.net: hisilicon: hisi_femac: make the MAC core reset optional. The Hi3520DV200's "hieth-sf" switch-fabric MAC has an up port whose registers and bits match hisi-femac exactly (MAC_PORTSEL/PORTSET/SET, the queue registers, the up-port bits of FWCTRL/MACTCTRL/IRQ_ENA and the MAC filter). The global block sits at +0x1300 and is passed as hisi-femac's second region, and the MDIO block at +0x1100. There is no reset controller yet, so the MAC reset becomes optional, as the PHY reset already is.net: mdio: hisi-femac: set the Hi3520DV200 internal PHY address(with a dt-bindings commit). The internal PHY answers at the address in bits 4:0 of SYS_CTRL PERI24 (0x20050094). That register is 0 after power-on, and only the bootloader's network code sets it. So a kernel booted straight from flash finds no PHY:MDIO device at address 3 is missing, and no eth0. The driver's existing internal-PHY path also writes the address, but then runs the festa PHY trim, and this SoC has no trim data and a different PHY. The new compatible takes an address-only path, with the register as the MDIO node's secondregentry.spi: hisi-sfc-v3xx: support the Hi3520DV200 SFC v350 via device tree. The SFC v350 (hw version 0x350) has the register layout of the Kunpeng v3xx parts: GLB_CFG 0x100, interrupts 0x120–0x12c, CMD_CFG/INS/ADDR 0x300–0x30c with identical fields, and a 16-word data buffer at 0x400. The commit adds an OF match, allows the driver onARCH_HISI_BVT, and honoursnum-cs(the flash is on CS1).ata: add AHCI glue for the HiSilicon Hi3520DV200. A smallahci_platform-style driver. It runs the vendor PHY bring-up (clocks, the per-port bug-bypass value, PHY/OOB settings, reset sequence) and then hands the controller to the generic AHCI code. The port PHY value can be set withhisilicon,phy-config: XiongMai boards need0x0e262709(the Hi3531/Hi3521 value, which their stock kernel writes). With HiSilicon's Hi3520D reference value the link keeps resetting. This matches hi3520dv200: enable SCSI and the SoC's SATA controller firmware#2579 for the 3.0.8 kernel.ARM: hisilicon: add the hil2v200 L2 cache controller. HiSilicon's own L2 (128 KB, 8 ways, 32-byte lines), ported from the vendor driver as an outer cache. It is brought up from the machine'sinit_irq, where the core would set up a PL310.nol2on the command line leaves it off.watchdog: sp805: restart with a load of 1, not 0. This SoC's SP805 never resets with a load of 0. Before the change, a reboot ended inReboot failed -- System haltedand the board stayed hung. WithLOAD_MINit resets at once.hi3520dv200_defconfig. It fits the 2048 KB kernel partition of an 8 MB NOR layout: 1731 KB with everything below (xz, which is 88 KB smaller than LZMA here and unpacks in the same ~1 s). It also enablesMTD_CMDLINE_PARTS, which OpenIPC's flash images rely on, and WireGuard as a module (133 KB of.koon the rootfs), as on the other OpenIPC boards, so theirmodprobe wireguardstart-up works unchanged.ARM: configs: hi3520dv200: enable sysctl. RestoresPROC_SYSCTL, which the size trims had dropped. Without/proc/sys, OpenIPC's sysctl start-up fails, mdev cannot register as the hotplug helper, andnet.ipv4.ip_forwardcannot be set. 18 KB.ARM: dts: hi3520dv200: nbd6808t: describe all 256 MB of DDR. The vendor firmware gave Linux only the first 128 MB and kept the rest for the MPP's media memory. Without the MPP, all 256 MB is ordinary memory, apart from the VGA framebuffer, which stays reserved. With 128 MB, eight camera streams through go2rtc ran the system out of memory.spi: hisi-sfc-v3xx: name the flash after its DT labeland the board DT labelling its flashhi_sfc. Both the vendor and the OpenIPC bootloader pass the layout asmtdparts=hi_sfc:.... Through spi-mem the MTD device would otherwise be named after the SPI device, so the command-line layout never applied. The hook returns the DTlabelwhen there is one and the default name otherwise, so the ACPI parts are unaffected.startvo 0 4 10; startgx 0 0x8f000000 3840 0 0 1920 1080opens VGA at 1080p60 and scans graphics layer 0 out of a buffer at0x8f000000(ARGB1555, alpha bit ignored; checked with colour bands). The board DT describes that buffer as a reservedsimple-framebuffer(x1r5g5b5), and the defconfig enables simplefb,/dev/fb0and fbcon. That adds 107 KB. Without those bootloader commands the buffer is ordinary reserved memory and nothing is shown.Not covered: HDMI (the bootloader's
startvodoes not start the HDMI transmitter), display-controller set-up from Linux itself, and the video decoder. Those depend on the vendor's MPP modules, which exist only for 3.0.8. There is no CRG/clock driver yet; the DT uses fixed-clocks matching the bootloader's PLL settings.Test plan
All on a XiongMai NBD6808T-PL, RAM-booted from the stock U-Boot (uImage of zImage + DTB at 0x80008000, OpenIPC hi3520dv200 rootfs as an initrd). The flash was not written; its partitions were read-only in the DT.
hi3520dv200_defconfigbuilds from scratch, and every commit in the series builds on its own/dev/pts/00x001cc816); a 50 MB TCP send arrives complete at 11.7 MB/s; a TFTP download's md5 matchesmw.l 0x20050094 0) right beforebootm, giving the power-on state of a plain flash boot. The driver writes address 3, the PHY attaches at10091100.mdio:03, the link comes up, and a 20 MB transfer over SSH arrives complete. Before the change, a boot from flash showedMDIO device at address 3 is missingand no eth0hw version 0x350; the bootloader, kernel, application and logo partitions read back byte-identical to a dump taken with the vendor bootloader (the jffs2 settings partition differs only because the stock firmware rewrote it since); full 8 MB in 4.4 snol2. gzip of 8 MB takes 4.95 s instead of 8.40 s, and ext4 writes run at 73 instead of 53 MB/s. All the DMA checks above pass with the L2 onreboot -fand a sysrq-triggered panic withpanic=20both reset the board to the bootloader/dev/fb0appears on screen; checked with the defconfig build (1643 KB zImage)hi3520dv200_neodefconfig, see below) RAM-booted withmtdparts=hi_sfc:256k(boot)ro,64k(env)ro,2048k(kernel)ro,5120k(rootfs)ro,-(rootfs_data)rogives5 cmdlinepart partitions found on MTD device hi_sfc, withboot,env,kernel,rootfsandrootfs_dataat the expected offsetsRunning sysctl: OK(it wasFAIL),kernel.printkis applied,/proc/sys/kernel/hotplugis/sbin/mdev, and/proc/sys/net/ipv4/ip_forwardexistsmem=256M,Memory: 249560K/262144K available, the framebuffer is still reserved and registers, and 150 MB of random data in tmpfs reads back identical. An eight-camera go2rtc load peaks at 115 MB with 79 MB still freecheckpatch.pl --strictclean apart from MAINTAINERS and Signed-off-by notesA sibling OpenIPC/firmware PR adding a
hi3520dv200_neovariant will follow.