From 189f7aec382c288e6ba3f16b80d3927f93ad9250 Mon Sep 17 00:00:00 2001 From: BFE Engineering Date: Tue, 25 Aug 2026 13:46:08 -0600 Subject: [PATCH] sdk: bootstrap standalone repo (P0) - Dual license (LICENSE / LICENSE-MIT / LICENSE-APACHE) matching the crate manifests. - ADRs 0001-0005: kernel base (direct 5.10->6.18.46 forward-port), tiered MC/DC, standalone repo, CI runner (3rd repo-scoped runner on 0640), driver source-of-truth. - README goal 1 reconciled to the verified 6.18.46 forward-port (was stale plan44/6.6). - Drop tracked build objects (*.o now gitignored). - Capture the display (VOP dclk-pol + WIN1) and GT911 touch bring-up VERIFIED docs + capabilities-audit update from this session. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_017wB8KB3MMQztRDXCMCkPrf --- .gitignore | 4 + LICENSE | 10 + LICENSE-APACHE | 202 ++++++++++++++++++ LICENSE-MIT | 39 ++++ README.md | 15 +- docs/decisions/0001-kernel-base.md | 28 +++ docs/decisions/0002-mcdc-tiering.md | 28 +++ docs/decisions/0003-standalone-repo.md | 20 ++ docs/decisions/0004-ci-runner.md | 21 ++ docs/decisions/0005-driver-source-of-truth.md | 21 ++ .../rv1106-enablement/CAPABILITIES-AUDIT.md | 14 +- kernel/rv1106-enablement/display/README.md | 16 +- kernel/rv1106-enablement/display/VERIFIED.md | 87 ++++++++ kernel/rv1106-enablement/touch/VERIFIED.md | 57 +++++ 14 files changed, 547 insertions(+), 15 deletions(-) create mode 100644 LICENSE create mode 100644 LICENSE-APACHE create mode 100644 LICENSE-MIT create mode 100644 docs/decisions/0001-kernel-base.md create mode 100644 docs/decisions/0002-mcdc-tiering.md create mode 100644 docs/decisions/0003-standalone-repo.md create mode 100644 docs/decisions/0004-ci-runner.md create mode 100644 docs/decisions/0005-driver-source-of-truth.md create mode 100644 kernel/rv1106-enablement/display/VERIFIED.md create mode 100644 kernel/rv1106-enablement/touch/VERIFIED.md diff --git a/.gitignore b/.gitignore index 9d0ae7b..ab744a1 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,10 @@ target/ **/target/ Cargo.lock +# build artifacts (firmware/kernel objects are rebuilt from source) +*.o +*.a + # scratch / editor *.swp *~ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..b0b40ae --- /dev/null +++ b/LICENSE @@ -0,0 +1,10 @@ +warden-sdk is dual-licensed under either of + + * Apache License, Version 2.0 (LICENSE-APACHE) + * MIT license (LICENSE-MIT) + +at your option. + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in this work by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. diff --git a/LICENSE-APACHE b/LICENSE-APACHE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/LICENSE-APACHE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/LICENSE-MIT b/LICENSE-MIT new file mode 100644 index 0000000..1f8cf8c --- /dev/null +++ b/LICENSE-MIT @@ -0,0 +1,39 @@ +MIT License + +Copyright (c) 2026 BlueFlare + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +------------------------------------------------------------------------------- +Third-party components carry their own licenses, which are not superseded by +the above: + + - LVGL (the UI library, fetched during build, not vendored here) is MIT + licensed by its authors. + - The Luckfox / Rockchip RV1106 SDK and its cross-toolchain are covered by + their respective vendor licenses. + - vendor/asic-rs is 256 Foundation's asic-rs, vendored into this repository + with git subtree and licensed under Apache-2.0. Its license text is kept + at vendor/asic-rs/LICENSE.txt. Files modified locally must carry a notice + saying so, per Apache-2.0 section 4(b); see vendor/README.md. + +The contents of branding/ (BlueFlare logos, wordmarks, and splash artwork) are +NOT covered by the MIT license above. They are proprietary to BlueFlare, all +rights reserved, and are included only so the firmware builds and displays as +shipped. Do not reuse them in derivative works. diff --git a/README.md b/README.md index e752ae2..3e33ee6 100644 --- a/README.md +++ b/README.md @@ -29,11 +29,16 @@ without a panel in the loop**, and to move us onto a modern, maintained kernel. ## Goals (from future-features) -1. **Modern kernel.** Move to the newest stable Linux we can run on our current - Buildroot LTS (2025.02.x). The realistic ceiling is **plan44's OpenWrt RV1106 - fork — Linux 6.6**, which carries 152 RV1106 patches and a devicetree for our - exact board. Mainline is not viable (no DT/clk/display/RGA/NPU/flash-boot). - This is a bounded, evidence-backed forward-port, not a mainline chase. +1. **Modern kernel.** A self-built **Linux 6.18.46**, forward-ported directly from + the vendor 5.10.160 tree (no plan44/OpenWrt code) on our current Buildroot LTS + (2025.02.x). This is **done and hardware-verified on `warden-c8a3`**: essentially + every RV1106 block the 86-Panel uses boots and works — clk, pinctrl, eMMC, GMAC, + TRNG, OTP, SARADC/TSADC, RTC, USB host, PWM/backlight, **VOP display**, **GT911 + touch**, **AIC8800 wifi**, **RGA**, **I2S audio**, **HPMCU mailbox**, the **open + NPU driver**, and **PVTM**. Mainline was not viable (no DT/clk/display/RGA/NPU/ + flash-boot upstream for RV1106); the direct 5.10→6.18 forward-port reuses the + already-in-mainline rv1126 register data where it matches and carries our deltas + as a reviewable patch series (`patches/`). 2. **Ported, hardened drivers → 100% MC/DC on the code we own.** "100% MC/DC on 100% of drivers" is infeasible as literally stated: ~97% of driver LOC is vendor blobs (the AIC8800 wifi driver alone is 88.5K lines). So the target is diff --git a/docs/decisions/0001-kernel-base.md b/docs/decisions/0001-kernel-base.md new file mode 100644 index 0000000..0112322 --- /dev/null +++ b/docs/decisions/0001-kernel-base.md @@ -0,0 +1,28 @@ +# ADR 0001 — Kernel base: direct 5.10→6.18 forward-port + +**Status:** Accepted (2026-08-25). Supersedes the README's original plan44/6.6 goal. + +## Context +The vendor kernel is Rockchip 5.10.160 (via Luckfox). We want the newest stable +Linux runnable on our Buildroot LTS (2025.02.x). Two candidate paths existed: +(a) baseline on plan44's OpenWrt RV1106 fork (Linux 6.6, 152 RV1106 patches), or +(b) forward-port the vendor tree directly onto a chosen upstream stable. + +## Decision +Forward-port **directly to Linux 6.18.46** from vendor 5.10.160, carrying **no +plan44/OpenWrt code**. Reuse the already-upstream **rv1126** register data where it +matches the RV1106 ("RV-series lite" VOP, clk, pinctrl), and carry the RV1106 +deltas as a reviewable patch series in `patches/`. + +## Consequences +- Done and **hardware-verified on `warden-c8a3`**: clk, pinctrl, eMMC, GMAC, TRNG, + OTP, SARADC/TSADC, RTC, USB host, PWM/backlight, VOP display, GT911 touch, AIC8800 + wifi, RGA, I2S audio, HPMCU mailbox, open NPU driver, PVTM. +- **uClibc stays load-bearing** — RGA/MPP/ISP/NPU userspace ship as uClibc-only + blobs; a glibc swap breaks media (flare-edge #51, wontfix). Any kernel bump + inherits this. +- Kernel bumps risk struct-ABI breaks for out-of-tree modules (the AIC8800/VLAN + `struct net_device` offset saga). Mitigation: ship one matched full boot+oem + image, never a partial reflash. +- Deferred by design: crypto-v3 accelerator (CPU crypto already covers the need), + open NPU *compute* (a person-year register-RE effort, no RV1106 prior art). diff --git a/docs/decisions/0002-mcdc-tiering.md b/docs/decisions/0002-mcdc-tiering.md new file mode 100644 index 0000000..b9e9ffa --- /dev/null +++ b/docs/decisions/0002-mcdc-tiering.md @@ -0,0 +1,28 @@ +# ADR 0002 — Tiered MC/DC coverage policy + +**Status:** Accepted (2026-08-25). + +## Context +The goal "port + harden 100% of drivers to 100% MC/DC" is infeasible as literally +stated: ~97% of driver LOC is vendor blobs (the AIC8800 wifi driver alone is 88.5K +lines) that we cannot meaningfully unit-test to MC/DC on the host. Forcing MC/DC on +that code would be theatre, not assurance. + +## Decision +A **two-tier** policy, measured against the Hardware Abstraction Seam: + +- **Tier 1 — our own hardware-facing code → real 100% MC/DC.** `modbus_engine.c`, + `relays.c`, `warden_rga.c` (wrapper), `hpmcu.rs`, `devmem.rs`, `freshness.c`, plus + the two smallest near-mainline drivers where feasible. Enforced in CI + (`gcc-14 -fcondition-coverage` + `gcov-14 --conditions`; `cargo-llvm-cov --mcdc` + for Rust). +- **Tier 2 — ported/vendor drivers → fault-injection + branch coverage + benchmarks** + against the simulator, behind a stable seam. Explicitly NOT literal MC/DC. + +## Consequences +- Matches the user's framing: "as many drivers as possible at 100% MC/DC; for the + rest, a very serious testing and benchmarking system." +- The seam is the shared object: the same thing MC/DC is measured against and the + simulator implements — the two goals reinforce, not duplicate. +- Every Tier-1 file gets a `drivers/-mcdc/` host harness with an + `enforce-mcdc.sh` that fails CI below 100%. diff --git a/docs/decisions/0003-standalone-repo.md b/docs/decisions/0003-standalone-repo.md new file mode 100644 index 0000000..36aa658 --- /dev/null +++ b/docs/decisions/0003-standalone-repo.md @@ -0,0 +1,20 @@ +# ADR 0003 — warden-sdk is a standalone repo + +**Status:** Accepted (2026-08-25). + +## Context +Our real SDK changes lived as uncommitted edits in a 2GB opaque vendor fork, with +no CI, tests, or versioning of their own. The SDK requirement (future-features-2 +§SDK) calls for "its own repo, held to firmware standards." + +## Decision +A **private** `bfe-noah/warden-sdk` GitHub repo, standalone from day one with its own +CI/versioning. Work lands on a `bringup` branch; the first commit to `main` is gated +on a passing code-review-harness run, green CI, and [maintainer]'s fresh explicit go-ahead. + +## Consequences +- flare-edge consumes warden-sdk later (flared depending on `warden-sim`, drivers + built from here) — a separate, [maintainer]-gated integration step; flare-edge is not + edited by the SDK-completion effort. +- Private for now (references bench devices / in-progress hardening); can be opened + later once scrubbed, matching how `flare-deployment` is handled. diff --git a/docs/decisions/0004-ci-runner.md b/docs/decisions/0004-ci-runner.md new file mode 100644 index 0000000..847098e --- /dev/null +++ b/docs/decisions/0004-ci-runner.md @@ -0,0 +1,21 @@ +# ADR 0004 — CI/CD runner: 3rd repo-scoped self-hosted runner on 0640 + +**Status:** Accepted (2026-08-25). + +## Context +The heavy kernel/firmware build needs the SDK toolchain and Buildroot's baked-in +absolute paths — impractical on GitHub-hosted runners. flare-edge already builds on +a repo-scoped self-hosted runner on `bfe-mpc-0640` (label `flare-edge`); a repo-scoped +registration cannot be shared across repos by label alone. + +## Decision +Register a **third repo-scoped runner instance** on `bfe-mpc-0640`, label +`warden-sdk` (own systemd unit `actions.runner.bfe-noah-warden-sdk.*`, own +`CPUQuota=400%`/`MemoryMax=6G` drop-in). Only the heavy `kernel-build` job uses +`runs-on: [self-hosted, warden-sdk]`; all host-testable jobs (tests, coverage, MC/DC, +benchmarks, badges, patches-apply) run on GitHub-hosted runners. + +## Consequences +- Isolated from the flare backend + flare-edge CI already on that host (cgroup-capped). +- Runner setup + host build deps + the project-local `python` venv documented in + `docs/ci-cd.md`, mirroring flare-edge's. diff --git a/docs/decisions/0005-driver-source-of-truth.md b/docs/decisions/0005-driver-source-of-truth.md new file mode 100644 index 0000000..053007c --- /dev/null +++ b/docs/decisions/0005-driver-source-of-truth.md @@ -0,0 +1,21 @@ +# ADR 0005 — Hardened drivers live in warden-sdk/drivers/ + +**Status:** Accepted (2026-08-25). + +## Context +Our own hardware-facing driver code (relays, modbus master, RGA wrapper, HPMCU +supervisor, devmem/reset ladder, freshness) is the Tier-1 MC/DC target, but it +currently lives in flare-edge. The kernel driver source lives in an un-versioned +scratch tree (`flare-edge/research/linux-6.18.46/`). + +## Decision +Bring **hardened copies into `warden-sdk/drivers/`** as the canonical source-of-truth, +each with its HAL seam and a 100% MC/DC host harness. The RV1106 kernel deltas are +formalized as a patch series in `patches/`. flare-edge consumes warden-sdk later +(separate, [maintainer]-gated step). + +## Consequences +- Realizes the seam architecture (ADR-referenced in `docs/architecture.md`). +- flare-edge is not edited now; a later integration step points flare-edge at these. +- Risk: temporary duplication of shared constants between the two repos until the + integration lands — tracked, acceptable for the bring-up window. diff --git a/kernel/rv1106-enablement/CAPABILITIES-AUDIT.md b/kernel/rv1106-enablement/CAPABILITIES-AUDIT.md index c7a5292..fd06830 100644 --- a/kernel/rv1106-enablement/CAPABILITIES-AUDIT.md +++ b/kernel/rv1106-enablement/CAPABILITIES-AUDIT.md @@ -16,8 +16,20 @@ PWM backlight · **USB host** (dwc3/xhci) + usb2phy · grf/pmu syscons. - **GMAC** — eth0 Link Up 100 Mbps/Full (`gmac/`). - **SARADC** — iio:device0 reads 2 ch; the −22 was vref, not clk (`adc/SARADC-FIX.md`). +## ✅ VOP display — VERIFIED this run (2026-08-25) +Full WardenOS Dashboard renders on the 86-Panel on 6.18 (`_b`), webcam-verified, +pixel-identical to stock `_a`. Two VOP driver bugs were the final black-screen +cause: `rgb_dclk_pol` hardcoded inverted (panel needs 0), and the wrong primary +scanout window (rv1106 uses **WIN1**, not rv1126's WIN2). Full chain + `_a`-vs-`_b` +register diff in `display/VERIFIED.md`. + +## ✅ GT911 touch — VERIFIED this run (2026-08-25) +UI responds to taps/swipes on the panel ([maintainer]-confirmed); GT911 detected +(`ID 911, version 1060`), `/dev/input/event0` held by warden-ui. Fix: +`CONFIG_TOUCHSCREEN_GOODIX=y` (built-in — the rootfs `goodix.ko` is a 5.10 build +that can't load on 6.18) + GT911 node on `&i2c3`. Details in `touch/VERIFIED.md`. + ## 🔨 In flight -- **VOP display** — binds; connector is tomorrow's on-panel work. - **i2s-tdm** — DAI builds; needs the codec + card (below). - **AIC8800 BT** — module built (6.18 vermagic); HCI bring-up not yet exercised. diff --git a/kernel/rv1106-enablement/display/README.md b/kernel/rv1106-enablement/display/README.md index 54941d1..ebd4326 100644 --- a/kernel/rv1106-enablement/display/README.md +++ b/kernel/rv1106-enablement/display/README.md @@ -39,13 +39,11 @@ rockchip-drm display-subsystem: bound ff990000.vop brightness settable). **The VOP driver port is validated** — the register data, version, feature, and resets are right. -## Open (needs on-panel eyes + a little more debug) +## ✅ RESOLVED — full UI renders on the panel (2026-08-25) -`/sys/class/drm/card0-*` has **no connector yet** — `rockchip_rgb_init` isn't -producing one (log: `Cannot find any crtc or sizes`), despite INTERNAL_RGB set and -a clean vop→panel of_graph. Likely a panel-probe-order / `drm_of_find_panel_or_bridge` -detail. This is the last mile of M4 and, unlike the driver bind, needs the panel -physically observed (pixels can't be verified over serial/ssh). To pin it down: a -debug print in `rockchip_rgb_init` (child_count / find-panel ret), and set the panel -bus_format to `MEDIA_BUS_FMT_RGB666_1X18` (a small `panel_dpi_probe` addition, since -mainline panel-dpi doesn't read bus-format from DT). +The connector *and* the deeper black-screen chain that followed it are fixed; the +86-Panel now draws the full WardenOS Dashboard on 6.18 (`_b`), verified by webcam. +The two final root causes were VOP driver bugs — `rgb_dclk_pol` hardcoded inverted, +and the wrong primary scanout window (rv1106 scans out via **WIN1**, not WIN2). +See **`VERIFIED.md`** for the complete bring-up chain, the `_a`-vs-`_b` register +diff that pinned it down, and every file changed. diff --git a/kernel/rv1106-enablement/display/VERIFIED.md b/kernel/rv1106-enablement/display/VERIFIED.md new file mode 100644 index 0000000..a73f1f0 --- /dev/null +++ b/kernel/rv1106-enablement/display/VERIFIED.md @@ -0,0 +1,87 @@ +# Display (VOP + RGB panel) — ✅ VERIFIED on warden-c8a3 (2026-08-25) + +The 86-Panel renders the **full WardenOS Dashboard UI** on our self-built Linux +6.18.46 (`_b` slot), pixel-identical to the stock 5.10 `_a` slot. Verified by +webcam pointed at the physical panel (pixels can't be checked over serial/ssh) — +`warden-ui -b DRM` drawing the Dashboard: nav sidebar, "Wellhead 03" site card, +Mesh/WAN/LAN/RS485 status rows, correct colors, no banding, no colour swap. + +This closes the "Open" item in `README.md` (connector-not-created + the deeper +black-screen chain that followed it). + +## The bring-up chain (each step was a real blocker) + +1. **Connector never created** (`Cannot find any crtc`): `CONFIG_ROCKCHIP_RGB` + was not set, AND the vendor `&rgb` bridge node's dangling endpoint + (`rgb_in_vop -> vop_out_rgb`) read to fw_devlink as a vop↔panel dependency + cycle, so the VOP probed before the panel. Fix: enable `ROCKCHIP_RGB` + + `/delete-node/ &rgb;` so `vop_out_rgb <-> panel_in_vop` is the only graph link + (rockchip_rgb_init then defers + retries and finds the panel → `LVDS-1`). +2. **Backlight dark**: `&pwm1` had `pinctrl-names = "active"`; mainline + pwm-rockchip relies on the driver core auto-applying the **`"default"`** state, + so the PWM pin was never muxed. Fix: rename to `"default"`. +3. **bus-format unset** (RGB output width undefined): mainline `panel-dpi` + ignores the DT `bus-format`. Fix: small `panel_dpi_probe()` patch to read it + + `bus-format = ` on the panel node. +4. **RGB output pins unmuxed** (no data reaches the panel): the 22-pin parallel + bus (`lcd_clk` + `lcd_d0..d17` + den/hsync/vsync) needs the `&lcd_pins` mux. + The vendor carried it as `pinctrl-0 = <&lcd_pins>` **on the `&rgb` node**, which + we deleted in step 1. Fix: re-attach it on `&vop` (`pinctrl-names="default"`; + the core auto-applies it at VOP probe). +5. **`reset-gpios` on the panel node is WRONG** (leave it off): GPIO0_A1 resets the + CH32V003 panel-init MCU, released once early by U-Boot `board_init()`. Handing + it to `panel-simple` makes `drm_panel_prepare()` re-reset the MCU mid-scanout. + Luckfox deleted these props upstream (commit e2b0ffa22); the flare-edge 5.10 DTS + documents the deletion as "the fix." We match: **backlight only, no reset-gpios**. + +## The two root causes of the final "backlit-black" (VOP driver bugs) + +With connector + backlight + pins + panel-init all correct, the screen was still +physically black (backlight on, `LVDS-1` connected, VOP streaming, fb0 720×720, +`modetest`/splash written) — the classic "everything healthy, glass dark" state. +Found by dumping the VOP register block `0xff990000` on the **working `_a` slot** +and diffing against `_b` (same SoC, same register map): + +**Bug 1 — DCLK polarity inverted.** `rockchip_drm_vop.c` hardcodes +`rgb_dclk_pol = 1` for the LVDS/RGB output. The panel latches pixel data on the +**non-inverted** edge — `_a` reads `PX30_DSP_CTRL0` (0xff990020) = `0x1` +(rgb_dclk_pol bit1 = **0**). The vendor 5.10 derives it as +`(bus_flags & PIXDATA_DRIVE_NEGEDGE) ? 1 : 0`, which is 0 for this panel. With the +inverted clock the panel samples RGB on the wrong edge → black. **Fix:** set +`rgb_dclk_pol` to 0 in the `DRM_MODE_CONNECTOR_LVDS` case. + +**Bug 2 — wrong primary scanout window.** The rv1106 VOP scans out through +**WIN1**, but our port reused rv1126's win table (`win0`-overlay + **`win2`**-primary). +The vendor `rv1106_vop_win_data` is `{ NULL-win0, rk3366_lit_win1_data-primary }` — +i.e. WIN1 (`PX30_WIN1_*` at 0x090). Mainline was configuring WIN2, which never +reaches this SoC's RGB interface, so WIN1 stayed all-zero and nothing scanned out. +Register evidence (`_a` working vs `_b` broken, before the fix): + +| reg | name | `_a` (works) | `_b` (black) | +|---|---|---|---| +| 0x090 | WIN1_CTRL0 (enable) | `0x00000001` | `0x00000000` | +| 0x098 | WIN1_VIR (stride) | `0x000002D0` (720) | `0x00000000` | +| 0x0a0 | WIN1_MST (fb addr) | `0x0F900000` | `0x00000000` | +| 0x0a4 | WIN1_DSP_INFO (size)| `0x02CF02CF` (720×720) | `0x00EF013F` (stale) | + +**Fix:** `rv1106_vop_win_data[] = { { .phy = &px30_win1_data, PRIMARY } }` +(`px30_win1_data` already exists in mainline over `PX30_WIN1_*` — just wasn't wired +for rv1106). After the fix `_b` reads WIN1_CTRL0=1, WIN1_DSP_INFO=0x02CF02CF — +matching `_a`. + +## Files changed (in research/linux-6.18.46) + +- `drivers/gpu/drm/rockchip/rockchip_drm_vop.c` — `rgb_dclk_pol` 1 → 0 (LVDS case). +- `drivers/gpu/drm/rockchip/rockchip_vop_reg.c` — `rv1106_vop_win_data` uses + `px30_win1_data` as the single PRIMARY window (was rv1126's win0+win2). +- `drivers/gpu/drm/panel/panel-simple.c` — `panel_dpi_probe()` reads DT `bus-format`. +- `arch/arm/boot/dts/rockchip/rv1106-warden.dts` — `&vop` pinctrl `<&lcd_pins>`; + `&pwm1` pinctrl "default"; `/delete-node/ &rgb`; panel `bus-format` RGB666, + no reset-gpios. + +## Known separate issue (NOT display) + +`_b` still cold-reboots periodically (pre-existing `_b` general-stability issue, +independent of the display — the panel renders correctly the whole time it is up). +Tracked separately; the high-bootlimit env (`bootlimit=10000`) keeps these reboots +from tripping `altbootcmd=download` into the loader during bring-up. diff --git a/kernel/rv1106-enablement/touch/VERIFIED.md b/kernel/rv1106-enablement/touch/VERIFIED.md new file mode 100644 index 0000000..383c9c5 --- /dev/null +++ b/kernel/rv1106-enablement/touch/VERIFIED.md @@ -0,0 +1,57 @@ +# GT911 capacitive touch — ✅ VERIFIED on warden-c8a3 (2026-08-25) + +Touch works on our self-built 6.18.46 (`_b`): the WardenOS UI responds to +taps/swipes ([maintainer] confirmed on the physical panel). Objective evidence: + +``` +Goodix-TS 3-0014: ID 911, version: 1060 +input: Goodix Capacitive TouchScreen as .../i2c-3/3-0014/input/input0 +``` +`/dev/input/event0` is created and held open by `warden-ui` (pid 517, exclusive +EVIOCGRAB — which is why a second reader sees 0 bytes; the events go to the UI). + +## Root cause on `_b` + +Touch was dead on `_b` while fine on `_a`. dmesg showed: +``` +module goodix: .gnu.linkonce.this_module section size must match the kernel's +built struct module size at run time +``` +The **stock rootfs ships `goodix.ko` built for the 5.10 kernel**; it cannot load +on our 6.18 (`struct module` layout mismatch). Our 6.18 `.config` did **not** have +the driver at all (`# CONFIG_TOUCHSCREEN_GOODIX is not set`), and the DTS had no +GT911 node — so nothing drove the GT911. + +## Fix + +1. **`CONFIG_TOUCHSCREEN_GOODIX=y`** — build the mainline Goodix driver *into* the + kernel (no module → no vermagic/struct mismatch; the stale rootfs `.ko` still + fails to insmod but is now harmless). +2. **GT911 DT node** under `&i2c3` (matches the vendor 86-panel wiring): + ``` + touchscreen@14 { + compatible = "goodix,gt911"; + reg = <0x14>; + interrupt-parent = <&gpio0>; + interrupts = ; + irq-gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio3 RK_PD0 GPIO_ACTIVE_HIGH>; + }; + ``` + plus `pinctrl-0 = <&i2c3m2_xfer &tp_rst &tp_irq>` on `&i2c3` and the `tp_rst` + (GPIO3_D0) / `tp_irq` (GPIO0_A0) pin groups. + +Polarity note: mainline goodix drives reset **logical 0 = hold, 1 = release**, and +the GT911 reset is physically active-low, so `reset-gpios` is **ACTIVE_HIGH** +(logical==physical) — NOT the ACTIVE_LOW the vendor 5.10 driver used. Confirmed +against mainline gt911 DT examples (sun7i-a20-wexler-tab7200 etc.): both irq-gpios +and reset-gpios are ACTIVE_HIGH; reg 0x14 needs irq-gpios for address select. + +Non-fatal: `Direct firmware load for goodix_911_cfg.bin failed (-2)` — the GT911 +uses its flashed internal config; touch works without a cfg.bin. + +## Files changed (research/linux-6.18.46) + +- `.config` — `CONFIG_TOUCHSCREEN_GOODIX=y`. +- `arch/arm/boot/dts/rockchip/rv1106-warden.dts` — GT911 node on `&i2c3`, + `tp_rst`/`tp_irq` pin groups under `&pinctrl`.