From 83771d0fc7eb05b494cb1572485e2ce25c58d241 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 11 Feb 2026 20:03:48 +0000 Subject: [PATCH 1/9] Initial plan From 4c4b13bc4bee50eb2f559093161454abd49c682d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 11 Feb 2026 20:13:24 +0000 Subject: [PATCH 2/9] Fix reset button: add logind reboot config, remove vendor-only pwrkey DT node, clean up kernel config Co-authored-by: edtubbs <84785904+edtubbs@users.noreply.github.com> --- docs/nanopc-T6.md | 58 ++++++++++--------- nix/builders/nanopc-t6/base.nix | 25 +++++--- .../nanopc-t6/rk3588-nanopc-t6.dtsi.patch | 9 --- 3 files changed, 49 insertions(+), 43 deletions(-) diff --git a/docs/nanopc-T6.md b/docs/nanopc-T6.md index b239ae5..f3d24a8 100644 --- a/docs/nanopc-T6.md +++ b/docs/nanopc-T6.md @@ -34,43 +34,49 @@ Documentation used for NixOS/Dogebox support: ## Reset Button Support -The NanoPC-T6 has a physical reset/power button that is **connected to the RK806 PMIC's pwrkey input**, not to a GPIO pin. This button is configured in the device tree patch (`rk3588-nanopc-t6.dtsi.patch`) as follows: +The NanoPC-T6 has a physical power/reset button connected to the **RK806 PMIC's pwrkey input** (not to a GPIO pin). -- **Connection**: RK806 PMIC pwrkey input -- **Driver**: `rk805-pwrkey` (automatically instantiated by MFD driver) -- **Key Code**: KEY_POWER -- **Kernel Config**: - - `CONFIG_INPUT_RK805_PWRKEY=y` - - `CONFIG_MFD_RK806_SPI=y` (FriendlyARM kernel variant) +### How It Works -The button works by triggering interrupts (PWRON_FALL and PWRON_RISE) on the RK806 PMIC, which are handled by the kernel's rk805-pwrkey driver. This is the same mechanism used in U-Boot and the FriendlyARM kernel fork. +1. **Hardware**: Button press triggers the RK806 PMIC's PWRON interrupt lines (PWRON_FALL on press, PWRON_RISE on release) +2. **Kernel**: The mainline `rk8xx-core.c` MFD driver automatically registers an `rk805-pwrkey` platform device for RK806 PMICs — no device tree `pwrkey` node is needed +3. **Input**: The `rk805-pwrkey` driver generates `KEY_POWER` input events +4. **Userspace**: `systemd-logind` handles `KEY_POWER` events according to `HandlePowerKey` configuration -### Device Tree Configuration +### Kernel Configuration -In the PMIC node (`&spi2 > pmic@0`), the pwrkey node is enabled after the DVS pinctrl definitions and before the `regulators` block: +The following kernel config options are required (added via `structuredExtraConfig` since nabam's kernel doesn't include them): -```dts -rk806_dvs3_null: dvs3-null-pins { - pins = "gpio_pwrctrl3"; - function = "pin_fun0"; -}; +- `CONFIG_MFD_RK8XX_SPI=y` — RK806 PMIC MFD driver via SPI bus +- `CONFIG_INPUT_RK805_PWRKEY=y` — Power key input driver for RK8XX PMICs +- `CONFIG_PINCTRL_RK805=y` — RK8XX family pinctrl driver -pwrkey { - status = "okay"; -}; +These are **mainline kernel** config names. The FriendlyARM vendor kernel (v6.1.y) uses different names (`CONFIG_MFD_RK806_SPI`, etc.) — do not confuse them. -regulators { - ... -} -``` +### systemd-logind Configuration -This enables the MFD driver to instantiate the power key device, which registers as a standard input device generating KEY_POWER events. +The power key behavior is configured in `base.nix`: -**Important Note**: The pwrkey node placement matches the Rockchip kernel device tree structure, which differs from mainline Linux. It should come after the pinctrl definitions and before the regulators block in the Rockchip kernel. +- **Short press**: `HandlePowerKey=reboot` — triggers a clean reboot +- **Long press**: `HandlePowerKeyLongPress=poweroff` — triggers a clean shutdown -**Kernel Variant**: This system uses the FriendlyARM-based Rockchip kernel (`kernel_linux_latest_rockchip_stable`), which uses `rk806-core.c` MFD driver instead of mainline's `rk8xx-core.c`. The FriendlyARM driver checks for the pwrkey device tree node and requires it to be explicitly enabled with `status = "okay"`. +Without explicit configuration, NixOS defaults `HandlePowerKey` to `poweroff`, which on a headless device silently shuts down instead of rebooting. -**Previous Incorrect Approach**: Earlier attempts tried to configure the button as a GPIO key on GPIO1_PC0, but this was incorrect. The button is physically wired to the PMIC, not to a regular GPIO pin. +### Important: Mainline vs FriendlyARM Vendor Kernel + +This system uses `nabam/nixos-rockchip`'s `kernel_linux_latest_rockchip_stable`, which is the **mainline Linux kernel** with Rockchip-specific config options. It is NOT the FriendlyARM vendor kernel (v6.1.y). + +Key differences for pwrkey: +- **Mainline kernel**: `rk8xx-core.c` unconditionally creates pwrkey MFD cell for RK806 — no DT node needed +- **FriendlyARM kernel**: `rk806-core.c` requires an explicit `pwrkey { status = "okay"; }` DT node + +The device tree patch should NOT include a `pwrkey` node — it would be ignored by the mainline driver and could cause DT validation warnings. + +### Previous Incorrect Approach + +Earlier attempts tried: +1. Configuring the button as a GPIO key (GPIO1_PC0) — incorrect, button is wired to PMIC +2. Adding `pwrkey { status = "okay"; }` DT node — only works with FriendlyARM vendor kernel, not mainline ## Device peripheral firmware diff --git a/nix/builders/nanopc-t6/base.nix b/nix/builders/nanopc-t6/base.nix index 946208e..b60ec00 100644 --- a/nix/builders/nanopc-t6/base.nix +++ b/nix/builders/nanopc-t6/base.nix @@ -55,19 +55,28 @@ boot.loader.generic-extlinux-compatible.enable = true; boot.loader.timeout = 1; + # The NanoPC-T6 power/reset button is connected to the RK806 PMIC pwrkey input. + # The mainline kernel rk8xx-core MFD driver automatically creates a rk805-pwrkey + # platform device that generates KEY_POWER events on button press/release. + # Configure systemd-logind to reboot on power key press (default is poweroff, + # which on a headless device silently shuts down instead of rebooting). + services.logind.settings.Login = { + HandlePowerKey = "reboot"; + HandlePowerKeyLongPress = "poweroff"; + }; + boot.kernelPackages = let - # Use nabam's mainline-based rockchip kernel + # Use nabam's mainline-based rockchip kernel (linux_latest with rockchip config). + # nabam's config includes REGULATOR_RK808, GPIO_ROCKCHIP, PINCTRL_ROCKCHIP, SPI_ROCKCHIP + # but is missing the RK8XX MFD SPI driver and pwrkey input driver needed for the + # RK806 PMIC on the NanoPC-T6. baseKernel = inputs.rockchip.legacyPackages.aarch64-linux.kernel_linux_latest_rockchip_stable; - - # Override with mainline RK8XX config options for RK806 PMIC support customKernel = baseKernel.kernel.override { structuredExtraConfig = with lib.kernel; { - # Mainline kernel RK8XX drivers (supports RK806) - MFD_RK8XX_SPI = yes; # MFD driver for RK806 via SPI - REGULATOR_RK808 = yes; # Regulator driver (covers RK806) - PINCTRL_RK805 = yes; # Pinctrl driver (covers RK806) - INPUT_RK805_PWRKEY = yes; # Power key input driver + MFD_RK8XX_SPI = yes; # RK806 PMIC MFD driver via SPI + PINCTRL_RK805 = yes; # RK8XX family pinctrl driver + INPUT_RK805_PWRKEY = yes; # RK8XX power key input driver }; }; in diff --git a/nix/builders/nanopc-t6/rk3588-nanopc-t6.dtsi.patch b/nix/builders/nanopc-t6/rk3588-nanopc-t6.dtsi.patch index c3909a3..204ddf4 100644 --- a/nix/builders/nanopc-t6/rk3588-nanopc-t6.dtsi.patch +++ b/nix/builders/nanopc-t6/rk3588-nanopc-t6.dtsi.patch @@ -24,12 +24,3 @@ + }; }; }; - -@@ -793,6 +811,9 @@ - gpio-controller; - #gpio-cells = <2>; -+ pwrkey { -+ status = "okay"; -+ }; - - rk806_dvs1_null: dvs1-null-pins { From d0711b303c69f811d1485c872a68de7c3fa460fb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 11 Feb 2026 20:14:23 +0000 Subject: [PATCH 3/9] Improve comment: clarify long press duration for power key Co-authored-by: edtubbs <84785904+edtubbs@users.noreply.github.com> --- nix/builders/nanopc-t6/base.nix | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nix/builders/nanopc-t6/base.nix b/nix/builders/nanopc-t6/base.nix index b60ec00..331bf15 100644 --- a/nix/builders/nanopc-t6/base.nix +++ b/nix/builders/nanopc-t6/base.nix @@ -58,8 +58,9 @@ # The NanoPC-T6 power/reset button is connected to the RK806 PMIC pwrkey input. # The mainline kernel rk8xx-core MFD driver automatically creates a rk805-pwrkey # platform device that generates KEY_POWER events on button press/release. - # Configure systemd-logind to reboot on power key press (default is poweroff, + # Configure systemd-logind to reboot on short press (default is poweroff, # which on a headless device silently shuts down instead of rebooting). + # Long press (~5s) triggers poweroff for intentional shutdown. services.logind.settings.Login = { HandlePowerKey = "reboot"; HandlePowerKeyLongPress = "poweroff"; From 45cdf1c6e4946402538255483324cde51caf5f77 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 11 Feb 2026 20:24:28 +0000 Subject: [PATCH 4/9] Fix reset button: add rockchip,reset-mode=1 to PMIC DT, document all 3 buttons correctly Co-authored-by: edtubbs <84785904+edtubbs@users.noreply.github.com> --- docs/nanopc-T6.md | 55 ++++++++++++------- nix/builders/nanopc-t6/base.nix | 22 ++++---- .../nanopc-t6/rk3588-nanopc-t6.dtsi.patch | 15 +++++ 3 files changed, 61 insertions(+), 31 deletions(-) diff --git a/docs/nanopc-T6.md b/docs/nanopc-T6.md index f3d24a8..b5ace7b 100644 --- a/docs/nanopc-T6.md +++ b/docs/nanopc-T6.md @@ -32,18 +32,19 @@ Documentation used for NixOS/Dogebox support: - CONFIG_VENDOR_FRIENDLYELEC=y - 'Zero memory on allocation' -## Reset Button Support +## Buttons -The NanoPC-T6 has a physical power/reset button connected to the **RK806 PMIC's pwrkey input** (not to a GPIO pin). +The NanoPC-T6 has **three distinct physical buttons** with different hardware connections and behaviors: -### How It Works +### 1. Power Button (PWRON) -1. **Hardware**: Button press triggers the RK806 PMIC's PWRON interrupt lines (PWRON_FALL on press, PWRON_RISE on release) -2. **Kernel**: The mainline `rk8xx-core.c` MFD driver automatically registers an `rk805-pwrkey` platform device for RK806 PMICs — no device tree `pwrkey` node is needed -3. **Input**: The `rk805-pwrkey` driver generates `KEY_POWER` input events -4. **Userspace**: `systemd-logind` handles `KEY_POWER` events according to `HandlePowerKey` configuration +- **Hardware**: Connected to the RK806 PMIC's **PWRON** input pin +- **Mechanism**: PMIC-level power control with interrupt notification to kernel +- **Kernel driver**: `rk805-pwrkey` (auto-created by mainline `rk8xx-core.c` MFD driver — no device tree `pwrkey` node needed) +- **Input event**: `KEY_POWER` +- **Behavior**: Handled by `systemd-logind` (`HandlePowerKey`). NixOS default is `poweroff`. -### Kernel Configuration +#### Kernel Configuration The following kernel config options are required (added via `structuredExtraConfig` since nabam's kernel doesn't include them): @@ -53,30 +54,42 @@ The following kernel config options are required (added via `structuredExtraConf These are **mainline kernel** config names. The FriendlyARM vendor kernel (v6.1.y) uses different names (`CONFIG_MFD_RK806_SPI`, etc.) — do not confuse them. -### systemd-logind Configuration +### 2. Reset Button (RESETB) -The power key behavior is configured in `base.nix`: +- **Hardware**: Connected to the RK806 PMIC's **RESETB** input pin +- **Mechanism**: Pure hardware reset — asserts RESETB low, which triggers the PMIC's reset function. **Bypasses the kernel entirely** (no software event, no clean shutdown) +- **Kernel driver**: None — handled at PMIC hardware level +- **Input event**: None +- **Behavior**: Configured by the `rockchip,reset-mode` device tree property on the RK806 PMIC node: + - Mode 0: Restart PMU (full power cycle, regulators briefly interrupted) + - Mode 1: Reset all power off registers, force state to ACTIVE mode + - Mode 2: Same as mode 1, also pulls RESETB pin down for 5ms -- **Short press**: `HandlePowerKey=reboot` — triggers a clean reboot -- **Long press**: `HandlePowerKeyLongPress=poweroff` — triggers a clean shutdown +The device tree patch sets `rockchip,reset-mode = <1>` to match the FriendlyARM vendor kernel behavior (`pmic-reset-func = <1>`). Without this property, the PMIC uses its hardware default. The mainline kernel's `rk8xx-core.c` reads this property during probe and writes it to `RK806_SYS_CFG3`. -Without explicit configuration, NixOS defaults `HandlePowerKey` to `poweroff`, which on a headless device silently shuts down instead of rebooting. +### 3. Mask ROM Button (SARADC) + +- **Hardware**: Connected to **SARADC channel 0** via voltage divider +- **Mechanism**: ADC-based key detection (reads analog voltage level) +- **Kernel driver**: `adc-keys` (already in mainline DTS as `adc-keys-0` node) +- **Input event**: `KEY_SETUP` (Mask Rom) +- **Behavior**: Used for entering Mask ROM/recovery mode when held during power-on. In U-Boot, detected via `CONFIG_BUTTON_ADC`. ### Important: Mainline vs FriendlyARM Vendor Kernel This system uses `nabam/nixos-rockchip`'s `kernel_linux_latest_rockchip_stable`, which is the **mainline Linux kernel** with Rockchip-specific config options. It is NOT the FriendlyARM vendor kernel (v6.1.y). -Key differences for pwrkey: -- **Mainline kernel**: `rk8xx-core.c` unconditionally creates pwrkey MFD cell for RK806 — no DT node needed -- **FriendlyARM kernel**: `rk806-core.c` requires an explicit `pwrkey { status = "okay"; }` DT node - -The device tree patch should NOT include a `pwrkey` node — it would be ignored by the mainline driver and could cause DT validation warnings. +Key differences: +- **Mainline kernel**: `rk8xx-core.c` unconditionally creates pwrkey MFD cell for RK806. Reset mode configured via `rockchip,reset-mode` DT property. +- **FriendlyARM kernel**: `rk806-core.c` requires an explicit `pwrkey { status = "okay"; }` DT node. Reset mode configured via `pmic-reset-func` DT property. -### Previous Incorrect Approach +### Previous Incorrect Approaches Earlier attempts tried: -1. Configuring the button as a GPIO key (GPIO1_PC0) — incorrect, button is wired to PMIC -2. Adding `pwrkey { status = "okay"; }` DT node — only works with FriendlyARM vendor kernel, not mainline +1. Configuring the reset button as a GPIO key (GPIO1_PC0) — incorrect, reset is wired to PMIC RESETB +2. Adding `pwrkey { status = "okay"; }` DT node — only works with FriendlyARM vendor kernel +3. Treating the power button and reset button as the same button — they are separate hardware +4. Configuring `HandlePowerKey=reboot` in systemd-logind — this changes the power button behavior, not the reset button which is hardware-only ## Device peripheral firmware diff --git a/nix/builders/nanopc-t6/base.nix b/nix/builders/nanopc-t6/base.nix index 331bf15..4c3ebb0 100644 --- a/nix/builders/nanopc-t6/base.nix +++ b/nix/builders/nanopc-t6/base.nix @@ -55,16 +55,18 @@ boot.loader.generic-extlinux-compatible.enable = true; boot.loader.timeout = 1; - # The NanoPC-T6 power/reset button is connected to the RK806 PMIC pwrkey input. - # The mainline kernel rk8xx-core MFD driver automatically creates a rk805-pwrkey - # platform device that generates KEY_POWER events on button press/release. - # Configure systemd-logind to reboot on short press (default is poweroff, - # which on a headless device silently shuts down instead of rebooting). - # Long press (~5s) triggers poweroff for intentional shutdown. - services.logind.settings.Login = { - HandlePowerKey = "reboot"; - HandlePowerKeyLongPress = "poweroff"; - }; + # NanoPC-T6 has three physical buttons: + # + # 1. Power button (PWRON) — connected to RK806 PMIC pwrkey input. + # Generates KEY_POWER via rk805-pwrkey driver. Handled by systemd-logind. + # Default NixOS behavior: short press = poweroff, which is correct. + # + # 2. Reset button (RESETB) — connected to RK806 PMIC RESETB pin. + # Hardware-level reset, bypasses kernel entirely. Configured via + # rockchip,reset-mode device tree property (see rk3588-nanopc-t6.dtsi.patch). + # + # 3. Mask ROM button — connected to SARADC channel 0. + # Used for entering Mask ROM/recovery mode during boot. boot.kernelPackages = let diff --git a/nix/builders/nanopc-t6/rk3588-nanopc-t6.dtsi.patch b/nix/builders/nanopc-t6/rk3588-nanopc-t6.dtsi.patch index 204ddf4..9b1a3e5 100644 --- a/nix/builders/nanopc-t6/rk3588-nanopc-t6.dtsi.patch +++ b/nix/builders/nanopc-t6/rk3588-nanopc-t6.dtsi.patch @@ -24,3 +24,18 @@ + }; }; }; + +@@ -809,6 +827,13 @@ + + system-power-controller; + ++ /* ++ * Configure PMIC reset behavior when RESETB pin is asserted ++ * (physical reset button). Mode 1: reset all power off registers, ++ * force state to ACTIVE mode (matches FriendlyARM pmic-reset-func=1). ++ */ ++ rockchip,reset-mode = <1>; ++ + vcc1-supply = <&vcc4v0_sys>; + vcc2-supply = <&vcc4v0_sys>; + vcc3-supply = <&vcc4v0_sys>; From 1bf5473166369d5a24004003f93b2d60cc606cc0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 12 Feb 2026 00:18:38 +0000 Subject: [PATCH 5/9] Fix reset button: change rockchip,reset-mode from 1 (no-op) to 0 (full PMU restart) Co-authored-by: edtubbs <84785904+edtubbs@users.noreply.github.com> --- docs/nanopc-T6.md | 9 +++++---- nix/builders/nanopc-t6/rk3588-nanopc-t6.dtsi.patch | 7 ++++--- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/docs/nanopc-T6.md b/docs/nanopc-T6.md index b5ace7b..bd2270f 100644 --- a/docs/nanopc-T6.md +++ b/docs/nanopc-T6.md @@ -61,11 +61,11 @@ These are **mainline kernel** config names. The FriendlyARM vendor kernel (v6.1. - **Kernel driver**: None — handled at PMIC hardware level - **Input event**: None - **Behavior**: Configured by the `rockchip,reset-mode` device tree property on the RK806 PMIC node: - - Mode 0: Restart PMU (full power cycle, regulators briefly interrupted) - - Mode 1: Reset all power off registers, force state to ACTIVE mode - - Mode 2: Same as mode 1, also pulls RESETB pin down for 5ms + - Mode 0: **Restart PMU** — full power cycle of all regulators, cold reboot (**correct for reset button**) + - Mode 1: Reset power-off registers, force ACTIVE state — **no visible effect on running system** + - Mode 2: Same as mode 1, also pulls RESETB output low for 5ms -The device tree patch sets `rockchip,reset-mode = <1>` to match the FriendlyARM vendor kernel behavior (`pmic-reset-func = <1>`). Without this property, the PMIC uses its hardware default. The mainline kernel's `rk8xx-core.c` reads this property during probe and writes it to `RK806_SYS_CFG3`. +The device tree patch sets `rockchip,reset-mode = <0>` for a full PMU restart (cold reboot) when the reset button is pressed. Mode 1 was previously used (matching FriendlyARM's `pmic-reset-func = <1>`) but is wrong for mainline: it only resets internal PMIC registers without power-cycling regulators, so a running system sees no effect. The FriendlyARM vendor PMIC driver (`rk806-core.c`) does additional initialization beyond what mainline's `rk8xx-core.c` does, which is why mode 1 may work differently in the vendor kernel. ### 3. Mask ROM Button (SARADC) @@ -90,6 +90,7 @@ Earlier attempts tried: 2. Adding `pwrkey { status = "okay"; }` DT node — only works with FriendlyARM vendor kernel 3. Treating the power button and reset button as the same button — they are separate hardware 4. Configuring `HandlePowerKey=reboot` in systemd-logind — this changes the power button behavior, not the reset button which is hardware-only +5. Using `rockchip,reset-mode = <1>` — mode 1 is a no-op for running systems (only resets PMIC registers, doesn't power-cycle) ## Device peripheral firmware diff --git a/nix/builders/nanopc-t6/rk3588-nanopc-t6.dtsi.patch b/nix/builders/nanopc-t6/rk3588-nanopc-t6.dtsi.patch index 9b1a3e5..c59bd85 100644 --- a/nix/builders/nanopc-t6/rk3588-nanopc-t6.dtsi.patch +++ b/nix/builders/nanopc-t6/rk3588-nanopc-t6.dtsi.patch @@ -31,10 +31,11 @@ + /* + * Configure PMIC reset behavior when RESETB pin is asserted -+ * (physical reset button). Mode 1: reset all power off registers, -+ * force state to ACTIVE mode (matches FriendlyARM pmic-reset-func=1). ++ * (physical reset button). Mode 0: restart PMU — full power ++ * cycle of all regulators, causing a cold reboot. ++ * Mode 1 (force ACTIVE) is a no-op on running systems. + */ -+ rockchip,reset-mode = <1>; ++ rockchip,reset-mode = <0>; + vcc1-supply = <&vcc4v0_sys>; vcc2-supply = <&vcc4v0_sys>; From b4a30e464b8c7224f0629354dff3f3807d44b4a5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 12 Feb 2026 01:09:38 +0000 Subject: [PATCH 6/9] Fix malformed patch: correct hunk line count from 13 to 14 in rk3588-nanopc-t6.dtsi.patch Co-authored-by: edtubbs <84785904+edtubbs@users.noreply.github.com> --- nix/builders/nanopc-t6/rk3588-nanopc-t6.dtsi.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nix/builders/nanopc-t6/rk3588-nanopc-t6.dtsi.patch b/nix/builders/nanopc-t6/rk3588-nanopc-t6.dtsi.patch index c59bd85..8313472 100644 --- a/nix/builders/nanopc-t6/rk3588-nanopc-t6.dtsi.patch +++ b/nix/builders/nanopc-t6/rk3588-nanopc-t6.dtsi.patch @@ -25,7 +25,7 @@ }; }; -@@ -809,6 +827,13 @@ +@@ -809,6 +827,14 @@ system-power-controller; From 2734d0b8f07a1dfdcb7fff5eb292fe99b20e37b1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 12 Feb 2026 20:29:14 +0000 Subject: [PATCH 7/9] Fix reset button: remove rockchip,reset-mode to preserve U-Boot's working PMIC config Co-authored-by: edtubbs <84785904+edtubbs@users.noreply.github.com> --- docs/nanopc-T6.md | 18 +++++++++++------- nix/builders/nanopc-t6/base.nix | 6 ++++-- .../nanopc-t6/rk3588-nanopc-t6.dtsi.patch | 15 --------------- 3 files changed, 15 insertions(+), 24 deletions(-) diff --git a/docs/nanopc-T6.md b/docs/nanopc-T6.md index bd2270f..9673be0 100644 --- a/docs/nanopc-T6.md +++ b/docs/nanopc-T6.md @@ -60,12 +60,14 @@ These are **mainline kernel** config names. The FriendlyARM vendor kernel (v6.1. - **Mechanism**: Pure hardware reset — asserts RESETB low, which triggers the PMIC's reset function. **Bypasses the kernel entirely** (no software event, no clean shutdown) - **Kernel driver**: None — handled at PMIC hardware level - **Input event**: None -- **Behavior**: Configured by the `rockchip,reset-mode` device tree property on the RK806 PMIC node: - - Mode 0: **Restart PMU** — full power cycle of all regulators, cold reboot (**correct for reset button**) - - Mode 1: Reset power-off registers, force ACTIVE state — **no visible effect on running system** - - Mode 2: Same as mode 1, also pulls RESETB output low for 5ms +- **Behavior**: Configured by `RST_FUN` bits [7:6] in the RK806's `SYS_CFG3` register (0x72). The mainline kernel DT binding (`rockchip,reset-mode`) and FriendlyARM vendor DT property (`pmic-reset-func`) both map to this register: + - Mode 0: **Restart PMU** — full power cycle of all regulators + - Mode 1: Reset all power-off registers, force state to ACTIVE mode (FriendlyARM default) + - Mode 2: Same as mode 1, also pulls RESETB pin low for 5ms (resets SoC via CHIP_RESETB) -The device tree patch sets `rockchip,reset-mode = <0>` for a full PMU restart (cold reboot) when the reset button is pressed. Mode 1 was previously used (matching FriendlyARM's `pmic-reset-func = <1>`) but is wrong for mainline: it only resets internal PMIC registers without power-cycling regulators, so a running system sees no effect. The FriendlyARM vendor PMIC driver (`rk806-core.c`) does additional initialization beyond what mainline's `rk8xx-core.c` does, which is why mode 1 may work differently in the vendor kernel. +**Current approach**: The DT patch does NOT set `rockchip,reset-mode`. This means the mainline `rk8xx-core.c` MFD driver skips the RST_FUN register write during probe, preserving whatever U-Boot configured. Since the reset button works correctly in U-Boot, preserving its PMIC configuration is the most reliable approach. + +FriendlyARM's vendor kernel uses `pmic-reset-func = <1>` and their vendor PMIC driver (`rk806-core.c`) handles it. Their driver does additional initialization beyond mainline's `rk8xx-core.c`, which is why mode values may behave differently between the two kernels. ### 3. Mask ROM Button (SARADC) @@ -80,7 +82,7 @@ The device tree patch sets `rockchip,reset-mode = <0>` for a full PMU restart (c This system uses `nabam/nixos-rockchip`'s `kernel_linux_latest_rockchip_stable`, which is the **mainline Linux kernel** with Rockchip-specific config options. It is NOT the FriendlyARM vendor kernel (v6.1.y). Key differences: -- **Mainline kernel**: `rk8xx-core.c` unconditionally creates pwrkey MFD cell for RK806. Reset mode configured via `rockchip,reset-mode` DT property. +- **Mainline kernel**: `rk8xx-core.c` unconditionally creates pwrkey MFD cell for RK806. Reset mode configured via `rockchip,reset-mode` DT property. During probe, `pre_init_reg` writes to `SYS_CFG3` bit[1] (slave restart) but does NOT touch RST_FUN bits[7:6] unless `rockchip,reset-mode` is present. - **FriendlyARM kernel**: `rk806-core.c` requires an explicit `pwrkey { status = "okay"; }` DT node. Reset mode configured via `pmic-reset-func` DT property. ### Previous Incorrect Approaches @@ -90,7 +92,9 @@ Earlier attempts tried: 2. Adding `pwrkey { status = "okay"; }` DT node — only works with FriendlyARM vendor kernel 3. Treating the power button and reset button as the same button — they are separate hardware 4. Configuring `HandlePowerKey=reboot` in systemd-logind — this changes the power button behavior, not the reset button which is hardware-only -5. Using `rockchip,reset-mode = <1>` — mode 1 is a no-op for running systems (only resets PMIC registers, doesn't power-cycle) +5. Setting `rockchip,reset-mode = <1>` — was never actually tested due to malformed patch (build failed) +6. Setting `rockchip,reset-mode = <0>` — mode 0 (restart PMU) may not reliably reset the SoC if power rails don't drop below POR threshold +7. **Solution**: Do not set `rockchip,reset-mode` at all — let U-Boot's working PMIC config persist through to Linux ## Device peripheral firmware diff --git a/nix/builders/nanopc-t6/base.nix b/nix/builders/nanopc-t6/base.nix index 4c3ebb0..0ed4ad1 100644 --- a/nix/builders/nanopc-t6/base.nix +++ b/nix/builders/nanopc-t6/base.nix @@ -62,8 +62,10 @@ # Default NixOS behavior: short press = poweroff, which is correct. # # 2. Reset button (RESETB) — connected to RK806 PMIC RESETB pin. - # Hardware-level reset, bypasses kernel entirely. Configured via - # rockchip,reset-mode device tree property (see rk3588-nanopc-t6.dtsi.patch). + # Hardware-level reset, bypasses kernel entirely. The PMIC's reset + # function (RST_FUN in SYS_CFG3) is configured by U-Boot and left + # untouched by the kernel — do NOT add rockchip,reset-mode to the + # device tree, as overriding U-Boot's working config breaks the button. # # 3. Mask ROM button — connected to SARADC channel 0. # Used for entering Mask ROM/recovery mode during boot. diff --git a/nix/builders/nanopc-t6/rk3588-nanopc-t6.dtsi.patch b/nix/builders/nanopc-t6/rk3588-nanopc-t6.dtsi.patch index 8313472..4305fc5 100644 --- a/nix/builders/nanopc-t6/rk3588-nanopc-t6.dtsi.patch +++ b/nix/builders/nanopc-t6/rk3588-nanopc-t6.dtsi.patch @@ -25,18 +25,3 @@ }; }; -@@ -809,6 +827,14 @@ - - system-power-controller; - -+ /* -+ * Configure PMIC reset behavior when RESETB pin is asserted -+ * (physical reset button). Mode 0: restart PMU — full power -+ * cycle of all regulators, causing a cold reboot. -+ * Mode 1 (force ACTIVE) is a no-op on running systems. -+ */ -+ rockchip,reset-mode = <0>; -+ - vcc1-supply = <&vcc4v0_sys>; - vcc2-supply = <&vcc4v0_sys>; - vcc3-supply = <&vcc4v0_sys>; From 7e1dfbe44cb4402a9bb69e4eb7c43c921d22c024 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Feb 2026 01:17:40 +0000 Subject: [PATCH 8/9] Fix reset button: kernel patch disables SLAVE_RESTART_FUN + DT uses reset-mode 2 Co-authored-by: edtubbs <84785904+edtubbs@users.noreply.github.com> --- docs/nanopc-T6.md | 17 +++++++++++------ nix/builders/nanopc-t6/base.nix | 13 +++++++++---- .../nanopc-t6/rk3588-nanopc-t6.dtsi.patch | 9 +++++++++ .../nanopc-t6/rk806-disable-slave-restart.patch | 10 ++++++++++ 4 files changed, 39 insertions(+), 10 deletions(-) create mode 100644 nix/builders/nanopc-t6/rk806-disable-slave-restart.patch diff --git a/docs/nanopc-T6.md b/docs/nanopc-T6.md index 9673be0..e3ca553 100644 --- a/docs/nanopc-T6.md +++ b/docs/nanopc-T6.md @@ -65,9 +65,13 @@ These are **mainline kernel** config names. The FriendlyARM vendor kernel (v6.1. - Mode 1: Reset all power-off registers, force state to ACTIVE mode (FriendlyARM default) - Mode 2: Same as mode 1, also pulls RESETB pin low for 5ms (resets SoC via CHIP_RESETB) -**Current approach**: The DT patch does NOT set `rockchip,reset-mode`. This means the mainline `rk8xx-core.c` MFD driver skips the RST_FUN register write during probe, preserving whatever U-Boot configured. Since the reset button works correctly in U-Boot, preserving its PMIC configuration is the most reliable approach. +**Current approach** (two-part fix): -FriendlyARM's vendor kernel uses `pmic-reset-func = <1>` and their vendor PMIC driver (`rk806-core.c`) handles it. Their driver does additional initialization beyond mainline's `rk8xx-core.c`, which is why mode values may behave differently between the two kernels. +1. **Kernel patch** (`rk806-disable-slave-restart.patch`): The mainline `rk8xx-core.c` MFD driver unconditionally enables `SLAVE_RESTART_FUN` (SYS_CFG3 bit[1]) during probe for multi-PMIC setups where a master can restart slave PMICs via the RESETB pin. On the NanoPC-T6 (single PMIC), this is unnecessary and may interfere with RESETB button input handling. The kernel patch changes the `rk806_pre_init_reg[]` entry from `RK806_SLAVE_RESTART_FUN_EN` to `RK806_SLAVE_RESTART_FUN_OFF`. + +2. **DT property** (`rockchip,reset-mode = <2>`): Mode 2 resets PMIC registers, forces ACTIVE state, AND explicitly pulls the RESETB output low for 5ms. This ensures the SoC's reset input (CHIP_RESETB_N) sees the reset signal. Mode 0 (PMU restart) might not reliably reset the SoC if bypass capacitors hold power rails above the POR threshold. Mode 2 avoids this by using the dedicated reset signal path. + +FriendlyARM's vendor kernel uses `pmic-reset-func = <1>` and their vendor PMIC driver (`rk806-core.c`) handles it differently from mainline. ### 3. Mask ROM Button (SARADC) @@ -82,8 +86,8 @@ FriendlyARM's vendor kernel uses `pmic-reset-func = <1>` and their vendor PMIC d This system uses `nabam/nixos-rockchip`'s `kernel_linux_latest_rockchip_stable`, which is the **mainline Linux kernel** with Rockchip-specific config options. It is NOT the FriendlyARM vendor kernel (v6.1.y). Key differences: -- **Mainline kernel**: `rk8xx-core.c` unconditionally creates pwrkey MFD cell for RK806. Reset mode configured via `rockchip,reset-mode` DT property. During probe, `pre_init_reg` writes to `SYS_CFG3` bit[1] (slave restart) but does NOT touch RST_FUN bits[7:6] unless `rockchip,reset-mode` is present. -- **FriendlyARM kernel**: `rk806-core.c` requires an explicit `pwrkey { status = "okay"; }` DT node. Reset mode configured via `pmic-reset-func` DT property. +- **Mainline kernel**: `rk8xx-core.c` unconditionally creates pwrkey MFD cell for RK806. Unconditionally enables `SLAVE_RESTART_FUN` in pre_init_reg. Reset mode configured via `rockchip,reset-mode` DT property. +- **FriendlyARM kernel**: `rk806-core.c` requires an explicit `pwrkey { status = "okay"; }` DT node. Does NOT enable `SLAVE_RESTART_FUN`. Reset mode configured via `pmic-reset-func` DT property. ### Previous Incorrect Approaches @@ -93,8 +97,9 @@ Earlier attempts tried: 3. Treating the power button and reset button as the same button — they are separate hardware 4. Configuring `HandlePowerKey=reboot` in systemd-logind — this changes the power button behavior, not the reset button which is hardware-only 5. Setting `rockchip,reset-mode = <1>` — was never actually tested due to malformed patch (build failed) -6. Setting `rockchip,reset-mode = <0>` — mode 0 (restart PMU) may not reliably reset the SoC if power rails don't drop below POR threshold -7. **Solution**: Do not set `rockchip,reset-mode` at all — let U-Boot's working PMIC config persist through to Linux +6. Setting `rockchip,reset-mode = <0>` — mode 0 (restart PMU) tested but didn't work; SoC may not reset if caps hold voltage +7. Removing `rockchip,reset-mode` entirely — tested but didn't work; letting U-Boot config persist wasn't enough because the MFD driver's `pre_init_reg` still modifies SYS_CFG3 (enables SLAVE_RESTART_FUN) +8. **Current fix**: Disable SLAVE_RESTART_FUN via kernel patch + set mode 2 via DT for explicit RESETB output assertion ## Device peripheral firmware diff --git a/nix/builders/nanopc-t6/base.nix b/nix/builders/nanopc-t6/base.nix index 0ed4ad1..6a0f681 100644 --- a/nix/builders/nanopc-t6/base.nix +++ b/nix/builders/nanopc-t6/base.nix @@ -62,10 +62,11 @@ # Default NixOS behavior: short press = poweroff, which is correct. # # 2. Reset button (RESETB) — connected to RK806 PMIC RESETB pin. - # Hardware-level reset, bypasses kernel entirely. The PMIC's reset - # function (RST_FUN in SYS_CFG3) is configured by U-Boot and left - # untouched by the kernel — do NOT add rockchip,reset-mode to the - # device tree, as overriding U-Boot's working config breaks the button. + # Hardware-level reset, bypasses kernel entirely. Requires two fixes: + # a) Kernel patch disables SLAVE_RESTART_FUN (rk806-disable-slave-restart.patch) + # so the MFD driver doesn't repurpose RESETB for multi-PMIC slave restart. + # b) DT sets rockchip,reset-mode = <2> which resets PMIC registers, forces + # ACTIVE state, AND pulls RESETB output low for 5ms to reset the SoC. # # 3. Mask ROM button — connected to SARADC channel 0. # Used for entering Mask ROM/recovery mode during boot. @@ -92,6 +93,10 @@ name = "rk3588-nanopc-t6.dtsi.patch"; patch = ./rk3588-nanopc-t6.dtsi.patch; } + { + name = "rk806-disable-slave-restart.patch"; + patch = ./rk806-disable-slave-restart.patch; + } ]; diff --git a/nix/builders/nanopc-t6/rk3588-nanopc-t6.dtsi.patch b/nix/builders/nanopc-t6/rk3588-nanopc-t6.dtsi.patch index 4305fc5..f1c5738 100644 --- a/nix/builders/nanopc-t6/rk3588-nanopc-t6.dtsi.patch +++ b/nix/builders/nanopc-t6/rk3588-nanopc-t6.dtsi.patch @@ -25,3 +25,12 @@ }; }; +@@ -775,6 +793,8 @@ + + system-power-controller; + ++ rockchip,reset-mode = <2>; ++ + vcc1-supply = <&vcc4v0_sys>; + vcc2-supply = <&vcc4v0_sys>; + vcc3-supply = <&vcc4v0_sys>; diff --git a/nix/builders/nanopc-t6/rk806-disable-slave-restart.patch b/nix/builders/nanopc-t6/rk806-disable-slave-restart.patch new file mode 100644 index 0000000..ece4770 --- /dev/null +++ b/nix/builders/nanopc-t6/rk806-disable-slave-restart.patch @@ -0,0 +1,10 @@ +--- a/drivers/mfd/rk8xx-core.c ++++ b/drivers/mfd/rk8xx-core.c +@@ -154,7 +154,7 @@ + static const struct rk808_reg_data rk806_pre_init_reg[] = { + { RK806_GPIO_INT_CONFIG, RK806_INT_POL_MSK, RK806_INT_POL_L }, +- { RK806_SYS_CFG3, RK806_SLAVE_RESTART_FUN_MSK, RK806_SLAVE_RESTART_FUN_EN }, ++ { RK806_SYS_CFG3, RK806_SLAVE_RESTART_FUN_MSK, RK806_SLAVE_RESTART_FUN_OFF }, + { RK806_SYS_OPTION, RK806_SYS_ENB2_2M_MSK, RK806_SYS_ENB2_2M_EN }, + }; + From ce2ae8727020c1a67ff0e0775006960d59356e2c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Feb 2026 17:09:22 +0000 Subject: [PATCH 9/9] Fix reset button: merge kernel config with nabam's base and apply patches directly in kernel override Co-authored-by: edtubbs <84785904+edtubbs@users.noreply.github.com> --- nix/builders/nanopc-t6/base.nix | 37 ++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/nix/builders/nanopc-t6/base.nix b/nix/builders/nanopc-t6/base.nix index 6a0f681..a29c3b2 100644 --- a/nix/builders/nanopc-t6/base.nix +++ b/nix/builders/nanopc-t6/base.nix @@ -65,8 +65,8 @@ # Hardware-level reset, bypasses kernel entirely. Requires two fixes: # a) Kernel patch disables SLAVE_RESTART_FUN (rk806-disable-slave-restart.patch) # so the MFD driver doesn't repurpose RESETB for multi-PMIC slave restart. - # b) DT sets rockchip,reset-mode = <2> which resets PMIC registers, forces - # ACTIVE state, AND pulls RESETB output low for 5ms to reset the SoC. + # b) DT sets rockchip,reset-mode = <2> which resets PMIC registers and forces + # ACTIVE state so the SoC power-on-resets. # # 3. Mask ROM button — connected to SARADC channel 0. # Used for entering Mask ROM/recovery mode during boot. @@ -77,28 +77,31 @@ # nabam's config includes REGULATOR_RK808, GPIO_ROCKCHIP, PINCTRL_ROCKCHIP, SPI_ROCKCHIP # but is missing the RK8XX MFD SPI driver and pwrkey input driver needed for the # RK806 PMIC on the NanoPC-T6. + # + # Use function-form override to merge our additions with nabam's existing + # structuredExtraConfig and to append our kernel patches (DTS + driver fix) + # directly into the kernel derivation. baseKernel = inputs.rockchip.legacyPackages.aarch64-linux.kernel_linux_latest_rockchip_stable; - customKernel = baseKernel.kernel.override { - structuredExtraConfig = with lib.kernel; { + customKernel = baseKernel.kernel.override (prev: { + structuredExtraConfig = (prev.structuredExtraConfig or {}) // (with lib.kernel; { MFD_RK8XX_SPI = yes; # RK806 PMIC MFD driver via SPI PINCTRL_RK805 = yes; # RK8XX family pinctrl driver INPUT_RK805_PWRKEY = yes; # RK8XX power key input driver - }; - }; + }); + kernelPatches = (prev.kernelPatches or []) ++ [ + { + name = "rk3588-nanopc-t6.dtsi.patch"; + patch = ./rk3588-nanopc-t6.dtsi.patch; + } + { + name = "rk806-disable-slave-restart.patch"; + patch = ./rk806-disable-slave-restart.patch; + } + ]; + }); in lib.mkForce (pkgs.linuxPackagesFor customKernel); - boot.kernelPatches = [ - { - name = "rk3588-nanopc-t6.dtsi.patch"; - patch = ./rk3588-nanopc-t6.dtsi.patch; - } - { - name = "rk806-disable-slave-restart.patch"; - patch = ./rk806-disable-slave-restart.patch; - } - ]; - boot.initrd.availableKernelModules = [ "nvme"