Skip to content

feat: add hi3516cv300 SoC family support#38

Merged
widgetii merged 1 commit intomainfrom
feat/hi3516cv300
Apr 11, 2026
Merged

feat: add hi3516cv300 SoC family support#38
widgetii merged 1 commit intomainfrom
feat/hi3516cv300

Conversation

@widgetii
Copy link
Copy Markdown
Member

Summary

  • Add V3 generation hi3516cv300/hi3516ev100 SoC family (ARM926EJ-S / ARMv5TE, kernel 3.18.20) as fourth CHIPARCH target
  • 29 kernel modules: OSAL-based architecture (like CV500), with raw .o blobs + init wrappers from SDK
  • 9 sensor libraries (ar0237, imx290, imx307, imx323, imx385, jxf22, ov2718, ov2718_2a, sc2235)
  • ISP algorithm source from Hi3516CV300 SDK V1.0.4.0
  • QEMU boot smoke-test CI job (qemu-system-arm -M hi3516cv300, verified locally to login prompt)

Key differences from other families

cv200 (V2) cv300 (V3) cv500 (V3.5) ev200 (V4)
OSAL no (mmz+himedia standalone) yes yes yes
H.265 no yes yes yes
Blob source .ko via objcopy raw .o + init from SDK raw .o + init from SDK raw .o
Peripheral base 0x20xxxxxx 0x12xxxxxx 0x12xxxxxx 0x12xxxxxx
Kernel 4.9 3.18 4.9 4.9–7.0

Test plan

  • Cross-compile 29 .ko modules with CHIPARCH=hi3516cv300 (0 errors, first attempt)
  • Local QEMU boot to login prompt
  • CI: hi3516cv300_lite build via OpenIPC firmware
  • CI: QEMU boot smoke-test

🤖 Generated with Claude Code

Add the V3 generation hi3516cv300/hi3516ev100 SoC family (ARM926EJ-S
/ ARMv5TE, kernel 3.18.20) as the fourth CHIPARCH target.

CV300 uses OSAL-based module architecture (like CV500), with V3
peripheral addresses (0x12xxxxxx). Supports H.264 + H.265 encoding.

Kernel modules (29 total, CHIPARCH=hi3516cv300):
- Source modules from Hi3516CV300 SDK V1.0.4.0: OSAL (with integrated
  MMZ + himedia), sys_config, mipi_rx, wdt, ir, pwm, rtc, sensor_i2c,
  sensor_spi
- Blob modules from SDK mpp/obj/ + mpp/init/ wrappers: base, sys, vi,
  vpss, venc, vedu, h264e, h265e, jpege, rc, rgn, vgs, ive, chnl, vo,
  ISP, audio chain (aio, ai, ao, aenc, adec, acodec)
- Cipher source included but not yet wired into kbuild

Libraries:
- 9 sensor drivers (ar0237, imx290, imx307, imx323, imx385, jxf22,
  ov2718, sc2235, ov2718_2a)
- ISP algorithm source (firmware + vreg)

Build system:
- kernel/hi3516cv300.kbuild: monolithic build config with OSAL
- kernel/Kbuild: four-way CHIPARCH branch (cv500/cv300/cv200/ev200)
- libraries/Makefile: CV300 sensor directory filtering

CI:
- Added hi3516cv300 to build matrix (hi3516cv300_lite board)
- Added qemu-cv300-boot smoke-test (boots to userspace, verified locally)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@widgetii widgetii merged commit 20882c6 into main Apr 11, 2026
13 checks passed
widgetii pushed a commit that referenced this pull request Apr 29, 2026
Live diagnosis on cv300 hardware (172.17.32.126, IMX323 i2c) showed
that MODULE_LICENSE alone wasn't enough — the cv300 port of these
two modules was missing module_init/module_exit registration entirely.
The init/exit functions exist as plain C functions (mipi.c lines 2209
and 2281; sensor.c's sensor_dev_init/exit) but were never wired up
through the module_init() / module_exit() macros, so insmod loaded the
.ko but the kernel never invoked their init paths. End result on the
camera:

  - /dev/hi_mipi never created (mipi_init's osal_registerdevice never
    runs)            → user-space "warning: open hi_mipi dev failed"
  - sensor_i2c "loads but does nothing" → SDK can't reach sensor

cv200, av100, 3519v101, cv500 all have these wrappers wired (see
kernel/mipi_rx/hi3516cv200/mipi.c:1520, kernel/sensor_i2c/hi3516cv200/
sensor_i2c.c:186, kernel/init/hi3516cv500/mipi_rx_init.c). cv300 was
a half-port from PR #38 / #59 — it shipped the bus drivers as functions
expected to be combined into one bigger module the way the vendor did,
but openhisilicon's split form left them inert.

mipi.c: register the existing mipi_init/mipi_exit through the module
macros and declare GPL license.

sensor.c: declare the three module params load_hisilicon already passes
on insmod (sensor_bus_type, sensor_clk_frequency, sensor_pinmux_mode);
add a no-op module_init/exit pair. The actual bus/sensor wiring stays
driven by user-space via the ISP callback path that already calls
sensor_dev_init() once g_stSensorDev[index]->stCtrlBus is populated —
the vendor's combined hi3516cv300_sensor.ko worked the same way.

Combined with the firmware-side fix in OpenIPC/firmware#2030 (ships
hi_sensor_spi.ko and pre-loads it before hi3516cv300_sensor.ko) and
the MODULE_LICENSE addition already in this PR, this brings cv300
end-to-end with the user's IMX323 i2c camera at 172.17.32.126.

Refs #62, #66.
widgetii added a commit that referenced this pull request Apr 30, 2026
…param wiring (#67)

* ci: fail QEMU smoke test on silent module-load regressions

The QEMU boot job's only assertion was `Starting crond: OK` — but
load_hisilicon can exit mid-sequence (e.g., after report_error from a
duplicate insmod) and still let init reach crond. CV200's QEMU log has
been printing `insmod: can't insert 'hi3518e_sys.ko': Operation not
permitted` for some time without the job ever turning red.

Add three negative grep checks alongside the existing positive one, run
on every platform in the matrix:

- `insmod: can't insert` — direct module-load failure.
- `Error: There's something wrong, please check!` — load_hisilicon's
  report_error exit (e.g., insmod hitting an already-loaded module due
  to a stale rmmod).
- `Cannot get chip id` — majestic's downstream symptom when sys is
  inactive.

Each failure path tails 50 lines of qemu-output.txt and names which
signal hit, so the matrix immediately reveals which platforms are
affected without having to download the artifact.

Refs #62.

* ci: replace insmod check with rmmod check to align with #62

The previous `insmod: can't insert` grep flagged a separate, pre-existing
bug on hi3516cv200 / hi3516av100 (the sys.ko blob's init returns -EPERM
when run under qemu-hisilicon's incomplete chip emulation — observed on
vendor-blob-only runs pre-#2021 too). #62's fix won't clear that.

The rmmod-by-vendor-name failure pattern *is* the #62 bug:

    rmmod: can't unload module 'mmz': No such file or directory
    rmmod: can't unload module 'hi_sensor_i2c': No such file or directory
    rmmod: can't unload module 'hi3516cv500_isp': No such file or directory

`remove_detect()` rmmods by vendor name; openhisilicon source modules
announce as open_* internally; the rmmods fail silently; the script
exits at `SENSOR=unknown`; crond starts; old assertion stayed green.

Switching to `^rmmod: can't unload` makes this PR a clean TDD harness
for #62: hi3516cv100, hi3516cv500, hi3519v101 turn red on the actual
bug, will turn green when source-module names are aligned. ev200 and
gk7205v200 stay green (already aligned). cv200 / av100 / cv300 don't
reach remove_detect in QEMU due to separate earlier failures and remain
green here — they need their own issue/test cycle.

* sensor_i2c/hi3516cv300: declare MODULE_LICENSE("GPL")

User-reported failure on real hi3516cv300 hardware (IMX323 over I2C,
OpenIPC 2.6.04.28-lite):

  open_sensor_i2c: Unknown symbol i2c_new_device (err 0)
  open_sensor_i2c: Unknown symbol i2c_unregister_device (err 0)

The kernel's `i2c_new_device` / `i2c_unregister_device` are
`EXPORT_SYMBOL_GPL`. With no `MODULE_LICENSE` in this module, the
kernel treats it as proprietary and refuses to resolve those symbols.

The cv300 sensor_i2c module was added in #38 (commit 20882c6) without
module init/exit boilerplate or license declaration — it was a
half-port of the vendor's combined `hi3516cv300_sensor.ko`, where the
top-level wrapper would have lived. Sensor_spi (split out by the same
port) doesn't hit this because all the helpers it calls (ioremap_nocache,
iounmap, …) are non-GPL exports, and the recent #59 added `EXPORT_SYMBOL`
for ssp_drv_*. The i2c branch of i2c_drv.c hits two GPL-only symbols
that have always required this license tag.

Verified live on hi3516cv300 hardware (172.17.32.126) reproducing the
user's `Unknown symbol i2c_new_device` failure. Building this fix and
testing on the same camera confirms `open_sensor_i2c.ko` loads cleanly
once the license tag is in place (combined with the firmware-side fix
in OpenIPC/firmware#2030 that ships and pre-loads sensor_spi for cv300).

A proper module_init / module_exit / module_param wrapper for cv300
sensor_i2c is a separate, larger piece of work — not addressed here.
The .ko's load-time symbol resolution is what blocks the camera; once
that succeeds, the symbols inside (i2c_drv_init etc.) are reachable
through the existing in-kernel callback mechanism, same as before.

Refs #62, #66.

* {mipi_rx,sensor_i2c}/hi3516cv300: add module_init/exit + MODULE_LICENSE

Live diagnosis on cv300 hardware (172.17.32.126, IMX323 i2c) showed
that MODULE_LICENSE alone wasn't enough — the cv300 port of these
two modules was missing module_init/module_exit registration entirely.
The init/exit functions exist as plain C functions (mipi.c lines 2209
and 2281; sensor.c's sensor_dev_init/exit) but were never wired up
through the module_init() / module_exit() macros, so insmod loaded the
.ko but the kernel never invoked their init paths. End result on the
camera:

  - /dev/hi_mipi never created (mipi_init's osal_registerdevice never
    runs)            → user-space "warning: open hi_mipi dev failed"
  - sensor_i2c "loads but does nothing" → SDK can't reach sensor

cv200, av100, 3519v101, cv500 all have these wrappers wired (see
kernel/mipi_rx/hi3516cv200/mipi.c:1520, kernel/sensor_i2c/hi3516cv200/
sensor_i2c.c:186, kernel/init/hi3516cv500/mipi_rx_init.c). cv300 was
a half-port from PR #38 / #59 — it shipped the bus drivers as functions
expected to be combined into one bigger module the way the vendor did,
but openhisilicon's split form left them inert.

mipi.c: register the existing mipi_init/mipi_exit through the module
macros and declare GPL license.

sensor.c: declare the three module params load_hisilicon already passes
on insmod (sensor_bus_type, sensor_clk_frequency, sensor_pinmux_mode);
add a no-op module_init/exit pair. The actual bus/sensor wiring stays
driven by user-space via the ISP callback path that already calls
sensor_dev_init() once g_stSensorDev[index]->stCtrlBus is populated —
the vendor's combined hi3516cv300_sensor.ko worked the same way.

Combined with the firmware-side fix in OpenIPC/firmware#2030 (ships
hi_sensor_spi.ko and pre-loads it before hi3516cv300_sensor.ko) and
the MODULE_LICENSE addition already in this PR, this brings cv300
end-to-end with the user's IMX323 i2c camera at 172.17.32.126.

Refs #62, #66.

* sensor_i2c/hi3516cv300: bus_type / pinmux_mode are strings, not ints

UART trace on real cv300 hardware showed:

  insmod: can't insert 'hi3516cv300_sensor.ko': Invalid argument

after the previous commit declared the script's params as int. The
load_hisilicon script for cv300 actually passes:

  sensor_bus_type="i2c"          (or "ssp")
  sensor_pinmux_mode="i2c_mipi"  (or "ssp_mipi", "i2c_dc", "ssp_dc")
  sensor_clk_frequency=37125000  (numeric, stays int)

The kernel module_param parser returns -EINVAL on `int` for non-numeric
values, which is what we hit. Switch the two string params to charp.
The clock frequency stays int.

Without this, insmod fails, cv300_sensor.ko never loads, the rest of
the boot continues but majestic dies on missing sensor → watchdog
times out and the camera reboots in a loop.

* Revert "mipi_rx/hi3516cv300: add module_init/exit + MODULE_LICENSE"

Live UART trace on real cv300 hardware showed that registering
mipi_init through module_init at insmod time panics the kernel —
the SSH session resets, watchdog reboots, the camera enters a boot
loop. cv200's mipi_init is wired the same way and works because
cv200 also installs a platform_driver that's resolved its IRQ
mapping via platform_get_irq() before mipi_init runs (cv200/mipi.c
:1533). cv500 ships the same pattern out-of-band as a separate
init/hi3516cv500/mipi_rx_init.c wrapper.

cv300's mipi.c hardcodes mipi_irq=28 at compile time, but inside
module_init the irq/register state isn't safely set up — request_irq
or the prior mipi_drv_init_reg() ioremap'd register write panics
the kernel before any printk reaches /dev/console.

The proper fix is to add a dedicated init/hi3516cv300/mipi_rx_init.c
that registers a platform_driver, gets the irq number from devicetree,
and calls mipi_rx_mod_init() from the probe — exactly what cv500 does.
That's separate work; reverting this drop here so the rest of the
sensor_i2c fix in #67 lands cleanly without bricking cv300 cameras.

The remaining cv300 user impact: open_sensor_i2c.ko now loads (the
fix this PR addresses), but /dev/hi_mipi still isn't created, so
majestic still fails on "open hi_mipi dev failed". That's a smaller
scope than the unbootable-camera regression caused by leaving this
module_init in.

Refs #62, #66.

---------

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.

2 participants