Skip to content

Add gk7202v300_lite_generic-w7 device profile (GK-W7, GC2053-DVP, SSV6006C Wi-Fi) - #119

Merged
widgetii merged 2 commits into
OpenIPC:masterfrom
bneigher:gk7202v300-lite-w7-8m
Aug 29, 2026
Merged

Add gk7202v300_lite_generic-w7 device profile (GK-W7, GC2053-DVP, SSV6006C Wi-Fi)#119
widgetii merged 2 commits into
OpenIPC:masterfrom
bneigher:gk7202v300-lite-w7-8m

Conversation

@bneigher

Copy link
Copy Markdown
Contributor

Add gk7202v300_lite_w7_8m device profile (GK-W7, GC2053-DVP, SSV6006C Wi-Fi)

Adds a device profile for the GK-W7 board — GK7202V300, 8 MB NOR, product string
ipc533331a-W7-gc2053dvp-f8. Answers OpenIPC/firmware#2074, where @widgetii asked
for this as a builder profile rather than a change to the generic targets.

Hardware, and how it differs from the generic gk7202v300_lite target:

  • GC2053 wired in DVP (parallel) mode, SID strapped HIGH (7-bit i2c 0x3f).
    The generic target assumes MIPI + SID=0, so out of the box the i2c controller
    is muxed to pads that are not connected to the sensor: every address NACKs, no
    chip ID, no video.
  • iComm/SSV SSV6006C USB Wi-Fi, USB ID 8065:6000. The generic Lite target
    ships only mt7601u, which is MediaTek silicon and will never bind this part —
    ip link shows lo and nothing else.
  • No Ethernet PHY (femac ... connect to PHY failed in dmesg is expected here).

What is in the profile

  • br-ext-chip-goke/configs/gk7202v300_lite_w7_8m_defconfig — mirrors
    gk7202v300_lite_cootli_camv0103 (same SoC, same Wi-Fi family) with
    BR2_PACKAGE_SSV635X_OPENIPC=y. Drops BR2_PACKAGE_MOTORS — W7 is fixed-lens.
  • general/overlay/usr/share/openipc/customizer.shwlandev ssv6x5x-generic,
    sensor gc2053, opt-in sensor_dvp=1 / sensor_mclk=24, and pins
    .isp.sensorConfig to the DVP ini explicitly rather than relying on ini-glob
    ordering.
  • general/overlay/etc/wireless/usb — the ssv6x5x-generic branch.
  • general/overlay/etc/sensors/gc2053_i2c_dc_1080p.ini — DVP variant
    (input_mode=INPUT_MODE_CMOS, Input_mod=VI_MODE_DIGITAL_CAMERA, Isp_Bayer=0
    RGGB). The shipped gc2053_i2c_1080p.ini declares MIPI input.

Companion PR

The pad-routing selector lives in load_goke in the firmware tree, so this
profile depends on OpenIPC/firmware#2276, which adds the sensor_dvp env-var
gate. Per @widgetii's review note that is opt-in and keyed off an env var, not
off $CHIP_TYPE
— MIPI-wired gk7202v300 boards exist and testing the SoC name
would fix this board by breaking those.

Status: Wi-Fi and video both verified

Verified on three boards: wlan0 up and associating, and 1920x1080 H.264 over
RTSP with FrmErrCnt 0 at 25 fps.

Two caveats worth stating plainly rather than discovering after merge:

  1. The SSV driver needs patches this profile does not carry. Enabling the
    package is necessary but not sufficient — the chip enumerates, but reliable
    cold boot and AP mode needed six patches to the SMAC tree (a duplicate
    tu_ssv6xxx_init_mac() in probe that forces Jump-to-ROM and breaks RF under
    OpenIPC's xHCI, plus an EP2 IN drain before the ROM-ready poll). Those belong
    in the ssv6x5x tree and are offered separately; see the issue.
  2. The sensor library needs a register-level fix that is not in this PR.
    galaxycore_gc2053_ForCar in OpenIPC/openhisilicon programs i2c address
    0x6e (SID low), so on a SID-high board every register write silently
    no-ops while still reporting Init_OK; and reg 0x3e yields ValidWidth 1244
    instead of 1920, which VI counts as a frame error, starving VPSS and timing
    out VENC. Where those should live — profile-local patch vs upstreamed to
    openhisilicon — is the open question in the issue.

So: this profile gets the board to a working Wi-Fi and a correctly-routed,
correctly-addressed sensor bus. The two items above are what stand between that
and a stock build producing video unaided.

Refs: OpenIPC/firmware#2074

GK7202V300, 8MB NOR, product string ipc533331a-W7-gc2053dvp-f8.

Two things differ from the generic gk7202v300_lite target:

- GC2053 wired in DVP (parallel) mode with the SID strap HIGH (i2c 0x3f).
  The generic target assumes MIPI + SID=0, so the i2c controller is muxed to
  pads that are not connected to the sensor and nothing is ever detected.
- iComm/SSV SSV6006C USB Wi-Fi, USB ID 8065:6000. The generic Lite target
  ships only mt7601u, which is MediaTek silicon and will never bind it.

Mirrors gk7202v300_lite_cootli_camv0103 (same SoC, same Wi-Fi family), minus
BR2_PACKAGE_MOTORS since W7 is fixed-lens.

Depends on OpenIPC/firmware#2276 for the opt-in sensor_dvp gate.

Refs: OpenIPC/firmware#2074
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Add GK-W7 (gk7202v300_lite_w7_8m) device profile with DVP GC2053 + SSV6006C Wi‑Fi

✨ Enhancement ⚙️ Configuration changes 🕐 20-40 Minutes

Grey Divider

AI Description

• Add a dedicated GK-W7 Buildroot defconfig with SSV6x5x Wi‑Fi enabled.
• Configure first-boot env defaults for GC2053 DVP routing and explicit sensor INI.
• Ship a GC2053 DVP-mode sensor INI plus per-target rootfs exclude list.
Diagram

graph TD
A["gk7202v300_lite_w7_8m_defconfig"] --> B["Device rootfs overlay"] --> C(["customizer.sh"]) --> D[("U-Boot env")] --> E{{"load_goke / open_sys_config"}} --> F["GC2053 DVP INI"]
E --> G(["/etc/wireless/usb"]) --> H["ssv6x5x module"]
subgraph Legend
  direction LR
  _cfg["Config/File"] ~~~ _scr(["Script"]) ~~~ _env[("Env store")] ~~~ _ext{{"External component"}}
end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Fold into generic gk7202v300_lite with env-gated DVP/Wi‑Fi paths
  • ➕ Fewer board profiles to maintain
  • ➕ One place to document/ship DVP + SSV6x5x defaults
  • ➖ Risk of changing behavior for existing MIPI-wired boards
  • ➖ Generic target would accumulate board-specific quirks quickly
2. Derive from an existing similar profile via shared include/overlay fragments
  • ➕ Reduces duplication across gk7202v300_lite_* profiles
  • ➕ Encourages consistent Wi‑Fi and sensor bring-up patterns
  • ➖ Requires repo-level refactor of profile layout/conventions
  • ➖ Harder for builders to reason about final merged overlay content
3. Upstream sensor/driver fixes first, keep profile minimal
  • ➕ Profile can avoid compensating for known upstream issues
  • ➕ Improves out-of-box behavior for other GC2053/SSV boards
  • ➖ Blocks the immediate need for a builder-ready profile
  • ➖ Depends on coordination across other repos/trees

Recommendation: Keep the dedicated GK-W7 profile as implemented: it localizes board-specific DVP routing and SSV6x5x enablement without risking regressions on other gk7202v300_lite boards. Consider a later follow-up to factor common pieces (e.g., SSV6x5x hook and DVP sensor INI selection) into shared overlay fragments once a few similar profiles exist.

Files changed (5) +268 / -0

Other (5) +268 / -0
gk7202v300_lite_w7_8m_defconfigAdd Buildroot defconfig for GK7202V300 Lite W7 (8MB NOR) +69/-0

Add Buildroot defconfig for GK7202V300 Lite W7 (8MB NOR)

• Introduces a new device defconfig for the GK-W7 variant: goke gk7202v300, lite, 8MB flash. Enables the SSV635X/SSV6x5x Wi‑Fi package and standard OpenIPC userspace components (majestic, dropbear, wireguard).

devices/gk7202v300_lite_w7_8m/br-ext-chip-goke/configs/gk7202v300_lite_w7_8m_defconfig

gc2053_i2c_dc_1080p.iniAdd GC2053 DVP-mode 1080p sensor configuration INI +97/-0

Add GC2053 DVP-mode 1080p sensor configuration INI

• Adds a dedicated GC2053 configuration targeting digital camera (DVP/parallel) input mode rather than MIPI. Sets VI device parameters and frame sizing consistent with 1920x1080 capture.

devices/gk7202v300_lite_w7_8m/general/overlay/etc/sensors/gc2053_i2c_dc_1080p.ini

usbAdd USB Wi‑Fi hook for ssv6x5x-generic +13/-0

Add USB Wi‑Fi hook for ssv6x5x-generic

• Adds a wireless selector script branch for 'ssv6x5x-generic' that loads the 'ssv6x5x' kernel module. Returns failure for unknown Wi‑Fi selectors.

devices/gk7202v300_lite_w7_8m/general/overlay/etc/wireless/usb

customizer.shProvision GK-W7 defaults (upgrade URL, SSV Wi‑Fi, DVP sensor routing) +44/-0

Provision GK-W7 defaults (upgrade URL, SSV Wi‑Fi, DVP sensor routing)

• Adds a GK-W7-specific customizer that sets the upgrade URL and selects 'ssv6x5x-generic' Wi‑Fi. Opts into DVP pad routing via 'sensor_dvp=1', sets 'sensor=gc2053', and pins '.isp.sensorConfig' to the new DVP INI; also enables audio output.

devices/gk7202v300_lite_w7_8m/general/overlay/usr/share/openipc/customizer.sh

gk7202v300_lite.listAdd per-target exclude list for gk7202v300_lite image trimming +45/-0

Add per-target exclude list for gk7202v300_lite image trimming

• Introduces a gk7202v300_lite exclude list to drop unused sensor INIs/libs and selected kernel modules from the final image. Mirrors existing exclude patterns used by other gk7202v300_lite device profiles.

devices/gk7202v300_lite_w7_8m/general/scripts/excludes/gk7202v300_lite.list

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Aug 16, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Device dir name uses underscores ⊘ Outdated 📘 Rule violation ⚙ Maintainability
Description
The new device directory devices/gk7202v300_lite_w7_8m/ does not follow the required __-[-]
format (missing vendor-model hyphenated segment and uses underscore tokens instead). This can
break expected device discoverability/mapping conventions for BOARD naming and CI artifact layout.
Code

devices/gk7202v300_lite_w7_8m/general/overlay/usr/share/openipc/customizer.sh[1]

+#!/bin/sh
Evidence
PR Compliance ID 1 requires any new device directory under devices/ to follow __-[-] with
hyphen-separated vendor/model. The PR adds files under devices/gk7202v300_lite_w7_8m/, whose
directory name lacks the required vendor-model hyphenated component and uses underscores instead.

CLAUDE.md: Device Directory Name Must Follow Standard <soc><flavor><vendor>-<model>[-<version>] Format: CLAUDE.md: Device Directory Name Must Follow Standard <soc><flavor><vendor>-<model>[-<version>] Format: CLAUDE.md: Device Directory Name Must Follow Standard <soc><flavor><vendor>-<model>[-<version>] Format: CLAUDE.md: Device Directory Name Must Follow Standard <soc><flavor><vendor>-<model>[-<version>] Format
devices/gk7202v300_lite_w7_8m/general/overlay/usr/share/openipc/customizer.sh[1-1]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The device directory name `gk7202v300_lite_w7_8m` does not comply with the required `<soc>_<flavor>_<vendor>-<model>[-<version>]` naming convention (vendor/model must be hyphen-separated and present).
## Issue Context
Compliance requires consistent device directory naming under `devices/` so that BOARD naming, CI artifact naming, and repository layout stay predictable.
## Fix Focus Areas
- devices/gk7202v300_lite_w7_8m/general/overlay/usr/share/openipc/customizer.sh[1-1]
- devices/gk7202v300_lite_w7_8m/br-ext-chip-goke/configs/gk7202v300_lite_w7_8m_defconfig[1-1]
- devices/gk7202v300_lite_w7_8m/general/scripts/excludes/gk7202v300_lite.list[1-1]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Data_seq constant mismatch ⊘ Outdated 🐞 Bug ⚙ Maintainability
Description
gc2053_i2c_dc_1080p.ini sets Data_seq = VI_DATA_SEQ_YUYV, but the same file documents
VI_INPUT_DATA_* values for Data_seq, making the configuration internally inconsistent. This
obscures the intended pixel ordering and makes future adjustments/troubleshooting of VI settings
error-prone.
Code

devices/gk7202v300_lite_w7_8m/general/overlay/etc/sensors/gc2053_i2c_dc_1080p.ini[R34-37]

+Scan_mode    = 1;VI_SCAN_INTERLACED = 0
+                ;VI_SCAN_PROGRESSIVE,
+Data_seq     = VI_DATA_SEQ_YUYV ;data sequence (ONLY for YUV format)
+                ;----2th component U/V sequence in bt1120
Evidence
The new INI uses a Data_seq token that does not match the enum names documented immediately below
it, while other sensor INIs in this repo use numeric values alongside the same VI_INPUT_DATA_*
documentation, indicating the expected naming/value set for Data_seq.

devices/gk7202v300_lite_w7_8m/general/overlay/etc/sensors/gc2053_i2c_dc_1080p.ini[34-44]
devices/hi3516ev300_ultimate_rvi-1ncmw2028/general/package/hisilicon-osdrv-hi3516ev200/files/sensor/config/sc2330_i2c_1080p.ini[34-44]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`Data_seq` is set to `VI_DATA_SEQ_YUYV`, but the INI’s own inline documentation lists the acceptable symbolic values as `VI_INPUT_DATA_{UYVY,VYUY,YUYV,YVYU}` (and other shipped configs use numeric equivalents). This makes the configuration internally inconsistent and harder to maintain.
### Issue Context
This INI is explicitly pinned by the device’s `customizer.sh`, so it becomes the board’s authoritative VI/sensor configuration.
### Fix Focus Areas
- devices/gk7202v300_lite_w7_8m/general/overlay/etc/sensors/gc2053_i2c_dc_1080p.ini[34-44]
### What to change
- Replace `Data_seq = VI_DATA_SEQ_YUYV` with a documented/consistent value, e.g. `Data_seq = 2` (matching other configs) or `Data_seq = VI_INPUT_DATA_YUYV`.
- Alternatively (if this config path is strictly RAW/RGB), remove `Data_seq` entirely to avoid implying it is relevant here.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can group findings by type and pick your Finding display, from Minimal to Full

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

@bneigher

Copy link
Copy Markdown
Contributor Author

Thanks. Two findings here — one I would like your call on, one I think should be
left alone.

1. Device directory naming. The bot is right that devices/ overwhelmingly
uses <soc>_<flavor>_<vendor>-<model>gk7205v200_lite_tiandy-tc-c321n,
gk7205v210_lite_vixand-ivg-g4f-a, hi3516cv200_lite_trassir-tr-d4121ir1-v2.
gk7202v300_lite_w7_8m does not fit that, and _8m is redundant besides, since
the flash size is already BR2_OPENIPC_FLASH_SIZE.

I have not renamed it yet for two reasons. @widgetii named this profile
explicitly in OpenIPC/firmware#2074 ("your proposed gk7202v300_lite_w7_8m
profile is the correct shape"), and the template I mirrored,
gk7202v300_lite_cootli_camv0103, does not follow the convention either — so
this may be a deliberate exception for boards without a clean retail identity.

The honest problem is that I cannot name the vendor with any confidence. The
board reports ipc533331a-W7-gc2053dvp-f8; it looks like a reference design sold
under several labels, and the only "XMC" on it is the NOR part (XM25QH64), which
is the flash vendor, not the board's. So rather than invent one, tell me which
you would prefer and I will push it:

  • gk7202v300_lite_generic-w7
  • gk7202v300_lite_ipc533331a-w7
  • keep gk7202v300_lite_w7_8m as-is

2. Data_seq in the sensor ini — I would leave this one. The finding is
technically accurate (the symbolic constant does not match the enum documented
two lines below it) but the field is inert here. Its own inline comment says
"ONLY for YUV format", and this config is InputDataType=1 (RGB) with
Isp_Bayer=0 — a RAW Bayer path, where data sequencing does not apply.

More to the point, this ini is a verbatim copy of a configuration verified on
hardware: with it the sensor comes up at 1920x1080, FrmErrCnt 0, 25 fps, and
the pipeline delivers real video. I would rather not edit a proven sensor config
to satisfy a linter on a field that has no effect. Happy to add a clarifying
comment marking it inert if you would like the inconsistency documented rather
than removed.

@flyrouter

flyrouter commented Aug 25, 2026

Copy link
Copy Markdown
Member

Good afternoon.

The profile name does not follow the accepted format here, which is: processor_type-profile_vendor-model.
The current profile name gk7202v300_lite_w7_8m is missing the vendor name, includes an unnecessary memory size, and has issues with the underscore.
Please adjust it roughly like this: gk7202v300_lite_gk-w7.
Also, there are some doubts whether GK is actually the vendor name of the board, so it’s worth trying to find something real.

Thank you

@widgetii

Copy link
Copy Markdown
Member

Sorry — you asked me a direct question on 17 Aug and I left it sitting. Answering it below, but the naming is the smaller of the two things here.

The profile is missing sensor_mclk

fw_setenv sensor_mclk 24 does not appear anywhere in this PR — not in customizer.sh, not in the ini (whose only clock key is Clock_edge, the sampling edge, which is a different thing). The PR description says the profile sets "opt-in sensor_dvp=1 / sensor_mclk=24", so the description and the file disagree.

That matters because parse_sensor_clock() maps gc2053 to 0x6, and the driver's own table reads 0x6: 27MHz. Your evidence in OpenIPC/firmware#2276 was gathered "with sensor_dvp=1 and sensor_mclk=24" — both set by hand on the bench. Only one of them made it into the profile.

So as written, a board flashed from this profile comes up at 27 MHz against init tables you established are 24 MHz values — which is, in your own words from the firmware PR, "a corrupted or absent image while every log line still looks healthy". The ini cannot rescue it: majestic's ini is read in userspace, while MCLK is the SoC clock output programmed from the CRG, so nothing downstream of open_sys_config can change it.

Unless you found the clock was not actually needed once the pinmux was right — in which case the firmware PR's second half and the description here should both say so — I think this wants:

fw_setenv sensor_mclk 24

next to the sensor_dvp line. Worth re-flashing a board straight from the built profile to confirm, rather than from a bench that still has the env set by hand; that difference is exactly what hid this.

Directory name

Taking your three options, plus @flyrouter's gk7202v300_lite_gk-w7: I would go with gk7202v300_lite_generic-w7, your first one.

gk-w7 should be dropped. "GK" is Goke — the SoC vendor, already encoded in gk7202v300 — so it is redundant, and @flyrouter's own doubt in the same comment about whether it is really the board vendor is well founded. It is not.

You were right about the convention on both counts, and I checked before answering: CLAUDE.md documents <soc>_<flavor>_<vendor>-<model>[-<version>], 86 of 94 device profiles conform, so it is a real rule rather than an aspiration — but gk7202v300_lite_cootli_camv0103, the profile you mirrored, is one of the eight that do not, so you were not inventing a precedent. And generic is already an established vendor token here: gk7205v200_otg_generic, ssc30kq_rubyfpv_generic, ssc30kq_apfpv_greg-generic-bu-eu.

generic-w7 therefore satisfies the documented shape while being honest that the board has no identifiable vendor, which beats inventing one. Agreed on dropping _8m — flash size is already BR2_OPENIPC_FLASH_SIZE.

On the ini Data_seq finding

Agreed, leave it. Your reasoning is right — the field is inert on a RAW Bayer path, and editing a hardware-verified sensor config to satisfy a linter on a no-op field is a bad trade. A short comment marking it inert would be welcome if you are touching the file anyway, but I would not ask for it on its own.

Unblocked on the firmware side

OpenIPC/firmware#2276 merged as fc923b7, so sensor_dvp and sensor_mclk now exist on master and this profile has something real to opt into. Before merging I measured the register on a lab board of the same family and confirmed the field layout, and proved by execution trace that boards not setting the vars behave identically to before — details are on that PR.

One thing to note: no CI has ever been triggered on this branch, so there is no build signal here at all yet. Pushing the rename will create the first one.

Two review items from @widgetii and @flyrouter.

1. The profile never set sensor_mclk. This was a real hole, not a doc mismatch:
   the PR description claimed sensor_dvp=1 AND sensor_mclk=24, but only the first
   was in customizer.sh, so a board flashed from this profile would have come up
   at 27 MHz against 24 MHz init tables — the silent-corruption failure the
   firmware PR exists to prevent. My bench boards had sensor_mclk set by hand,
   which is exactly why the gap did not show.

   Confirmed against hardware rather than re-reading the code: PERI_CRG60 reads
   0x00000019 at the moment load_goke writes it, i.e. bits [5:2] = 0x6 = 27 MHz,
   matching parse_sensor_clock()'s gc2053 -> 0x6 mapping. The ini cannot fix this
   — MCLK is a CRG clock programmed before majestic reads any ini.

2. Renamed gk7202v300_lite_w7_8m -> gk7202v300_lite_generic-w7, per the
   documented <soc>_<flavor>_<vendor>-<model> shape. "gk-w7" is dropped: GK is
   Goke, the SoC vendor, already carried by gk7202v300 — flyrouter's doubt that
   it names the board vendor was right, it does not. "generic" is the honest
   token for a board with no identifiable vendor, and is already established
   here (gk7205v200_otg_generic, ssc30kq_rubyfpv_generic). _8m dropped since
   flash size is BR2_OPENIPC_FLASH_SIZE.

   The excludes list stays gk7202v300_lite.list — that name is keyed to
   <soc>_<flavor>, not to the profile, matching every other profile in the tree.

The inert ini Data_seq field is left as-is per review.

Refs: OpenIPC/firmware#2276
@bneigher bneigher changed the title Add gk7202v300_lite_w7_8m device profile (GK-W7, GC2053-DVP, SSV6006C Wi-Fi) Add gk7202v300_lite_generic-w7 device profile (GK-W7, GC2053-DVP, SSV6006C Wi-Fi) Aug 27, 2026
@bneigher

Copy link
Copy Markdown
Contributor Author

Both applied in 24da3cd. Thank you for going to the file rather than the
description — the sensor_mclk one was a real hole, and I would not have found it
from my bench.

sensor_mclk was genuinely missing

You are right, and the reason it hid is the reason you named: my boards have
sensor_mclk 24 set by hand.
They have had it since bring-up. So every "flash
and it works" result I have reported is a test of the bench, not of the profile —
the profile has never once been the thing that set that variable. A board flashed
from this PR as it stood would have come up at 27 MHz against 24 MHz init tables.

I checked your register claim on hardware rather than by re-reading the code,
since this is the second time in this series that reading the code was not enough.
Instrumented load_goke to log the register immediately before its write:

goke: NCAM-DEBUG pre-write reg=0x00000019

Bits [5:2] = 0x6 — exactly the 27 MHz your parse_sensor_clock() mapping
predicts, sitting there at the moment the write happens. Now added, with that
measurement recorded next to it so the next person does not have to re-derive why
a clock line is in a customizer script.

And agreed the ini cannot stand in for it. That is worth being precise about: MCLK
is a CRG clock programmed before majestic exists, so no userspace key can reach
it. Clock_edge is the sampling edge, an unrelated knob.

Naming

Gone with gk7202v300_lite_generic-w7. @flyrouter — you were right on both counts,
and thank you for the push-back on gk-w7 specifically: GK is Goke, the SoC
vendor, already carried by gk7202v300. Your doubt that it names the board
vendor was well founded; it does not. This board has no identifiable vendor
marking at all, so generic is the honest token rather than one I invent, and it
is already established here (gk7205v200_otg_generic, ssc30kq_rubyfpv_generic).
_8m dropped — flash size is BR2_OPENIPC_FLASH_SIZE.

The excludes list stays gk7202v300_lite.list: that name is keyed to
<soc>_<flavor> rather than to the profile, which is how every other profile in
the tree does it.

What is still unproven

Per your suggestion, the meaningful test is a board flashed from the built
profile
with no hand-set env — that is the only thing that exercises what this
PR actually changed, and it is precisely what my bench cannot show right now. I
will clear sensor_dvp/sensor_mclk from a board's U-Boot env, flash it from the
CI artifact once this branch produces one, and report the result here either way.
Until then, please read this PR as reviewed but not end-to-end verified.

Noted on CI never having run — the rename push should trigger the first one.

@bneigher

Copy link
Copy Markdown
Contributor Author

Correcting myself on one detail above, because it is checkable and I got it wrong.

I said my boards "have had sensor_mclk 24 set by hand since bring-up". They have
not. Until today those variables were empty on all three (fw_printenv -n sensor_dvp → nothing); I set them a few hours ago, after #2276 merged, so the
boards would be ready for a base rebase.

The accurate version is worse for me, not better: my boards run a forked
load_goke
that hardcodes the DVP branch and the 24 MHz write for this board and
never reads the env at all. So the bench could not have caught the missing
sensor_mclk under any value of those variables — it was not "env set by hand
masked it", it was "the bench does not execute the code path this profile
configures". Same conclusion, different and more complete reason.

Which makes your suggested test the only one that means anything here, and it now
has a second prerequisite I should state plainly: the board has to be running
stock upstream load_goke, not our fork, as well as having no hand-set env.
That is what I will do — clear both vars, flash from the CI artifact, and report.

@widgetii

Copy link
Copy Markdown
Member

Checked 24da3cd rather than taking the summary for it — all of it landed:

  • All five files moved to devices/gk7202v300_lite_generic-w7/, defconfig renamed with them, and the upgrade URL updated to match. That last one is easy to leave stale on a rename and you didn't.
  • fw_setenv sensor_mclk 24 is in, with the 0x00000019 measurement recorded beside it.
  • Excludes list stays gk7202v300_lite.list — agreed, that name is keyed to <soc>_<flavor>, not to the profile.

I've approved the workflow runs, so Build and lint are going now. That's the first CI this branch has ever had.

Your correction is the more useful version, and it reaches further than you applied it

Thank you for posting it rather than letting the tidier story stand. It also changes something you said sixteen minutes earlier on the other PR, which I don't think you'd noticed, so I'm joining it up here.

On OpenIPC/firmware#2276 you reported flashing a GK7202V300 and getting 1920×1080 @ 25 fps, i2c init failures 0, ISP errors 0. If your boards run a forked load_goke that hardcodes the DVP branch and the 24 MHz write, then that result is evidence your fork works — it isn't evidence the merged script does. The timing supports your correction rather than the original: #2276 merged at 17:11, and no nightly built from it existed by 17:35. And a board running stock pre-merge load_goke could not have brought up a DVP-wired sensor at all, since the gate didn't exist yet. So the script that produced that 1080p25 was necessarily yours.

I'd rather say that plainly than let it sit in the record as end-to-end validation of something already merged.

What that does and doesn't change

It doesn't change the merge. That went in on evidence independent of your bench: the field layout measured on a lab board of the same family, the no-op path proven by execution-trace equivalence against the base script with a negative control that fails 13 checks, and CI green across all seven Goke boards.

And your pre-write reg=0x00000019 stands completely, whichever script emitted the log line — it's a read of the register after open_sys_config configured it and before anything overwrote it. Bits [5:2] = 0x6 is exactly what parse_sensor_clock("gc2053") predicts. Set against the lab board's 0x00000011 — a different SoC, a different sensor, bits [5:2] = 0x4 matching parse_sensor_clock("imx335") — that's two independent confirmations of the same table entry-by-entry, with bit 0 set and bits [31:6] clear in both. Better than either of us had alone.

What remains open is what you already named: the merged load_goke, driving a DVP board, from a profile-set env. Your planned test is the right shape — stock upstream load_goke, both vars cleared from U-Boot env, flashed from the CI artifact. With CI now running, that artifact is about to exist.

No rush on it. The opt-in path is inert for every board that doesn't set the vars, so nothing is at risk in the field while this is outstanding — it's this profile's own correctness that's unproven, not the firmware change's safety.

@bneigher

Copy link
Copy Markdown
Contributor Author

CI is green — and I closed the firmware half of the open question, though not yet
the profile half.

The merged load_goke drives a DVP board from env. Tested on hardware.

Rather than wait to flash a whole profile image, I ran the thing actually in
doubt: installed upstream master's load_goke verbatim on a GK7202V300
DVP board, replacing our fork, and rebooted.

load_goke in use:        ebe95ba77a7865d70984484b66f0ba38   (= master's file, byte for byte)
fw_printenv sensor_dvp gate present:  1
NCAM fork hunks present:              0
env:  sensor_dvp=1  sensor_mclk=24

Result:

online_flag=0, cmos_yuv_flag=1, sensor=gc2053, chip=gk7205v200
i2c init failures: 0     ISP errors: 0
devmem 0x120100F0 = 0x0000000D      (bits[5:2]=3 = 24 MHz)

...and a clean 1920×1080 @ 25 fps RTSP frame. So the merged script, with zero
of our patches present, takes the DVP branch, borrows the gk7205v200 pad tables,
and programs 24 MHz — driven only by the two env vars. That is the claim I
previously supported with the wrong evidence; this is the right evidence.

I've also posted the correction on #2276 itself, since that is where the
overstated version was and where it would have been read.

What is still not proven

Exactly one link now: that this profile sets those vars on a real flash. My
test set them by hand, so it validates the firmware, not customizer.sh. The
remaining test is unchanged — clear both vars, flash the CI artifact, confirm the
board comes up without me touching the env — and it needs a board I can take out
of service, since our image carries an agent stack the profile image does not. I
will schedule that rather than rush it, and report here.

Given the merged script is now hardware-verified on this exact wiring, that last
step is checking the packaging, not the mechanism.

@widgetii

Copy link
Copy Markdown
Member

Your image is built and published — the thing you were waiting on now exists:

https://github.com/OpenIPC/builder/releases/tag/nightly-bisect-24da3cd

gk7202v300_lite_generic-w7-nor.tgz    6,884,329 bytes
https://github.com/OpenIPC/builder/releases/download/nightly-bisect-24da3cd/gk7202v300_lite_generic-w7-nor.tgz

Built from 24da3cd422cc118b366020bba100fcad74c99725 — this PR's head, not master — so customizer.sh inside it is the one under review here.

Why you were about to wait forever

There is no CI artifact on this PR, and there never will be. The publishing steps in master.yml are all gated the same way:

- name: Stage artifacts
  if: github.event_name != 'pull_request' && (env.NORFW || env.NANDFW)
- name: Upload build artifacts
  if: github.event_name != 'pull_request' && (env.NORFW || env.NANDFW)

Stage artifacts, Upload build artifacts, Send binary and Publish releases were all skipped on the green run, and the artifact count is zero. A builder PR compiles the whole image and then discards it. So "flash the CI artifact once this branch produces one" would not have resolved on its own.

The route that does work is the build-one workflow — a workflow_dispatch taking platform and a commit, whose upload step is gated only on env.NORFW || env.NANDFW with no PR restriction. I dispatched it for you:

platform: gk7202v300_lite_generic-w7
commit:   24da3cd422cc118b366020bba100fcad74c99725

Worth knowing for your next profile too — ask a maintainer to dispatch build-one rather than waiting on the PR build.

Size, since this is the first build this profile has ever had

rootfs.squashfs: [4900KB / 5120KB]
headroom: kernel=208KB  rootfs=220KB

It fits, but 220 KB of rootfs headroom is not much — about 4% of the partition. This family has a history of profiles going over the cliff as majestic grows (gk7205v300_lite, hi3518ev300_lite and hi3519v101_lite have all hit it). Not a blocker, and nothing to change now, but if you add anything to the overlay later that is the number to watch, and gk7202v300_lite.list is the lever.

On your hardware test

I checked the md5 rather than taking it on trust: ebe95ba77a7865d70984484b66f0ba38 is byte-for-byte master's load_goke, so "zero of our patches present" holds. And devmem 0x120100F0 = 0x0000000D is exactly what the read-modify-write predicts from your earlier pre-write 0x19(0x19 & ~0x3C) | (3 << 2). Two independent routes to the same word.

That closes the firmware half properly. It was the one case I said neither CI nor I could reach, and you reached it.

So the only link left is the one you named: flash the image above onto a board with sensor_dvp and sensor_mclk cleared from U-Boot env, and confirm it comes up without you touching anything. If that is clean, this merges.

@bneigher

Copy link
Copy Markdown
Contributor Author

Heads-up on the artifact, since it changes what the remaining test needs from you.

The run is green and Build firmware succeeded, but the image was built and
discarded — the staging steps didn't run:

7.  Build firmware:         success
9.  Stage artifacts:        skipped
10. Upload build artifacts: skipped
11. Send binary:            skipped

Publish releases skipped too, and there is no release or artifact on either
OpenIPC/builder or my fork. So "flash the CI artifact" currently has nothing to
flash. I assume that is deliberate — approved fork PRs building on your Actions
shouldn't be publishing releases — I just wanted to flag it rather than let you
assume I had an image and had gone quiet.

Three ways forward, and I am happy with any:

  1. I build the profile locally from this branch with the same recipe. That
    tests what is actually in question — whether customizer.sh sets the two vars
    on a real flash — since the profile's file set is identical. It does not test
    your CI packaging, but that was never the doubtful part.
  2. You enable staging for this run (or point me at a re-run that does), and I
    flash exactly what CI produced.
  3. Wait for merge, and I verify from the first canonical nightly that includes
    the profile. Slowest, but it tests the real artifact users would get.

Unless you would rather have (2) or (3), I will start on (1), since it needs
nothing from you. Either way the flash itself waits until I can take a board out
of service — our image carries an agent stack the profile image does not, so it is
a restore-from-backup operation rather than a reflash.

For the record, the firmware-side result from my last comment is unaffected by
any of this: that used master's load_goke directly on the board, no build system
involved.

@bneigher

Copy link
Copy Markdown
Contributor Author

Got an artifact, and the packaging side now checks out on paper. Built from
24da3cd via build-one.yml dispatched on my fork, so this is CI output rather
than anything hand-assembled: gk7202v300_lite_generic-w7-nor.tgz,
rootfs=5017600B, headroom: rootfs=220KB — the same numbers your run produced.

Unpacked, the two things in question:

1. customizer.sh carries both vars.

fw_setenv upgrade 'https://github.com/OpenIPC/builder/releases/download/latest/gk7202v300_lite_generic-w7-nor.tgz'
fw_setenv wlandev ssv6x5x-generic
fw_setenv sensor_dvp 1
fw_setenv sensor_mclk 24
fw_setenv sensor gc2053

2. The baked load_goke is master's, verbatim. Its md5 differs from the file
in the repo, which I chased rather than waving at: the build strips comments and
blank lines. Normalising both (sed 's/#.*//', drop blanks) makes them
byte-identical across all 306 remaining code lines. The fw_printenv -n sensor_dvp gate and the masked-RMW MCLK write are both present.

So the profile ships the merged gate and sets the env it needs. Combined with the
earlier on-hardware result — master's load_goke bringing up a DVP GC2053 from
those two vars — the only untested link left is first-boot execution: that
customizer.sh actually runs on a fresh flash and lands the vars in U-Boot env.
Everything upstream of that is now evidenced.

That last step still needs a board out of service, so it waits for a maintenance
window rather than a spare evening.

Two incidental findings from getting here, in case they are useful to you:

  • The first dispatch I ran reported completed success in 90 seconds across
    108 jobs and built nothing at all — my fork's master.yml predates the
    Select devices job, so its static matrix has no generic-w7 entry and every
    job self-skipped to green. Only mentioning it because a green run that builds
    nothing is an easy thing to believe.
  • builder.sh exits 0 when buildroot fails. I hit this locally: make died,
    and the script still printed Assembled firmware available in: pointing at an
    empty directory, then returned success. In CI it is masked because
    Stage artifacts is gated on env.NORFW, so a failed build merely skips
    upload rather than failing the job. Happy to open a separate PR making
    builder.sh propagate the failure if you think it is worth it.

@widgetii

Copy link
Copy Markdown
Member

Three things: the artifact did exist, your verification holds, and your builder.sh finding is worse than you described.

The artifact was there

You were looking at the PR's own build run. The steps you quoted — Stage artifacts: skipped, Upload build artifacts: skipped — are master.yml on a pull_request, which is exactly the gating I described. But I did not ask you to wait for that run; I dispatched build-one.yml, which has no such gate, and it published:

https://github.com/OpenIPC/builder/releases/tag/nightly-bisect-24da3cd
gk7202v300_lite_generic-w7-nor.tgz    6,884,329 bytes

Still up, asset attached. My fault for putting the release link under a heading about why the PR build produces nothing — the two are easy to run together, and you reasonably read the second as explaining the first.

The practical cost was only that you rebuilt what already existed, and you landed on identical numbers (rootfs=5017600B, headroom: rootfs=220KB), which is its own small confirmation that the dispatch route is reproducible across forks.

This is now moot going forward. #135 merged a few hours ago: Stage artifacts and Upload build artifacts no longer carry the pull_request guard, with retention of 7 days on PRs and 1 elsewhere. Send binary and publish keep their guards. So the next run on this branch will attach fw-* to the PR itself and nobody has to dispatch anything. Your option 2 is the default now.

Your verification

The normalising step is the part I would have got wrong: chasing an md5 mismatch to comment-and-blank-line stripping, rather than concluding the file differed, is the difference between a real check and a scare. 306 code lines identical, both the fw_printenv -n sensor_dvp gate and the masked RMW present, and customizer.sh carrying both vars.

Agreed on what is left: first-boot execution of customizer.sh on a clean flash. Everything upstream of it is evidenced now.

builder.sh exiting 0 — yes, please open that PR

Confirmed, and it defeats more than you saw. There is no set -e, line 157 is a bare make BOARD=${DEVICE}, and copy_to_archive runs unconditionally after it, so the script prints Assembled firmware available in: over an empty directory and ends on cd "$BUILDER_DIR" — exit 0.

The part worth adding to your report is what that does to CI. master.yml invokes it inside a retry loop:

for sleep_for in $backoffs ""; do
  bash builder.sh ${NAME} && break
  ...
  echo "::error::build failed after ${attempt} attempts"
  exit 1
done

Because builder.sh always returns 0, && break fires on the first attempt and that exit 1 is unreachable. So the retry budget — six backoffs, specifically there to absorb transient toolchain and CDN flakes — can never retry, and a genuinely failed build reports green rather than being re-attempted. That is a bigger hole than the staging gate masking it: the mechanism built to handle flaky builds has been inert.

Worth noting it also changes what a missing artifact means. Before #135 a PR produced no artifact either way, so there was no signal. Now a green job with no fw-* attached is a reliable tell that the build failed silently — which makes fixing builder.sh more valuable, not less.

Please do open it. Propagating the make status is the fix; whether that is set -e at the top or an explicit || exit on line 157 is your call, though the explicit form is probably safer given how much unguarded cp the script does.

This PR

mergeState: CLEAN. I am not merging ahead of your first-boot test, since that is the one link this profile is actually responsible for. No hurry on the maintenance window — nothing is waiting on it.

@bneigher

Copy link
Copy Markdown
Contributor Author

Opened as #136 — the retry-loop consequence is in the description, credited to
you, since that is the part that actually costs something and I had only seen the
banner.

On the artifact: you are right that I rebuilt what already existed. I checked
releases/tags/latest and my fork's releases, and never looked for a
nightly-bisect-* tag on OpenIPC/builder — so I read past a link that was sitting
there. Cheap mistake, and the identical rootfs=5017600B / headroom 220KB from
two different forks is a better reproducibility check than either of us would have
bothered to run deliberately.

Good news on #135 landing — that removes the whole detour for the next person, and
it makes the missing-artifact signal meaningful, which is worth more than the
convenience.

One correction to my own report while I am here. I said the retry budget was
"masked" by the staging gate. That understates it in the way you identified: the
budget was not merely hidden, it was inert&& break on a script that
cannot return non-zero means attempt 1 always succeeds. Six backoffs, zero
retries, ever. I had described a reporting problem; it was a control-flow one.

On the first-boot test

Agreed it is this profile's own responsibility and I would rather it gate the
merge than not. It needs a camera out of service — our image carries an agent
stack the profile image does not, so it is flash-and-restore rather than a
reflash — and that is the owner's call on timing, not mine. I will report the
result here either way, including if customizer.sh turns out not to run when I
expect it to.

Thank you for the review throughout this. Three separate things I had stated as
verified turned out to rest on something I had not checked — the fork evidence,
the artifact, and the retry loop — and each time you went to the source rather
than to my summary. The PR is better for it and so is the firmware change it
depends on.

@widgetii

Copy link
Copy Markdown
Member

I closed the remaining link from this end, without needing your board.

The open question was whether customizer.sh actually runs on a fresh flash and
lands the two vars before anything reads them. That is not board-specific — it is
S30customizer, which ships in the shared general/overlay/etc/init.d/ on every
OpenIPC image:

if [ ! -e /etc/custom.ok ] && [ -e /usr/share/openipc/customizer.sh ]; then
        echo "Run customizer script..."
        sh /usr/share/openipc/customizer.sh
        touch /etc/custom.ok
fi

Runs once, on first boot, guarded by a sentinel. The same mechanism every other
profile in devices/ relies on.

The ordering works out, and it is the part worth checking rather than assuming.
The driver load is S70vendor, which is just:

vendor=$(ipcinfo -v)
load_"$vendor" -i

S30 before S70, so customizer.sh sets sensor_dvp / sensor_mclk / sensor
before load_goke runs and reads them with fw_printenv. Had those numbers
been the other way round, the first boot would have come up with no sensor and
only worked after a reboot — which is the kind of thing that gets diagnosed as a
flaky board rather than an ordering bug.

Your customizer.sh is sh -n, dash -n and busybox ash -n clean, and does
nothing exotic: five fw_setenv, three cli -s, exit 0.

What that leaves

Every link in the chain is now independently evidenced:

  1. customizer.sh ships at the right path in the built image — you verified by
    unpacking the CI artifact.
  2. S30customizer runs it on first boot, before the driver load — verified here
    from the shared init scripts.
  3. load_goke reads the two vars, takes the DVP branch and programs 24 MHz — you
    verified on hardware with master's load_goke byte-for-byte, md5 confirmed
    independently.
  4. The sensor comes up: 1920x1080 @ 25 fps, i2c init failures 0, ISP errors 0 —
    your measurement, on this exact wiring.

What has never been run is the conjunction — all four unattended, on a board
flashed from this image with no hand-set env. I am merging on the four links
rather than holding for it, since each is evidenced and the remaining risk is
composition rather than mechanism.

Please still do the flash when a maintenance window comes up, and please report if
it does not come up clean — a merged profile is easier to fix than a stalled PR,
and I would rather know.

Thanks for the work on this one, and for correcting your own evidence twice when
it would have been easier not to.

@widgetii
widgetii merged commit b676643 into OpenIPC:master Aug 29, 2026
6 checks passed
@bneigher

Copy link
Copy Markdown
Contributor Author

Thank you — and the S30/S70 ordering check is the one I should have done and
didn't. I had been treating "does customizer.sh run" as something only a flash
could answer, when it was readable from the shared init scripts the whole time.

Confirmed the same thing from the other end, on a GK-W7 board running now:

/etc/init.d/S30customizer
/etc/init.d/S70vendor

with the body byte-for-byte as you quoted. So the ordering holds on real hardware,
not just in the tree.

One way the test could give a false negative

Worth recording before anyone runs it, mine included. The guard is:

if [ ! -e /etc/custom.ok ] && [ -e /usr/share/openipc/customizer.sh ]; then

/etc/custom.ok is a sentinel that survives a rootfs reflash, because it
lives in the overlay rather than in the squashfs. So a board that has ever booted
an image with a customizer will silently skip it on every later flash — the
customizer does not run, no env is set, and the sensor comes up dead in a way that
looks like the profile is broken rather than like a stale sentinel.

Checked our boards for exactly this and they are clean:

customizer.sh on our current image: ABSENT     (so it never ran)
/overlay/root/etc/custom.ok:        absent
/overlay/root/etc/network.ok:       absent

That is a happy accident rather than foresight — our image simply carries no
customizer, so the sentinel was never created. Anyone repeating this test on a
board with a different history should rm -f /etc/custom.ok before flashing, or
they will be debugging the wrong thing.

The flash

Agreed on merging for the four links rather than holding for the conjunction, and
noted on reporting back regardless of outcome — a bad result is the more useful
one to publish, and I would rather post it than quietly not mention it. It waits
on the owner's maintenance window; nothing technical is blocking it.

I will report here with the boot log and devmem 0x120100F0 either way.

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.

3 participants