Skip to content

nanopi-zero2: add USB support for RK3528 (current + edge)#9500

Open
rubycomm wants to merge 5 commits intoarmbian:mainfrom
rubycomm:nanopi-zero2-usb-support-v2
Open

nanopi-zero2: add USB support for RK3528 (current + edge)#9500
rubycomm wants to merge 5 commits intoarmbian:mainfrom
rubycomm:nanopi-zero2-usb-support-v2

Conversation

@rubycomm
Copy link
Contributor

@rubycomm rubycomm commented Mar 7, 2026

Summary

Add USB support for the FriendlyElec NanoPi Zero2 (RK3528) on mainline kernels (6.18 / 6.19):

  • USB2 PHY driver: Add RK3528 support to phy-rockchip-inno-usb2: standalone PHY at 0xffdf0000 with separate phy_base regmap and clkout_ctl_phy for 480MHz clock control
  • SoC DTS nodes: Add xHCI (DWC3), EHCI, OHCI controllers and USB2 PHY with OTG + Host ports to rk3528.dtsi
  • Board enablement: Enable all USB controllers on NanoPi Zero2: host-only DWC3 limited to high-speed (combo PHY used for PCIe)
  • Cleanup: Remove 6 upstreamed verisilicon AV1 patches from 6.18 + 6.19

Based on Jonas Karlman's (Kwiboo) WIP RK3528 USB work.

Tested on hardware

  • USB-A host port: USB storage mount/unmount, read/write
  • USB OTG port (via xHCI/DWC3): enumerated as host, high-speed
  • PCIe Gen2 x1: Intel AX210 WiFi detected and connected to network
  • Kernel: 6.18.16-current-rockchip64

Note on Intel AX210 WiFi firmware

The Armbian firmware package currently ships iwlwifi-ty-a0-gf-a0-59.ucode (v59), but kernel 6.18's iwlwifi driver requires v89 (iwlwifi-ty-a0-gf-a0-89.ucode). Without the correct firmware, the AX210 will be detected on PCIe but fail to initialize with no suitable firmware found!.

Workaround: manually copy iwlwifi-ty-a0-gf-a0-89.ucode and iwlwifi-ty-a0-gf-a0.pnvm from linux-firmware to /lib/firmware/ and reload with modprobe -r iwlwifi && modprobe iwlwifi.

This is not specific to this PR: it affects any board using AX210 with kernel 6.18+.

Summary by CodeRabbit

  • New Features

    • PCIe enabled for NanoPi Zero2 (M.2 WiFi slot)
    • USB2/USB3 host enabled for NanoPi Zero2
    • RK3528 USB2 PHY support added
  • Changes

    • NanoPi Zero2 board config: broadened kernel target set; DTB selection and serial-console handling adjusted for current/edge branches
  • Bug Fixes

    • AV1: fixed CDEF enable logic
    • AV1: corrected IDR flag for intra frames
    • AV1: fixed transform/tx-mode handling

rubycomm and others added 4 commits March 5, 2026 22:32
Enable mainline kernel (current/edge) for the NanoPi Zero2 (RK3528):

- Add current,edge to KERNEL_TARGET
- Override BOOT_FDT_FILE to rk3528-nanopi-zero2.dtb for mainline branches
  (vendor kernel uses rk3528-nanopi-rev01.dtb)
- Set SERIALCON=ttyS0 and patch boot script for mainline, as RK3528 debug
  UART is UART0 (ttyS0), not UART2 (ttyS2) like other RK35xx SoCs

Tested on hardware with kernel 6.18 (current branch).
Enable the PCIe Gen2x1 controller and combo PHY on the NanoPi Zero2
for the M.2 Key-E 2230 WiFi slot.

Signed-off-by: Shlomi Marco <s.marco@rubycomm.com>
These 3 patches are now included in mainline kernels 6.18 and 6.19,
causing "Reversed (or previously applied)" failures during patch application:
- media-0004: AV1 Fix enable cdef computation
- media-0005: AV1 Set IDR flag for intra_only frames
- media-0006: AV1 Fix tx mode bit setting

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add three kernel patches for USB support on the RK3528 SoC:
- phy-rockchip-inno-usb2: Add RK3528 USB2 PHY driver support
- rk3528.dtsi: Add xHCI, EHCI, OHCI and USB2 PHY device tree nodes
- nanopi-zero2: Enable USB host and OTG ports

Tested on hardware: USB storage, PCIe (AX210 WiFi) all working.
@github-actions github-actions bot added size/large PR with 250 lines or more 05 Milestone: Second quarter release Needs review Seeking for review Hardware Hardware related like kernel, U-Boot, ... Patches Patches related to kernel, U-Boot, ... labels Mar 7, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 7, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: dc156fde-1b06-4f96-a743-df86388d7fd9

📥 Commits

Reviewing files that changed from the base of the PR and between 6abe655 and f2b40ab.

📒 Files selected for processing (4)
  • patch/kernel/archive/rockchip64-6.18/rk3528-10-phy-rockchip-inno-usb2-Add-support-for-RK3528.patch
  • patch/kernel/archive/rockchip64-6.18/rk3528-11-arm64-dts-rockchip-rk3528-Add-USB-controller-and-PHY-nodes.patch
  • patch/kernel/archive/rockchip64-6.19/rk3528-10-phy-rockchip-inno-usb2-Add-support-for-RK3528.patch
  • patch/kernel/archive/rockchip64-6.19/rk3528-11-arm64-dts-rockchip-rk3528-Add-USB-controller-and-PHY-nodes.patch
🚧 Files skipped from review as they are similar to previous changes (1)
  • patch/kernel/archive/rockchip64-6.18/rk3528-11-arm64-dts-rockchip-rk3528-Add-USB-controller-and-PHY-nodes.patch

📝 Walkthrough

Walkthrough

Adds NanoPi Zero2 board support and RK3528 platform updates: expands KERNEL_TARGET, conditions device-tree DTB and serial console for branches, enables PCIe and USB in board DT, adds RK3528 USB2 PHY driver support, and applies several Verisilicon AV1 decoder patches (CDEF enable logic, IDR flag change, TX-mode mapping/removal across kernel versions).

Changes

Cohort / File(s) Summary
Board config / U-Boot hooks
config/boards/nanopi-zero2.csc
KERNEL_TARGET changed from vendor to vendor,current,edge; added post_family_config__nanopi_zero2_mainline() to set BOOT_FDT_FILE and SERIALCON for current/edge; added post_family_tweaks__nanopi_zero2_serial_console() to replace console=ttyS2,1500000console=ttyS0,1500000 and regenerate boot.scr for current/edge.
PCIe device tree (NanoPi Zero2)
patch/kernel/archive/.../board-nanopi-zero2-enable-pcie.patch (6.18 & 6.19)
arch/arm64/boot/dts/rockchip/rk3528-nanopi-zero2.dts
Adds/enables &combphy { status = "okay"; } and a &pcie node with pinctrl-*, reset-gpios, and status = "okay" to enable PCIe Gen2x1 for M.2 Key‑E WiFi slot.
RK3528 USB PHY driver
patch/kernel/archive/.../rk3528-10-phy-rockchip-inno-usb2-Add-support-for-RK3528.patch (6.18 & 6.19)
drivers/phy/rockchip/phy-rockchip-inno-usb2.c
Adds RK3528-specific USB2 PHY support: introduces phy_base regmap, clkout_ctl_phy, RK3528 tuning function and rk3528_phy_cfgs, replaces usbgrf with phy_base in struct rockchip_usb2phy, and extends compatibility table.
RK3528 base DTS USB nodes
patch/kernel/archive/.../rk3528-11-arm64-dts-rockchip-rk3528-Add-USB-controller-and-PHY-nodes.patch (6.18 & 6.19)
arch/arm64/boot/dts/rockchip/rk3528.dtsi
Adds USB subsystem nodes: usb_host0_xhci (DWC3), usb_host0_ehci, usb_host0_ohci, and u2phy with u2phy_otg/u2phy_host; nodes are added disabled by default.
NanoPi Zero2 DTS USB enablement
patch/kernel/archive/.../rk3528-12-arm64-dts-rockchip-nanopi-zero2-Enable-USB.patch (6.18 & 6.19)
arch/arm64/boot/dts/rockchip/rk3528-nanopi-zero2.dts
Enables USB: sets status = "okay" for &u2phy, &u2phy_host, &u2phy_otg, &usb_host0_ehci, &usb_host0_ohci, &usb_host0_xhci; sets dr_mode = "host" and maximum-speed = "high-speed" for XHCI and wires phy-supply to usb2_host_5v.
Verisilicon AV1 decoder patches
patch/kernel/archive/.../media-0004-0006-*.patch (6.18 & 6.19 sets)
Multiple AV1 decoder changes: compute enable_cdef from actual CDEF fields (write to av1_enable_cdef in set_cdef), change IDR flag write to use IS_INTRA(...), and add/remove TX-mode mapping logic across versions (enum + helper added in 6.18 set, later removed in 6.19 set).

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

size/medium

Suggested reviewers

  • igorpecovnik
  • catalinii
  • brentr
  • joekhoobyar
  • prahal
  • chainsx

Poem

🐰 I hopped through patches, small and spry,

PCIe woke, USB waved hi,
DTBs and PHYs all set in rows,
AV1 sings where video flows,
NanoPi hums — the rabbit knows.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'nanopi-zero2: add USB support for RK3528 (current + edge)' directly and clearly describes the main objective: adding USB support for the NanoPi Zero2 board on RK3528 SoC for current and edge kernel branches.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@rubycomm rubycomm changed the title Nanopi zero2 usb support v2 nanopi-zero2: add USB support for RK3528 (current + edge) Mar 7, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
config/boards/nanopi-zero2.csc (1)

29-35: Make the boot.cmd rewrite fail fast.

sed -i succeeds even when the expected console=ttyS2,1500000 token disappears from boot.cmd. On a headless board that silently ships current/edge images with the wrong serial console.

Suggested hardening
 function post_family_tweaks__nanopi_zero2_serial_console() {
 	case "${BRANCH}" in
 		current|edge)
 			display_alert "$BOARD" "Adjusting boot.cmd serial console to ttyS0 for ${BRANCH}" "info"
+			if ! grep -q 'console=ttyS2,1500000' "${SDCARD}"/boot/boot.cmd; then
+				display_alert "$BOARD" "boot.cmd no longer contains the ttyS2 console stanza" "err"
+				return 1
+			fi
 			sed -i 's/console=ttyS2,1500000/console=ttyS0,1500000/g' "${SDCARD}"/boot/boot.cmd
 			mkimage -C none -A arm -T script -d "${SDCARD}"/boot/boot.cmd "${SDCARD}"/boot/boot.scr
 			;;
 	esac
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@config/boards/nanopi-zero2.csc` around lines 29 - 35, The sed replacement in
post_family_tweaks__nanopi_zero2_serial_console currently runs silently even
when no token is changed; modify the function to verify the presence of the
expected token before/after editing (e.g., grep for "console=ttyS2,1500000" or
check that the resulting file contains "console=ttyS0,1500000"), and if the
replacement did not occur call display_alert "$BOARD" with an error and exit
non-zero so the mkimage step is not run; ensure the logic surrounds the sed
invocation and mkimage so failure fails fast and is clearly logged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@patch/kernel/archive/rockchip64-6.18/rk3528-10-phy-rockchip-inno-usb2-Add-support-for-RK3528.patch`:
- Around line 182-202: The rk3528_usb2phy_tuning function incorrectly
accumulates regmap_write() return values with bitwise OR; change each call to
check its return and propagate errors immediately: for each
regmap_write(rphy->phy_base, ... ) assign ret = regmap_write(...); if (ret)
return ret; (do this for the writes to offsets 0x30, 0x430, 0x30, 0x430, and
0x94) so the function returns the actual negative errno from the failing
regmap_write instead of a corrupted value.

In
`@patch/kernel/archive/rockchip64-6.18/rk3528-11-arm64-dts-rockchip-rk3528-Add-USB-controller-and-PHY-nodes.patch`:
- Around line 31-52: The DWC3 USB node (usb_host0_xhci / usb@fe500000) and
associated PHY need RK3528 power-domain links so runtime PM/genpd works; add
appropriate power-domains properties: assign the DWC3 controller node
(usb_host0_xhci / usb@fe500000) to the VPU power-domain (the upstream patch uses
RK3528_PD_VPU, typically referenced as &pd_vpu) and ensure EHCI/OHCI and the
u2phy_otg PHY nodes are bound to the VO power-domain (RK3528_PD_VO, typically
&pd_vo); update the usb_host0_xhci node and the u2phy_otg / EHCI/OHCI nodes to
include these power-domains phandles so the blocks participate in
genpd/runtime-PM.

In
`@patch/kernel/archive/rockchip64-6.19/rk3528-11-arm64-dts-rockchip-rk3528-Add-USB-controller-and-PHY-nodes.patch`:
- Around line 31-52: The USB DWC3 node usb_host0_xhci (usb@fe500000) is missing
power-domain links; add a power-domains property referencing the appropriate
RK3528 genpd identifiers so DWC3 is in RK3528_PD_VPU and the companion
EHCI/OHCI/u2phy nodes (e.g., the &u2phy node) are in RK3528_PD_VO as per
upstream; update the usb_host0_xhci node to include the correct phandles/names
for RK3528_PD_VPU and ensure the u2phy/EHCI/OHCI nodes include RK3528_PD_VO in
their power-domains to enable runtime PM/genpd handling.

---

Nitpick comments:
In `@config/boards/nanopi-zero2.csc`:
- Around line 29-35: The sed replacement in
post_family_tweaks__nanopi_zero2_serial_console currently runs silently even
when no token is changed; modify the function to verify the presence of the
expected token before/after editing (e.g., grep for "console=ttyS2,1500000" or
check that the resulting file contains "console=ttyS0,1500000"), and if the
replacement did not occur call display_alert "$BOARD" with an error and exit
non-zero so the mkimage step is not run; ensure the logic surrounds the sed
invocation and mkimage so failure fails fast and is clearly logged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: fa4b2774-2ec9-48cf-a1c4-b3b1a360c0d9

📥 Commits

Reviewing files that changed from the base of the PR and between 25c4cfe and 6abe655.

📒 Files selected for processing (15)
  • config/boards/nanopi-zero2.csc
  • patch/kernel/archive/rockchip64-6.18/board-nanopi-zero2-enable-pcie.patch
  • patch/kernel/archive/rockchip64-6.18/media-0004-media-verisilicon-AV1-Fix-enable-cdef-computation.patch
  • patch/kernel/archive/rockchip64-6.18/media-0005-media-verisilicon-AV1-Set-IDR-flag-for-intra_only-fr.patch
  • patch/kernel/archive/rockchip64-6.18/media-0006-media-verisilicon-AV1-Fix-tx-mode-bit-setting.patch
  • patch/kernel/archive/rockchip64-6.18/rk3528-10-phy-rockchip-inno-usb2-Add-support-for-RK3528.patch
  • patch/kernel/archive/rockchip64-6.18/rk3528-11-arm64-dts-rockchip-rk3528-Add-USB-controller-and-PHY-nodes.patch
  • patch/kernel/archive/rockchip64-6.18/rk3528-12-arm64-dts-rockchip-nanopi-zero2-Enable-USB.patch
  • patch/kernel/archive/rockchip64-6.19/board-nanopi-zero2-enable-pcie.patch
  • patch/kernel/archive/rockchip64-6.19/media-0004-media-verisilicon-AV1-Fix-enable-cdef-computation.patch
  • patch/kernel/archive/rockchip64-6.19/media-0005-media-verisilicon-AV1-Set-IDR-flag-for-intra_only-fr.patch
  • patch/kernel/archive/rockchip64-6.19/media-0006-media-verisilicon-AV1-Fix-tx-mode-bit-setting.patch
  • patch/kernel/archive/rockchip64-6.19/rk3528-10-phy-rockchip-inno-usb2-Add-support-for-RK3528.patch
  • patch/kernel/archive/rockchip64-6.19/rk3528-11-arm64-dts-rockchip-rk3528-Add-USB-controller-and-PHY-nodes.patch
  • patch/kernel/archive/rockchip64-6.19/rk3528-12-arm64-dts-rockchip-nanopi-zero2-Enable-USB.patch
💤 Files with no reviewable changes (6)
  • patch/kernel/archive/rockchip64-6.19/media-0005-media-verisilicon-AV1-Set-IDR-flag-for-intra_only-fr.patch
  • patch/kernel/archive/rockchip64-6.18/media-0005-media-verisilicon-AV1-Set-IDR-flag-for-intra_only-fr.patch
  • patch/kernel/archive/rockchip64-6.18/media-0004-media-verisilicon-AV1-Fix-enable-cdef-computation.patch
  • patch/kernel/archive/rockchip64-6.19/media-0004-media-verisilicon-AV1-Fix-enable-cdef-computation.patch
  • patch/kernel/archive/rockchip64-6.18/media-0006-media-verisilicon-AV1-Fix-tx-mode-bit-setting.patch
  • patch/kernel/archive/rockchip64-6.19/media-0006-media-verisilicon-AV1-Fix-tx-mode-bit-setting.patch

- Fix error handling in USB2 PHY tuning: use individual return checks
  instead of ret |= pattern (thanks @coderabbitai)
- Remove power-domains properties from USB DTS nodes: causes kernel
  panic (synchronous external abort in rockchip_pmu_set_idle_request)
  as RK3528 PMU idle request registers are not ready for these domains
- Fix patch hunk headers to match updated line counts

Tested on hardware: both current (6.18) and edge (6.19) boot
successfully with working USB.
@rubycomm
Copy link
Contributor Author

rubycomm commented Mar 9, 2026

Note on edge (6.19) kernel support: The USB patches work correctly on both current (6.18) and edge (6.19), this was verified on hardware.
However, we discovered that the ORAS-cached U-Boot artifact for rk3528 edge has a 0-byte FDT, which prevents booting. This is an infrastructure issue unrelated to these kernel patches. Filed as #9508.

Edge remains in KERNEL_TARGET since the patches themselves are correct and removing it would hide the real problem.

@rpardini
Copy link
Member

rpardini commented Mar 9, 2026

Nice @rubycomm , I've tried in the past to pick from Kwiboo ref USB on the E24C, but failed to boot with a panic when I enabled the combphy, something ref the VPU regulator not being really on before it does. Have you encountered or handled something similar? I could try it your take on the E24C if you say it is worth a shot.

Also, upstream? Jonas seems busy with other stuff and I don't wanna pester him...

@rpardini rpardini mentioned this pull request Mar 9, 2026
7 tasks
@rubycomm
Copy link
Contributor Author

@rpardini
Full disclosure, I've been using Claude Code as a co-pilot for this work (the commits have Co-Authored-By: Claude). It was instrumental for analyzing the power-domains panic and working through the patch details and other 6.18/6.19 work we desperately needed.

Per-board copy-paste isn't ideal. We only have the NanoPi Zero2 (along with a bunch of other non-3528 nanopis) to test with, so I'm not sure which approach would be best for rockchip64_common without risking other boards.
I'd be happy to move it to the right spot if you can point me to the right direction.

Regarding USB:
We hit exactly what you described, adding power-domains (RK3528_PD_VPU for xHCI, RK3528_PD_VO for EHCI/OHCI) caused a synchronous external abort in rockchip_pmu_set_idle_request. The PMU idle request register mappings aren't wired up for those domains yet. The fix was to leave them out (USB works fine without them).

It should definitely be worth trying on the E24C, the PHY driver and SoC-level DTS nodes are shared across all rk3528 boards. You'd just need a board-level patch to enable the USB nodes, similar to our rk3528-12 patch for the Zero2.

@paolosabatino
Copy link
Contributor

Hello, I've made some early work for mainlining rk3528 you can find here. the tvbox I was working on was booting fine and (AFAIR) USB2/USB3 were working pretty well. I used the Jonas patches from patchwork and configured the node in the device tree accordingly.
Had the same kernel panic experiences when trying to wire up the power domains, left them out and USB ports were still working.

@rpardini
Copy link
Member

Nice, thanks for the info. I've cycled my E24C out of it's production-like role, and will pick and rebase this on 7.0-rcX as soon as I have time and test it there.

@paolosabatino
Copy link
Contributor

Nice, thanks for the info. I've cycled my E24C out of it's production-like role, and will pick and rebase this on 7.0-rcX as soon as I have time and test it there.

A question: does HDMI works on mainline kernel for rk3528? I could not be able to let it work on my tv box, but reading here and there it looks like the HDMI phy driver was surely missing at the time (not to mention the power domains issues...)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

05 Milestone: Second quarter release Hardware Hardware related like kernel, U-Boot, ... Needs review Seeking for review Patches Patches related to kernel, U-Boot, ... size/large PR with 250 lines or more

Development

Successfully merging this pull request may close these issues.

3 participants