From 7e42d9ec410a8006c813331ed041538b483ca6d1 Mon Sep 17 00:00:00 2001 From: Vasiliy Yakovlev Date: Sun, 24 May 2026 08:19:10 +0300 Subject: [PATCH] arm: hisilicon: add hi3516cv100 SoC support (DT + mach-hibvt) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds device-tree, DEMB board file, mach-hibvt entry, and ARCH_HI3516CV100 Kconfig for the Hi3516CV100 SoC family (V1 generation, ARM926EJ-S / ARMv5TE, the parent of the Hi3516CV200 family already supported in upstream-patches). cv100 is architecturally a strict subset of cv200 — same single ARM926EJ-S core, same SP804 dual-timers, same PL011 UARTs and PL022 SPI controllers, same hisi-femac ethernet, same FMC flash controller, same pinctrl-single pinmux block, all at identical MMIO addresses. The relevant difference for kernel boot is the VIC base — 0x10140000 on cv100 vs 0x100d0000 on cv200 — which is overridden in the cv100 dtsi via a label-based reference (&vic), reusing cv200's full DT scaffold via #include "hi3516cv200.dtsi". The CRG driver (drivers/clk/hisilicon/clk-hi3516cv200.c) handles cv100 unchanged — cv100's CRG register layout is a strict subset of cv200's (cv200 added a handful of extra clock gates for new peripherals that cv100 doesn't have). ARCH_HI3516CV100 just `select COMMON_CLK_HI3516CV200` and the existing "hisilicon,hi3518ev20x-clock" compatible matches both SoCs. The mach-hibvt entry reuses mach-hi3518ev20x.c (the cv200 mach file) verbatim, just adding "hisilicon,hi3516cv100" to its dt_compat array and the cv100 IO header to mach/io.h. HI_ZRELADDR is 0x80008000 (same as the rest of the V1/V2 ARMv5TE family). Sibling V1 SoCs (die-identical per qemu-hisilicon machine model decoding) can attach to this dtsi as overlays: Hi3518AV100, Hi3518CV100, Hi3518EV100. cv100's V1 single-controller register-poll i2c hardware is not driver-compatible with cv200's HiBVT i2c — the inherited i2c_bus0/1/2 DT nodes are explicitly marked disabled in hi3516cv100.dtsi. Boot does not depend on them; userspace can drive the sensor i2c MMIO directly via a separate kernel module if needed. Tested under qemu-system-arm -M hi3516cv100 with the OpenIPC userspace: - Boots to login prompt cleanly, no Oops/panic/BUG - hisi-femac eth0 link UP at 100Mbps/Full, DHCP from SLIRP obtains 10.0.2.15, ICMP echo to gateway 10.0.2.2 succeeds (~17ms) --- arch/arm/boot/dts/hisilicon/Makefile | 2 + .../boot/dts/hisilicon/hi3516cv100-demb.dts | 50 +++++++++++++++++++ arch/arm/boot/dts/hisilicon/hi3516cv100.dtsi | 40 +++++++++++++++ arch/arm/mach-hibvt/Kconfig | 17 +++++++ arch/arm/mach-hibvt/Makefile | 1 + arch/arm/mach-hibvt/include/mach/io.h | 8 +++ arch/arm/mach-hibvt/mach-hi3518ev20x.c | 1 + 7 files changed, 119 insertions(+) create mode 100644 arch/arm/boot/dts/hisilicon/hi3516cv100-demb.dts create mode 100644 arch/arm/boot/dts/hisilicon/hi3516cv100.dtsi diff --git a/arch/arm/boot/dts/hisilicon/Makefile b/arch/arm/boot/dts/hisilicon/Makefile index a491dcbba5b..8f75cf7456e 100644 --- a/arch/arm/boot/dts/hisilicon/Makefile +++ b/arch/arm/boot/dts/hisilicon/Makefile @@ -22,5 +22,7 @@ dtb-$(CONFIG_ARCH_HI3516CV300) += \ hi3516cv300-demb.dtb dtb-$(CONFIG_ARCH_HI3516CV200) += \ hi3516cv200-demb.dtb +dtb-$(CONFIG_ARCH_HI3516CV100) += \ + hi3516cv100-demb.dtb dtb-$(CONFIG_ARCH_HI3516AV100) += \ hi3516av100-demb.dtb diff --git a/arch/arm/boot/dts/hisilicon/hi3516cv100-demb.dts b/arch/arm/boot/dts/hisilicon/hi3516cv100-demb.dts new file mode 100644 index 00000000000..0d54b05c2c0 --- /dev/null +++ b/arch/arm/boot/dts/hisilicon/hi3516cv100-demb.dts @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * DTS for Hi3516CV100 DEMB (development reference) board. + * + * Memory: 64 MiB DDR2 at 0x80000000. The OS is given the lower 32 MiB + * (0x80000000-0x82000000); the upper 32 MiB are claimed at runtime by + * the openhisilicon mmz.ko allocator — matches the production cv100 + * load_hisilicon defaults (totalmem=64, osmem=32). The DT memory node + * advertises the OS-visible slice only. + */ + +/dts-v1/; +#include "hi3516cv100.dtsi" + +/ { + model = "HiSilicon Hi3516CV100 DEMB Board"; + compatible = "hisilicon,hi3516cv100-demb", "hisilicon,hi3516cv100"; + + memory@80000000 { + device_type = "memory"; + reg = <0x80000000 0x02000000>; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&uart0 { + status = "okay"; +}; + +&hisi_femac { + status = "okay"; + phy-mode = "mii"; + phy-handle = <&phy0>; +}; + +&mdio { + status = "okay"; + phy0: phy@0 { + reg = <0>; + }; +}; + +&fmc { + status = "okay"; + /* The flash node is populated via U-Boot or the bootloader; this + * placeholder keeps the controller probe path alive. */ +}; diff --git a/arch/arm/boot/dts/hisilicon/hi3516cv100.dtsi b/arch/arm/boot/dts/hisilicon/hi3516cv100.dtsi new file mode 100644 index 00000000000..3a834783d67 --- /dev/null +++ b/arch/arm/boot/dts/hisilicon/hi3516cv100.dtsi @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * HiSilicon Hi3516CV100 SoC family DT (V1 generation, ARM926EJ-S / ARMv5TE). + * + * Hi3516CV100 is the parent of Hi3516CV200 — same SoC architecture with + * a near-identical MMIO map. The only relevant difference for boot is + * the VIC base (0x10140000 vs cv200's 0x100d0000); CRG, sysctrl, UARTs, + * SP804 timers, PL022 SPI, FEMAC, FMC, pinmux all sit at identical + * addresses across the two families. Re-use cv200's full DT scaffold + * via #include and override the cv100-specific differences below. + * + * Sibling SoCs that re-use this dtsi (die-identical per qemu-hisilicon + * machine model decoding): Hi3518AV100, Hi3518CV100, Hi3518EV100. + */ + +#include "hi3516cv200.dtsi" + +/ { + compatible = "hisilicon,hi3516cv100"; +}; + +/* + * VIC moves on cv100 — overriding both the unit-address and reg property + * is straightforward via label-based references. The interrupt-controller + * type (pl190-vic) and cell layout are unchanged. + */ +&vic { + reg = <0x10140000 0x1000>; +}; + +/* + * cv100 has one I2C controller and uses the older register-poll + * "hisi-i2c-v1" hardware (not driver-compatible with cv200's HiBVT + * variant). Boot does not need it — the openhisilicon hi_i2c.ko + * userspace driver claims the same MMIO directly. Leave all i2c + * bus nodes disabled. + */ +&i2c_bus0 { status = "disabled"; }; +&i2c_bus1 { status = "disabled"; }; +&i2c_bus2 { status = "disabled"; }; diff --git a/arch/arm/mach-hibvt/Kconfig b/arch/arm/mach-hibvt/Kconfig index 81b93a74027..e4a8bc2aa02 100644 --- a/arch/arm/mach-hibvt/Kconfig +++ b/arch/arm/mach-hibvt/Kconfig @@ -47,6 +47,22 @@ config ARCH_HI3516CV200 Support for HiSilicon Hi3516CV200 / Hi3518EV20x V2 camera SoC family (ARM926EJ-S single-core, ARMv5TE). +config ARCH_HI3516CV100 + bool "Hisilicon Hi3516CV100 / Hi3518EV100 ARM926EJ-S family (V1)" + depends on ARCH_MULTI_V5 && CPU_LITTLE_ENDIAN + select ARM_VIC + select ARM_TIMER_SP804 + select PINCTRL + select COMMON_CLK_HI3516CV200 + select ARCH_HAS_RESET_CONTROLLER + select RESET_CONTROLLER + help + Support for HiSilicon Hi3516CV100 / Hi3518CV100 / Hi3518EV100 + V1 camera SoC family (ARM926EJ-S single-core, ARMv5TE). + Shares the V2 (Hi3516CV200) CRG driver — register layouts + match; VIC base is the only relevant MMIO difference, + overridden in the cv100 DTSI. + config ARCH_HI3516AV100 bool "Hisilicon Hi3516AV100 / Hi3516DV100 Cortex-A7 family" depends on ARCH_MULTI_V7 @@ -237,6 +253,7 @@ config HI_ZRELADDR default "0x80008000" if ARCH_HI3559V200 default "0x80008000" if ARCH_HI3516A default "0x80008000" if ARCH_HI3518EV20X + default "0x80008000" if ARCH_HI3516CV100 default "0x80008000" if ARCH_HI3536DV100 default "0x80008000" if ARCH_HI3521A default "0x40008000" if ARCH_HI3531A diff --git a/arch/arm/mach-hibvt/Makefile b/arch/arm/mach-hibvt/Makefile index 3d5214b7a1f..51770f67f47 100644 --- a/arch/arm/mach-hibvt/Makefile +++ b/arch/arm/mach-hibvt/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_ARCH_HI3516DV300) += mach-hi3516dv300.o obj-$(CONFIG_ARCH_HI3556V200) += mach-hi3556v200.o obj-$(CONFIG_ARCH_HI3559V200) += mach-hi3559v200.o obj-$(CONFIG_ARCH_HI3518EV20X) += mach-hi3518ev20x.o +obj-$(CONFIG_ARCH_HI3516CV100) += mach-hi3518ev20x.o obj-$(CONFIG_ARCH_HI3536DV100) += mach-hi3536dv100.o obj-$(CONFIG_ARCH_HI3521A) += mach-hi3521a.o obj-$(CONFIG_ARCH_HI3531A) += mach-hi3531a.o diff --git a/arch/arm/mach-hibvt/include/mach/io.h b/arch/arm/mach-hibvt/include/mach/io.h index 30ed0f85010..1fa67f2a1ed 100644 --- a/arch/arm/mach-hibvt/include/mach/io.h +++ b/arch/arm/mach-hibvt/include/mach/io.h @@ -9,6 +9,14 @@ #include #endif +#ifdef CONFIG_ARCH_HI3516CV100 +/* cv100 reuses cv200's mach file (mach-hi3518ev20x.c) — share its IO map. + * The IOCH1 range (0x10000000-0x100E0000) doesn't cover cv100's VIC at + * 0x10140000, but the iotable_init() entry is a virt-mapping cache hint; + * absence just means ioremap() is called per-driver, which still works. */ +#include +#endif + #ifdef CONFIG_ARCH_HI3536DV100 #include #endif diff --git a/arch/arm/mach-hibvt/mach-hi3518ev20x.c b/arch/arm/mach-hibvt/mach-hi3518ev20x.c index 9b302c660b6..8ed401c2a87 100644 --- a/arch/arm/mach-hibvt/mach-hi3518ev20x.c +++ b/arch/arm/mach-hibvt/mach-hi3518ev20x.c @@ -53,6 +53,7 @@ static void __init hi3518ev20x_map_io(void) iotable_init(hi3518ev20x_io_desc, ARRAY_SIZE(hi3518ev20x_io_desc)); } static const char *const hi3518ev20x_compat[] __initconst = { + "hisilicon,hi3516cv100", "hisilicon,hi3516ev200", "hisilicon,hi3516ev300", "hisilicon,hi3518ev300",