arm: hisilicon: add hi3516cv200 / hi3518ev20x SoC support (CRG + DT + Kconfig)#43
Merged
Merged
Conversation
V2 generation (ARM926EJ-S, ARMv5TE) SoC family — Hi3516CV200,
Hi3518EV200, Hi3518EV201 — all share the same CRG layout at
0x20030000 and the same sysctrl block at 0x20050000. The vendor 4.9
BSP drove these via drivers/clk/hisilicon/clk-hi3518ev20x.c; port
the full clock topology onto the modern crg- platform_driver scaffold
that crg-hi3516cv300.c established for the V3 sibling.
Adds:
- 25 fixed-rate roots (3 / 6 / 24 / 25 / 27 / 37.125 / 49.5 / 50 /
54 / 74.25 / 99 / 125 / 148.5 / 198 / 200 / 250 / 297 / 300 /
396 / 540 / 594 / 600 / 650 / 750 / 1188 MHz)
- 5 muxes (uart/fmc/mmc0-1/eth)
- 1 divider (sysapb)
- 13 gates (uart0-3, spi0-1, fmc, mmc0-1, eth, dmac, usb2 utmi/hrst)
- 4 sysctrl timer muxes registered via a separate provider
Two CLK_OF_DECLARE entries make TIMER/APB/UART/ETH available before
the platform_driver model is alive, so SP804 / PL011 / FEMAC don't
defer-forever or read clk_get_rate() == 0:
- hisilicon,hi3518ev20x-sysctrl → TIMER fixed-rate (3 MHz)
- hisilicon,hi3518ev20x-clock → sysapb / UART0-3 / ETH fixed-rate
The reset controller stays no-op but registers an explicit 2-cell
xlate so reset_controller_register doesn't force of_reset_n_cells = 1
(which had silently broken FEMAC on cv300 before that same fix —
this avoids the same trap on cv200).
dt-bindings/clock/hi3516cv200-clock.h is the matching clock-ID
header; the DT added in a later patch in this series references it
verbatim from cv200 + sibling boards.
Tested booting Linux 7.0 on a hi3516cv200 machine model under
qemu-hisilicon: SP804 ticks, FEMAC DHCP succeeds (10.0.2.15 / 10.0.2.2
via SLIRP), userspace reaches \`openipc-hi3516cv200 login:\`, no
Oops / panic / BUG / Trace.
Port the vendor 4.9 BSP hi3518ev20x DT to a 7.x-clean form and hook
the DEMB reference board into the hisilicon dtb Makefile. Same SoC
family as the vendor BSP (Hi3516CV200 / Hi3518EV200 / Hi3518EV201);
keep the vendor compatible strings ("hisilicon,hi3518ev20x-clock",
"-sysctrl") so the BSP DT remains drop-in compatible with this driver.
SoC dtsi (hi3516cv200.dtsi):
- drop legacy skeleton.dtsi (removed upstream in 4.18)
- SP804 dual_timer with explicit clock-frequency = <3000000>:
sp804 driver reads clk_get_rate() during start_kernel; without
the property it would see 0 and refuse to register
- hisi-femac-mdio: clock-names = "mdio" (modern devm_clk_get(dev,
"mdio") needs a named clock; older bindings tolerated nameless)
- hisi_femac: hisilicon,phy-reset-delays-us = <10000 10000 30000>
required by the modern femac driver when a "phy" reset is
declared
DEMB board (hi3516cv200-demb.dts):
- 64 MiB DDR @ 0x80000000 — matches production cv200 cameras that
typically ship with 64 MiB total. The vendor mmz allocator is
expected to claim the upper 32 MiB via `mmz=...` bootargs; the
kernel uses 32 MiB.
- bootargs configured for serial console + initrd handoff from
U-Boot, matching the (future) cv200_neo firmware defconfig
- phy@1 attached under &mdio with phy-mode = "mii"
- i2c_bus0 / spi_bus0 / uart0 enabled for cv200 reference platforms
Tested under qemu-hisilicon -M hi3516cv200 with a minimal initramfs:
kernel boots through SP804 + PL011, mounts squashfs initrd, FEMAC
DHCP succeeds, ntpd syncs the wall clock, no console errors.
ARCH_HI3516CV200 is selected via the Kconfig change in the next
patch in this series.
Wire the V2 SoC family (Hi3516CV200 / Hi3518EV200 / Hi3518EV201) into
the hibvt platform choice. Selects:
- ARM_VIC, ARM_TIMER_SP804 — interrupt + timer hardware
- PINCTRL — required by hibvt pinctrl
- COMMON_CLK_HI3516CV200 — the CRG driver added earlier in this
series
- ARCH_HAS_RESET_CONTROLLER + RESET_CONTROLLER — femac resets
Depends on ARCH_MULTI_V5 (ARM926EJ-S, ARMv5TE) + CPU_LITTLE_ENDIAN
— matches the existing ARCH_HI3516CV300 sibling.
After this patch, the kernel boots end-to-end on the cv200 machine
model in qemu-hisilicon. Real hardware verification is gated on the
openhisilicon-side OSAL shim work that resolves blob-import gaps for
do_gettimeofday / register_sysctl_table / strlcpy on modern kernels
(separate openhisilicon PR, doesn't affect the kernel-side support
landing here).
widgetii
added a commit
to OpenIPC/openhisilicon
that referenced
this pull request
May 22, 2026
…set (#170) PRs #162 and #165 landed the initial V2/V2A bring-up shims based on the issue #50 audit (4 symbols for cv200, 3 for av100). Exercising the real firmware build for the first time (hi3516cv200_neo via the upstream-patches 7.0 base) surfaced 8 more undefined symbols that issue #50 missed — the audit only covered blob source-imports, not the compiler-generated calls (memset → __memzero, kmalloc → __kmalloc internal slowpath, etc.) and not the symbols pulled in via inline- function expansion at blob-build time against the 4.9 kernel headers. This commit extends both shims (V2 cv200 + V2A av100) to cover every symbol modpost reports as undefined for the V2/V2A blob set on Linux 7.0. Verified empirically: hi3516cv200_neo now builds, boots in QEMU to a login prompt, and meets the openipc/firmware QEMU DoD (eth0 link, DHCP via SLIRP, ping 10.0.2.2). hi3516cv200_lite and hi3516av100_lite (kernel 4.9 production targets) rebuilt against this tree are byte-equivalent to nightly: - cv200_lite: 331/331 rootfs files, 68/68 hisilicon .ko, sets identical - av100_lite: 290/290 rootfs files, 61/61 hisilicon .ko, sets identical kernel/compat/kernel_compat.h adds: - pte_offset_map(pmd, addr) -> pte_offset_kernel(...) on >= 6.5. Modern pte_offset_map() inlines to __pte_offset_map() which is NOT EXPORT_SYMBOL'd, so modules can't link it. pte_offset_kernel is a static inline over pmd_page_vaddr() + pte_index() — same user-page-table lookup the legacy code already did without locking. Source-side fix because the call is in our own cv200/av100 mmz-userdev usr_virt_to_phys, not the blob. Both shim modules add the following exports (gated >= 5.0 so 4.9 lite stays a no-op shell): Symbol Modern equivalent we forward to ────────────────── ─────────────────────────────────────── _cond_resched __cond_resched __kmalloc __kmalloc_noprof (6.5+) kmem_cache_alloc kmem_cache_alloc_noprof (7.0 macro) __memzero memset(ptr, 0, n) PDE_DATA pde_data (5.17 rename) printk vprintk via _printk (6.0 rename) register_sysctl_paths register_sysctl_sz / register_sysctl jiffies_to_msecs (MSEC_PER_SEC / HZ) * j — header inline del_timer timer_delete (7.0 rename) vmalloc vmalloc_noprof (7.0 macro) dev_err dev_vprintk_emit at KERN_ERR sched_setscheduler sched_set_fifo / sched_set_normal — caller priority is dropped (sched_set_fifo doesn't accept one); SCHED_RR mapped to FIFO. Best- effort for legacy blobs that just want "raise above SCHED_NORMAL". Two header-collision cases needed a Kbuild-level macro rename (passed as -D... in CFLAGS_) so the static-inline definition in <linux/sched.h> / <linux/jiffies.h> doesn't conflict with our EXPORT_SYMBOL'd function under the same name: - _cond_resched (static inline since 5.10 preempt-dynamic rework; commit fe32d3cd5e8e) - jiffies_to_msecs (static inline when HZ | MSEC_PER_SEC — HZ=100 production config) For the macro-style conflicts (kmem_cache_alloc, vmalloc, PDE_DATA, printk, dev_err, del_timer) #undef in the shim source is sufficient. Out of scope for this commit (still tracked in issue #51): - struct timer_list .data ABI drift (chnl/viu/vpss blobs) — the shim resolves init_timer_key but timers don't fire with the correct argument until the blob is recompiled. Documented in both shim sources. Surfaces as broken video pipeline on cv200_neo / av100_neo; not a load-time error. - hi3516av100 mainline DT / CRG — av100_neo firmware target is blocked on a separate openipc/linux PR (av100 has no mainline Kconfig / DT / clock-driver support yet, unlike cv200 which landed in OpenIPC/linux#43). cv200_neo unblocked. Co-authored-by: Vasiliy Yakovlev <vixand@openipc.org> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4 tasks
widgetii
added a commit
that referenced
this pull request
May 22, 2026
#44) * arm: hisilicon: add hi3516av100 / hi3516dv100 SoC support (CRG + DT + Kconfig) V2A generation (Cortex-A7, ARMv7) SoC family — Hi3516AV100 and the pin-compatible Hi3516DV100. Same shape as the V2 cv200 / 3518ev20x support landed in #43 except this one is ARMv7 with GIC + arch-timer instead of VIC + SP804. Adds: - drivers/clk/hisilicon/crg-hi3516av100.c (~330 lines): ported from the 4.9 vendor BSP clk-hi3516a.c onto the modern crg- platform_ driver scaffold (mirroring crg-hi3516cv200.c). - 34 fixed-rate roots (3 / 6 / 13.5 / 24 / 25 / 27 / 37.125 / 50 / 74.25 / 75 / 99 / 100 / 125 / 145 / 148.5 / 150 / 194 / 198 / 200 / 229 / 237 / 242 / 250 / 297 / 300 / 333 / 400 / 500 / 594 / 600 / 750 / 900 / 1000 / 1188 MHz) - APLL stub fixed-rate at 850 MHz (mid of vendor OPP table) — full PLL programming is a follow-up; the kernel boots fine with the U-Boot-configured CPU rate. - 9 muxes (sysaxi, snor, snand, nand, mmc0/1, uart, eth_phy, a7) - 1 fixed-factor (clk_sysapb = sysaxi_mux / 4) - 15 gates (snor/snand/nand, mmc0/1, usb utmi/hrst, uart0-3, eth + eth_macif, spi0-1, dmac) - CLK_OF_DECLARE early init for sysctrl timer slots (8 entries — av100 exposes TIME0_0..TIME3_7 vs cv200's 4) and early UART / ETH consumers needing clk_get during start_kernel before platform_driver probing. - Noop reset-controller with 2-cell xlate so higmac probe doesn't defer forever waiting for resets. - arch/arm/boot/dts/hisilicon/hi3516av100.dtsi (~290 lines): - GIC v2 at 0x20300000 (cortex-a7-gic). - Architected ARM generic timer (arm,armv7-timer) — av100 has Cortex-A7 generic timer; SP804 dual_timer is exposed but disabled by default and only board files can enable. - PL011 uart0-3, PL022 spi0/1, PL061 gpio0-3 (vendor BSP wires 16 GPIO chips; mainline port enables 4 — sufficient for a DEMB board; rest can be added per-board). - hisi-i2c-hisilicon i2c_bus0-2, hisi-spi-nor controller. - higmac ethernet at 0x10090000 with MDIO sub-node — distinct from cv200/cv300's femac. - himci mmc0/1 at 0x206e0000/0x206f0000. - Skeleton.dtsi removed (4.18+ convention; explicit #address-cells/#size-cells on root). - arch/arm/boot/dts/hisilicon/hi3516av100-demb.dts (~95 lines): Reference board — 1 GiB RAM at 0x80000000, single Cortex-A7 Linux CPU (vendor BSP layout, even though the SoC has 2 cores), UART0 console at 115200n8, higmac + MDIO ethphy@1 rgmii. - include/dt-bindings/clock/hi3516av100-clock.h: clock IDs. - arch/arm/mach-hibvt/Kconfig: ARCH_HI3516AV100 entry. depends on ARCH_MULTI_V7. selects HAVE_ARM_ARCH_TIMER, ARM_GIC, COMMON_CLK_HI3516AV100, ARCH_HAS_RESET_CONTROLLER. Note: does NOT select ARM_TIMER_SP804 because arch-timer is preferred on this SoC (Cortex-A7 generic timer). - drivers/clk/hisilicon/Kconfig: COMMON_CLK_HI3516AV100 entry. - drivers/clk/hisilicon/Makefile: register the new object. - arch/arm/boot/dts/hisilicon/Makefile: register the demb.dtb. After this patch, the kernel boots end-to-end on an av100 board. Real hardware verification is gated on the openhisilicon-side OSAL shim work (#170 expanded the V2A blob-symbol set) and on a separate firmware-side av100_neo defconfig — neither block landing this kernel-side support. Co-authored-by: Vasiliy Yakovlev <vixand@openipc.org> Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * net: hisilicon: add hisi_higmac driver for hi3516av100 GMAC Minimal mainline platform driver for the higmac (Gigabit Ethernet MAC) IP block used on Hi3516AV100 / Hi3516DV100. The vendor 4.9 BSP carries a 3000-line driver in drivers/net/ethernet/hisilicon/higmac/ with TSO, EEE, AVS, multicast filters, statistics, ethtool, PM, etc. This port strips everything except the descriptor-ring TX/RX path that QEMU emulates and that real hardware needs to boot — sufficient for ifup, DHCP, and ping; production features can be layered on later. Register layout follows the QEMU machine model (qemu-hisilicon hw/net/hisi-gmac.c) which mirrors the vendor IP: 0x0000 STATION_ADDR_LOW MAC address 0x0004 STATION_ADDR_HIGH 0x0040 PORT_MODE 100M full hardcoded for QEMU 0x0044 PORT_EN bit1 RX_EN | bit2 TX_EN 0x0064 REC_FILT_CONTROL permissive (BIT_CRC_ERR_PASS) 0x03C0 MDIO_SINGLE_CMD embedded mii_bus 0x03C4 MDIO_SINGLE_DATA 0x0500 RX_FQ_* (free queue) SW pushes empty buffers 0x0520 RX_BQ_* (buffer queue) HW pushes received frames 0x0580 TX_BQ_* (send queue) SW pushes outgoing 0x05A0 TX_RQ_* (reclaim queue) HW pushes completions 0x05C0 RAW_PMU_INT IRQ status (W1C) 0x05C4 ENA_PMU_INT IRQ mask 0x05CC DESC_WR_RD_ENA master DMA enable (0xF = all on) Driver structure mirrors hisi_femac.c — platform_driver, single NAPI instance (weight 64), devm clk/reset acquisition, of_phy_get_and_connect via embedded mdio sub-node, dma_alloc_coherent ring memory. MDIO is at offset 0x3c0 of the same MMIO region as the MAC (vendor used a separate hisilicon,hisi-gemac-mdio platform device for this; mainline registers the mii_bus inline since the MMIO range is contiguous). DT bindings: reg — single MAC MMIO range interrupts — combined IRQ clocks/clock-names — "higmac_clk" + "macif_clk" (both optional) resets/reset-names — "port_reset" + "macif_reset" (both optional) phy-handle — reference to mdio child's PHY node phy-mode — "rgmii" / "mii" / "rmii" mac-address — from DT or random fallback DTSI delta: drops the separate hisilicon,hisi-gemac-mdio node and folds an mdio sub-node into the higmac itself; the demb.dts moves the ethphy@1 into that sub-node. Matches the mainline-friendly layout for GMAC + MDIO sharing one MMIO range. Out of scope (vendor driver has, mainline port doesn't): - TSO / GSO / GRO (NAPI uses napi_gro_receive so GRO works transparently — no driver-side TSO). - COE checksum offload bits (TSO_COE_CTRL register). - EEE / autoEEE (separate vendor sub-directory). - AVS (adaptive voltage scaling). - Statistics / ethtool / WoL / coalescing tuning. - Multicast hash table — driver runs permissive (broadcast + multicast pass; effectively promiscuous in steady state). Filter tightening would be a follow-up. - PM suspend/resume — leaves the IP at HW defaults across suspend. Verified clean compile under `make W=1` against Linux 7.0, ARM target, OpenIPC toolchain. Real-hardware verification is gated on the hi3516av100_neo firmware-side bring-up (separate openipc/firmware PR), which uses this driver and validates QEMU smoke + login + ping. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Vasiliy Yakovlev <vixand@openipc.org> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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 first-class support for the V2 generation HiSilicon camera SoC family — Hi3516CV200, Hi3518EV200, Hi3518EV201 (ARM926EJ-S, ARMv5TE) — to the openipc/linux upstream-patches base. Mirrors the structure of #42 (cv300) so V2 and V3 share the same shape: CRG driver + DT + ARCH Kconfig, all keyed by sibling-compatible strings so the vendor 4.9 BSP DT is drop-in compatible with this driver.
Three commits, each independent:
Test plan
Boots end-to-end under `qemu-system-arm -M hi3516cv200` (qemu-hisilicon master, machine model added previously), kernel pulled via this branch + nightly hi3516cv200 rootfs (vendor blob .ko load deliberately stubbed; that's an openhisilicon-side concern, not a kernel-side blocker):
Stage-2 hardware verification on a real Hi3516CV200 board is gated on the firmware-side PR that bundles this kernel with the new OSAL-shim module from openhisilicon — separate PR.
Companion PRs
Why now
cv200 was issue #46 in OpenIPC/openhisilicon — V2 has no OSAL layer, so historically it was locked to kernel 4.9. The blob struct-drift wall the issue called out (init_timer_key with `struct timer_list.data`) turns out to only affect the video pipeline blobs; everything below — kernel boot, network, userspace, audio — works fine on 7.0 with the right CRG + DT + shim plumbing. This PR lands the kernel side.