Files
bfe-core1106-sdk/kernel/rv1106-enablement/dts/rv1106-warden.dts
T
BFE EngineeringandClaude Fable 5 55b7cd5afa dts: document why usbdrd_dwc3 carries no extcon (D1-mod VBUS pins extcon to peripheral)
Tried extcon = <&u2phy> for 5.10 parity (2026-09-01) and reverted the same
day: bench/router panels self-source VBUS on the OTG port, so bvalid is
always high and extcon locks the role to peripheral, overriding debugfs mode
writes and orphaning a plugged USB NIC. Role stays manual (dwc3 debugfs mode,
router=host / client=gadget), with the switch sequence living in flare-edge
S26usbhost. See the usb2phy power-on issue for the remaining probe-time gap.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014L3eBF6wBXC55uJoZuUfS6
2026-09-01 14:45:07 -06:00

354 lines
10 KiB
Devicetree

// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* WardenOS 86-Panel board DT for the self-built Linux 6.18 forward-port.
*
* Includes the full vendor rv1106.dtsi (SoC nodes + pinctrl + gpio + dmac), then
* enables only what our wall-HMI needs — no camera/ISP/CSI. Grows one driver
* batch at a time toward full parity with the 5.10 kernel (DRIVER-PARITY.md).
*/
/dts-v1/;
#include <dt-bindings/display/media-bus-format.h>
#include "rv1106.dtsi"
/ {
model = "WardenOS 86-Panel (RV1106)";
compatible = "rockchip,rv1106-warden", "rockchip,rv1106";
chosen {
stdout-path = "serial2:115200n8";
bootargs = "earlycon=uart8250,mmio32,0xff4c0000 console=ttyS2,115200n8 earlyprintk rootwait";
};
memory@0 {
device_type = "memory";
reg = <0x00000000 0x10000000>; /* 256 MiB */
};
/* --- M5: AIC8800DC wifi/BT power sequencing --- */
sdio_pwrseq: sdio-pwrseq {
compatible = "mmc-pwrseq-simple";
pinctrl-names = "default";
reset-gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_LOW>;
};
/* SARADC voltage reference (1.8V) — the driver reads this for scale;
without it saradc probes -22 (regulator_get_voltage on the dummy). */
vcc_1v8: vcc-1v8 {
compatible = "regulator-fixed";
regulator-name = "vcc_1v8";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
};
/* --- console --- */
&uart2 {
status = "okay";
};
/* --- eMMC rootfs (M3) --- */
&emmc {
bus-width = <8>;
cap-mmc-highspeed;
mmc-hs200-1_8v;
non-removable;
status = "okay";
};
/* --- M5: AIC8800DC wifi/BT SDIO (on &sdmmc, mmc@ffaa0000 — NOT &sdio) --- */
&sdmmc {
max-frequency = <50000000>;
bus-width = <4>;
cap-sd-highspeed;
cap-sdio-irq;
keep-power-in-suspend;
non-removable;
rockchip,default-sample-phase = <90>;
supports-sdio;
mmc-pwrseq = <&sdio_pwrseq>;
pinctrl-names = "default";
pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_bus4 &sdmmc0_det>;
status = "okay";
};
/* --- batch 1: mainline peripherals (wire DT + config) --- */
&uart1 {
status = "okay";
};
&uart4 {
status = "okay";
};
/* --- GT911 capacitive touch on i2c3 (86-Panel HMI) ---
* The stock rootfs ships a goodix.ko built for the 5.10 kernel; it cannot load
* on our 6.18 (`struct module` size mismatch) so touch was dead on _b. Build
* CONFIG_TOUCHSCREEN_GOODIX=y instead (in the config fragment) and describe the
* GT911 here, matching the vendor 86-panel wiring: addr 0x14, IRQ GPIO0_A0
* (edge-falling), reset GPIO3_D0 (active-low). reset-gpios + irq-gpios let the
* mainline goodix driver run the GT911 power-on/address-select sequence. */
&i2c3 {
status = "okay";
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&i2c3m2_xfer &tp_rst &tp_irq>;
touchscreen@14 {
compatible = "goodix,gt911";
reg = <0x14>;
interrupt-parent = <&gpio0>;
interrupts = <RK_PA0 IRQ_TYPE_EDGE_FALLING>;
irq-gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
reset-gpios = <&gpio3 RK_PD0 GPIO_ACTIVE_HIGH>;
};
};
&pinctrl {
touch {
tp_rst: tp-rst {
rockchip,pins = <3 RK_PD0 RK_FUNC_GPIO &pcfg_pull_up>;
};
tp_irq: tp-irq {
rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
};
&saradc {
vref-supply = <&vcc_1v8>;
status = "okay";
};
&wdt {
status = "okay";
};
/* --- M4: display (VOP + RGB → 720x720 panel + PWM backlight) --- */
&display_subsystem {
status = "okay";
};
&vop {
status = "okay";
/* mainline rockchip_drm_vop requests named "ahb" + "dclk" resets that the
* vendor node omits; without them vop_bind fails "failed to get ahb reset". */
resets = <&cru SRST_H_VOP>, <&cru SRST_D_VOP>;
reset-names = "ahb", "dclk";
/*
* The 18-bit parallel RGB output (lcd_clk + lcd_d0..d17 + den/hsync/vsync,
* 22 pins) must be muxed to the VOP's LCDC function or NO pixel data reaches
* the panel -> backlit-black even with a fully healthy DRM pipeline. The
* vendor board carried this mux as pinctrl-0 = <&lcd_pins> ON THE &rgb node;
* we deleted &rgb (dangling-endpoint graph cycle), which silently dropped it.
* Re-attach it here: the driver core auto-applies the "default" pinctrl state
* when the VOP probes, exactly like the pwm1 backlight pin. Same root cause
* as the dark backlight -- an unmuxed output pin group. */
pinctrl-names = "default";
pinctrl-0 = <&lcd_pins>;
};
/* mainline wires vop_out straight to the panel (no separate rgb node) */
&vop_out_rgb {
remote-endpoint = <&panel_in_vop>;
};
&pwm1 {
status = "okay";
/* mainline pwm-rockchip does NOT pinctrl_select_state("active") the way
* the vendor 5.10 driver did; it relies on the pinctrl core auto-applying
* the "default" state at probe. With "active" the pin never gets muxed to
* PWM, so the backlight stays dark. Use "default". */
pinctrl-names = "default";
pinctrl-0 = <&pwm1m2_pins>;
};
/*
* NOTE on the RGB panel init MCU (WCH CH32V003, U6, net RGB_RES = GPIO0_A1):
* the panel controller is configured by that MCU's SPI init sequence, released
* once by U-Boot board_init() (stock boot). The WardenOS *userspace* (identical
* rootfs on _a and _b) also drives GPIO0_A1 as part of the panel bring-up, and
* on stock 5.10 (_a) the panel comes up fine that way. A kernel gpio-hog here
* FIGHTS that userspace management (two owners on the same line) and left the
* panel black on _b, so it is deliberately NOT hogged — matching _a, where only
* userspace touches the line.
*/
/ {
backlight: backlight {
compatible = "pwm-backlight";
pwms = <&pwm1 0 100000 50000>;
brightness-levels = <0 32 64 96 128 160 192 224 255>;
default-brightness-level = <8>;
status = "okay";
};
panel: panel {
compatible = "panel-dpi";
backlight = <&backlight>;
/* the 86-Panel is an 18-bit parallel RGB (RGB666) panel; without a
* bus-format the RGB output width is unset and the screen stays
* black. Read by our panel-dpi patch (upstream ignores it). */
bus-format = <MEDIA_BUS_FMT_RGB666_1X18>;
/*
* Deliberately NO reset-gpios / reset-delay-ms on this node.
* RGB_RES (GPIO0_A1) resets the CH32V003 init MCU, which is
* released exactly once, early, by U-Boot board_init() (shared
* across A/B slots) so the MCU SPI-inits the NV3052 panel
* controller before Linux. Handing reset-gpios to panel-simple
* makes drm_panel_prepare() REBOOT the MCU while the VOP is
* scanning out -- Luckfox deleted these two properties upstream
* for exactly this reason (commit e2b0ffa22), and the flare-edge
* 5.10 board DTS documents them as "the fix", not a regression.
* Verified black-screen root cause was the VOP dclk polarity, not
* this line (see rockchip_drm_vop.c rgb_dclk_pol). backlight stays
* (U-Boot rockchip_panel.c reads its handle from this node).
*/
width-mm = <85>;
height-mm = <85>;
panel-timing {
clock-frequency = <30000000>;
hactive = <720>;
vactive = <720>;
hback-porch = <44>;
hfront-porch = <46>;
vback-porch = <18>;
vfront-porch = <16>;
hsync-len = <2>;
vsync-len = <2>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <0>;
pixelclk-active = <0>;
};
port {
panel_in_vop: endpoint {
remote-endpoint = <&vop_out_rgb>;
};
};
};
};
/* The vendor rgb bridge node has no 6.18 driver and its dangling endpoint
* (rgb_in_vop -> vop_out_rgb) leaves a stray graph link that fw_devlink reads
* as a vop<->panel dependency cycle, so the VOP probes before the panel and the
* RGB connector is never created. DELETE it outright (disabling still left the
* endpoint in the graph) so vop_out_rgb <-> panel_in_vop is the only link. */
/delete-node/ &rgb;
/* --- sweep: USB OTG (eth0 gadget / host) via the ported inno-usb2 phy --- */
&u2phy {
status = "okay";
};
&u2phy_otg {
status = "okay";
};
&usbdrd {
status = "okay";
};
&usbdrd_dwc3 {
status = "okay";
dr_mode = "otg";
/* NO extcon, deliberately (tried 2026-09-01, reverted same day): our
* bench/router panels self-source VBUS on this port (D1 mod), so the
* phy's bvalid is always high and extcon pins the role to peripheral --
* the plugged USB NIC then never enumerates and debugfs "mode" writes
* are overridden. Without extcon, otg defaults to host and the role is
* switched at runtime per device role (router=host, client=gadget) via
* /sys/kernel/debug/usb/ffb00000.usb/mode -- S26usbhost's 6.18 path. */
};
/* --- sweep: RTC + thermal (tsadc) + I2S audio DAI --- */
&rtc {
status = "okay";
};
&tsadc {
status = "okay";
};
&i2s0_8ch {
status = "okay";
};
&rga2 {
status = "okay";
};
/* --- batch A: hardware RNG (trngv1, same IP as rk3588) --- */
&rng {
compatible = "rockchip,rv1106-rng";
status = "okay";
};
/* --- batch A: OTP / nvmem (chip id, MAC, PHY bandgap for GMAC) --- */
&otp {
status = "okay";
};
/* --- GMAC: wired 10/100 ethernet via the on-die RMII FEPHY --- */
&gmac {
status = "okay";
};
/* --- audio: i2s0_8ch (DAI) -> acodec (analog codec) -> speaker/headphone,
* tied together by a simple-audio-card. Matches the vendor 86-Panel wiring
* in rv1106-luckfox-pico-86panel-ipc.dtsi. The digital speaker modulator
* (dsm) driver is ported and builds, but is left disabled here: the panel
* uses the acodec path only, and the vendor board itself ships dsm
* disabled. --- */
&acodec {
#sound-dai-cells = <0>;
status = "okay";
};
&dsm {
status = "disabled";
};
/ {
acodec_sound: acodec-sound {
compatible = "simple-audio-card";
simple-audio-card,name = "rv1106-acodec";
simple-audio-card,format = "i2s";
simple-audio-card,mclk-fs = <256>;
simple-audio-card,cpu {
sound-dai = <&i2s0_8ch>;
};
simple-audio-card,codec {
sound-dai = <&acodec>;
};
};
};
/* --- HPMCU mailbox (A7 <-> RISC-V SCR1). Controller binds via the rk3368
* fallback compatible with zero driver patch; @ff5c0000 is the HPMCU-connected
* instance (SRST_CORE_MCU on the Linux side, MBOX_BASE 0xFF5C0000 on the MCU
* side). M-MBOX-1 proves the controller; M-MBOX-2 adds the SCR1 echo + round-trip. */
&mailbox {
status = "okay";
};
/* --- NPU (rknpu, ff660000). Kernel driver ported from the vendor 5.10 BSP
* (GPL source port -- see warden-sdk/kernel/rv1106-enablement/npu/PORT-PLAN.md
* and PORT-PROGRESS.md). compatible/reg/interrupts/clocks/resets are already
* fully specified in rv1106.dtsi's rv1106_rknpu_config-matching npu node --
* this is only the status flip, same pattern as every other block enabled
* in this file. No iommus= property (this board's NPU runs non-iommu,
* matching the 5.10 boot-log finding), no power-domains (single-rail). */
&npu {
/* the rknpu driver requests its IRQ by name ("npu_irq"); the base dtsi
* node declares the interrupt but no interrupt-names, so probe fails
* "IRQ npu_irq not found" without this. */
interrupt-names = "npu_irq";
status = "okay";
};