Skip to content

arm: hisilicon: add hi3516cv300 SoC support (CRG + DT + Kconfig)#42

Merged
widgetii merged 3 commits into
upstream-patchesfrom
feat/cv300-mainline
May 17, 2026
Merged

arm: hisilicon: add hi3516cv300 SoC support (CRG + DT + Kconfig)#42
widgetii merged 3 commits into
upstream-patchesfrom
feat/cv300-mainline

Conversation

@widgetii
Copy link
Copy Markdown
Member

Summary

Adds first-class hi3516cv300 (ARM926EJ-S / ARMv5TE) support to the openipc/linux upstream-patches base. cv300 is the only HiSi camera SoC with an ARMv5 entry in mach-hibvt and the only one with real mainline DT support — this PR brings it up to the same boot-on-modern-kernel level as ev300 / av300 / cv500.

Three commits, each independent:

  1. clk: hisilicon: rewrite hi3516cv300 CRG driver with full vendor topology — replaces the upstream stub (which only had uart/fmc/mmc/pwm muxes + 7 fixed-rate placeholders) with the full vendor clock tree: 28 fixed-rate roots, 14 muxes, 25 gates, 4 timer muxes via a sysctrl provider, no-op reset controller with explicit 2-cell xlate. Two CLK_OF_DECLARE entries make TIMER/APB/UART/ETH available before the platform_driver model is alive.
  2. arm: dts: hisilicon: add hi3516cv300 SoC and DEMB board — ported from the vendor 3.18 BSP, scrubbed for 6.x/7.x: drops removed skeleton.dtsi, adds clock-frequency = <3000000> on SP804 (works around sp804 driver reading clk_get_rate() == 0 at early init), clock-names = "mdio" on the hisi-femac-mdio node (modern driver uses named clk lookup), hisilicon,phy-reset-delays-us on the femac (required by the modern reset binding).
  3. arm: hibvt: add ARCH_HI3516CV300 Kconfig entry — gates the option on ARCH_MULTI_V5 + CPU_LITTLE_ENDIAN, selects the dependencies.

Test plan

Boots end-to-end under qemu-hisilicon -M hi3516cv300 with the cv300_neo firmware (separate PR against OpenIPC/firmware, depending on this one):

  • SP804 clock initializes (no clk_get_rate=0)
  • PL011 console reaches Welcome to OpenIPC
  • openipc-hi3516cv300 login: prompt appears
  • No Oops:, panic:, BUG:, Call Trace, or Unable to handle on console
  • FEMAC reset controller succeeds (no -EINVAL from reset_control_get)
  • DHCP obtains lease via udhcpc (10.0.2.15 / 10.0.2.2 in QEMU SLIRP)
  • NTP rolls wall clock forward

Stage-2 hardware verification (real cv300 board) gated on the firmware-side PR landing first.

Why now

Pre-existing cv300 stubs in this tree did not boot a modern kernel — the missing clock topology silently stalled the SP804 init and the missing reset xlate broke FEMAC. The vendor 3.18 DT carried these workarounds implicitly via legacy clock providers; the rewrite reconstructs that surface on the modern clk-of-declare path so the same DT compiles for both 3.18 and 7.x.

Companion PRs

  • OpenIPC/openhisilicon (kernel_compat.h shims + CI matrix row for cv300_neo) — coming next
  • OpenIPC/firmware (hi3516cv300_neo_defconfig + post-image script) — coming third; depends on this PR being mergeable so the upstream-patches tarball has the cv300 DT

cv300-neo-staging added 3 commits May 17, 2026 11:54
The upstream stub crg-hi3516cv300.c only declared a handful of muxes
(uart/fmc/mmc/pwm) plus seven fixed-rate placeholders, and never
registered a sysctrl provider — so the SP804 dual_timer probe walked
out via clk_get_rate() == 0, the FEMAC reset_control_get returned
-EINVAL because of_reset_n_cells defaulted to 1, and nothing on cv300
booted past pinctrl_init.

Replace the stub with the full vendor clock topology:

  - 28 fixed-rate roots (3/6/12/15/24/25/27/37.125/44/49.5/50/54/
    74.25/75/83.3/99/100/125/148.5/198/200/250/297/300/396/594/
    792/990 MHz)
  - 14 muxes (uart/fmc/mmc0-3/pwm/timer0-3/sensor/mipi)
  - 1 divider (eth)
  - 25 gates (apb/uart0-2/spi0-1/fmc/mmc0-3/eth*/dmac/pwm/usb*)
  - 4 timer muxes registered by a sysctrl provider so SP804 finds
    them via clk_of_declare's early init path

Two of_clk_init entries are added so the timer/console come up
before the platform_driver model is alive:

  - hisilicon,hi3516cv300-sysctrl  → TIMER fixed-rate (3 MHz)
  - hisilicon,hi3516cv300-crg      → APB / UART / ETH fixed-rate

The reset controller stays no-op but registers an explicit 2-cell
xlate so reset_controller_register stops forcing
of_reset_n_cells = 1 (which had been silently breaking FEMAC).

dt-bindings/clock/hi3516cv300-clock.h is expanded to cover the new
clock IDs the driver exports; the .dtsi (added in a later patch in
this series) and the vendor DTS both reference the same symbols, so
existing DT consumers compile unchanged.

Tested booting Linux 7.0 (openipc upstream-patches base) on cv300
under qemu-hisilicon: SP804 ticks, FEMAC DHCP, NTP succeeds. The
neo defconfig in firmware (separate PR) drives the integration.
Port the vendor 3.18 BSP cv300 device tree to a 6.x/7.x-clean form
and hook the DEMB reference board into the hisilicon dtb Makefile.

SoC dtsi (hi3516cv300.dtsi):
  - drop legacy skeleton.dtsi (removed upstream in 4.18)
  - SP804 dual_timer with explicit clock-frequency = <3000000>:
    upstream sp804 driver uses clk_get_rate() which returns 0 if
    the provider isn't fully initialized at start_kernel; the
    property short-circuits that for the pre-platform_driver path
  - hisi-femac-mdio: clock-names = "mdio" (modern devm_clk_get(dev,
    "mdio") needs a named clock; older bindings tolerated the
    nameless form)
  - hisi_femac: hisilicon,phy-reset-delays-us = <10000 10000 30000>
    required by the modern femac driver when a "phy" reset is
    declared

DEMB board (hi3516cv300-demb.dts):
  - 256 MiB DDR @ 0x80000000
  - bootargs configured for serial console + initrd handoff from
    U-Boot, matching the cv300 _neo firmware defconfig
  - phy@1 attached under &mdio with phy-mode = "mii", phy-handle
    wired into ethernet@10090000
  - sensor i2c/spi pinmux exposed for cv300 reference platforms

Tested under qemu-hisilicon -M hi3516cv300 with the cv300_neo
firmware: kernel boots through SP804 + PL011, mounts squashfs
initrd, FEMAC DHCP succeeds (10.0.2.15 / 10.0.2.2), NTP rolls
the wall clock forward, no console errors. ARCH_HI3516CV300 is
selected via the Kconfig change in the next patch.
Wire the cv300 SoC into the hibvt platform choice. Selects:

  - ARM_VIC, ARM_TIMER_SP804  — interrupt + timer hardware
  - PINCTRL                   — required by the cv300 pinctrl driver
  - COMMON_CLK_HI3516CV300    — 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
to gate the option only on configs that can actually compile cv300.
This is the only HiSi SoC family with an ARMv5 entry in mach-hibvt
upstream; everything else here is Cortex-A7 or newer.

After this patch, `make ARCH=arm hi3516cv300_neo_defconfig` boots
on real cv300 hardware and under qemu-hisilicon -M hi3516cv300.
@widgetii widgetii merged commit 75c37c9 into upstream-patches May 17, 2026
widgetii added a commit to OpenIPC/openhisilicon that referenced this pull request May 17, 2026
…w (issue #60) (#148)

* kernel: hi3516cv300: bring up V3 OSAL/peripherals against Linux 7.0

Issue #60 audited cv300 as the cleanest legacy platform — full OSAL
coverage, zero blobs that bypass OSAL for kernel APIs. The conclusion
was that a kernel bump only needs OSAL recompiled. This commit makes
that work concrete against the openipc/linux upstream-patches 7.0
base used by ev300_neo / av300_neo / cv500_neo.

The cv300 OSAL/init/peripheral sources reach into kernel APIs that
changed across the 3.18 -> 7.0 window. Per CLAUDE.md, we do NOT
sprinkle LINUX_VERSION_CODE through driver source — the changes route
through new shims in kernel/compat/kernel_compat.h, matching the
established convention used by cv500 (COMPAT_TIMER_SETUP /
COMPAT_USE_PROC_OPS / compat_access_ok / compat_vm_flags_set / etc.).

kernel_compat.h adds:

  - PDE_DATA()  macro on >= 5.17 (renamed to pde_data() in 5.17)
  - print_symbol() emulator for kernels after its 4.x removal
  - strlcpy()    redirect to strscpy() on >= 6.8 (where it was removed)
  - do_gettimeofday() + struct timeval emulator after their 5.0/5.6
    removals — uses ktime_get_real_ts64() under the hood
  - rtc_time_to_tm / rtc_tm_to_time redirect to the _64 variants on
    >= 5.6
  - DEFINE_SEMAPHORE() 1-arg variant on >= 6.4 (where it grew a count
    parameter; cv300 OSAL always wants count = 1)

cv300 sources updated to call the shims:

  - osal_proc.c   : proc_ops switch via COMPAT_USE_PROC_OPS
  - osal_timer.c  : timer_setup wrapper via COMPAT_TIMER_SETUP
  - osal_addr.c   : access_ok via compat_access_ok
  - osal_device.c : vm_flags via compat_vm_flags_set
  - mmz/media-mem.c, cma_allocator.c   : proc_ops + minor
  - himedia/base.c                     : platform_driver remove signature
  - peripherals (ir/pwm/rtc/sensor/wdt/sys_config): time/rtc/proc shims
  - init wrappers: ditto + base/sys/isp/ive/jpege/vedu/vgs/viu/vpss

osal_list.h gains `#define osal_list_head list_head` so the strict
type check introduced by list_is_head() upstream stops rejecting
osal_list_head*.

Verified end-to-end under qemu-hisilicon -M hi3516cv300 with the
companion openipc/linux feat/cv300-mainline merge and a draft
firmware cv300_neo defconfig (separate PRs): kernel reaches
\`openipc-hi3516cv300 login:\`, no Oops/panic/BUG/Trace, FEMAC DHCP
succeeds, NTP syncs the wall clock. Real-hardware verification is
deliberately deferred to a separate CI row + dev-board test once
the firmware PR lands.

* ci: add hi3516cv300_neo matrix row (Linux 7.0)

Mirror the existing av300_neo / cv500_neo 7.0 rows for cv300. The
prerequisites are now in place:

  - openipc/linux upstream-patches carries cv300 SoC support
    (CRG driver rewrite + DTS + ARCH_HI3516CV300 Kconfig — see
    OpenIPC/linux#42)
  - kernel/compat/kernel_compat.h shims cover every 3.18 -> 7.0
    delta the cv300 OSAL/peripheral source touches (PDE_DATA,
    print_symbol, strscpy, do_gettimeofday + struct timeval,
    rtc_time_to_tm, DEFINE_SEMAPHORE 1-arg) — added in the
    previous commit

The new row points at the cv300 source family (hi3516cv300) and
the cv300_neo firmware defconfig. The setup step is patterned on
av300_neo: it asserts the firmware-side defconfig is present
(hard error if not) and never tries to generate it inline — the
neo defconfig + post-image script live in the firmware repo
(OpenIPC/firmware, separate PR).

While the firmware PR is still in flight the row will fail at the
defconfig-presence check (red-then-green dance, same as av300_neo).
Once firmware lands the row will be green.

The CV300 qemu-boot row already exists and stays `allow-failure:
true` for the pre-existing cma_osal.ko/hi_osal.ko firmware naming
bug — that affects the legacy cv300_lite path and is orthogonal to
neo. The neo defconfig avoids the bug entirely because opensdk is
forced on (`# BR2_PACKAGE_HISILICON_OSDRV_HI3516CV300 is not set`).

---------

Co-authored-by: Vasiliy Yakovlev <vixand@openipc.org>
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