Skip to content

OrangePi5Pro: Comprehensive HW Support: YT6801 PCIe-Eth, Codec ES8388 Audio, eFUSE & U-Boot v2025.10#9600

Merged
igorpecovnik merged 9 commits into
armbian:mainfrom
c127dev:orangepi5-pro
Mar 27, 2026
Merged

OrangePi5Pro: Comprehensive HW Support: YT6801 PCIe-Eth, Codec ES8388 Audio, eFUSE & U-Boot v2025.10#9600
igorpecovnik merged 9 commits into
armbian:mainfrom
c127dev:orangepi5-pro

Conversation

@c127dev
Copy link
Copy Markdown
Contributor

@c127dev c127dev commented Mar 26, 2026

Description

This PR brings a comprehensive and stable hardware support for the Orange Pi 5 Pro SBC, bridging the gap between existing partial-support and a almost fully-functional SBC out of the box.

So, previously, the board relied on a .deb package installed during the first boot to enable the Motorcomm YT6801 Ethernet controller, which significantly slowed down the initial boot process. (Now 4~5s dmesg) This PR integrates the newly mainlined YT6801 driver directly into the current (6.18) and edge (7.0) kernels, alongside U-Boot v2025.10, fixing several low-level hardware bugs in the process.

Key Motivations and Fixes:

  • Ethernet YT6801 & eFUSE Race Condition: While implementing the mainline driver (merged Jan 2026 by Yao Zi), I discovered the eFUSE MAC address read constantly failed. After porting the driver to U-Boot and analyzing the behavior, I've identified a hardware race condition, so introduced a strict reset -> delay -> read sequence that guarantees the eFUSE MAC is correctly read in both U-Boot and the Linux Kernel.
  • U-Boot RX Descriptor Ring Fix: In U-Boot, the hardware would choke on incoming packets. After extensive DMA memory debugging, I found the RX descriptor ring of the Microchip was desynchronized with U-Boot's expected pace. Corrected the memory addresses and descriptor DSL sizes to achieve stable RX/TX. Bumped U-Boot to v2025.10.
  • Kernel 6.18 Backporting: Heavily backported the YT6801/YT8531S PHY support to the 6.18 LTS kernel, resolving several compilation errors and kernel panics related to the PCI/stmmac generic suspend/resume helpers.
  • Audio (ES8388) LRCK Sharing: The board's hardware design requires the capture and playback interfaces to share the same clock line. I patched the es8328 ASoC driver to explicitly allow LRCK sharing and added missing Mic Bias routing to the DTS. Both onboard mic and headphone jack now work flawlessly.
  • DTS Refactoring: Based the DTS on Dennis Gilmore's v2 patch from lore.kernel.org. (Note: v3 and v4 patches currently exhibit PCIe read issues, so v2 was heavily refactored and proven stable). Synced this DTS across U-Boot, current, and edge kernels.
  • Thermal/Power Safety: Mapped the PWM fan to a strict 20ms (50Hz) period. This is crucial because using standard 25kHz PWM causes the hardware's RC filter gate logic to overheat the MOSFETs.
  • Experimental: Enabled USB-C DP Alt-mode to HDMI routing.

Documentation summary for feature / change

If documentation entry is predicted, please provide key elements for further implementation into main documentation and set label to "Needs Documentation".

  • short description: Orange Pi 5 Pro: Full hardware support integration
  • summary: Native support added for Motorcomm YT6801 PCIe Ethernet (removing the need for first-boot .deb installation), enabled full audio support (3.5mm Jack Output and onboard/headset Microphone) via ES8388. Enabled safe PWM Fan control, M.2 NVMe, and AP6256 Wi-Fi/BT.
  • example of usage (how to see this in function)

How Has This Been Tested?

Extensive testing was performed across multiple environments to ensure stability in both the bootloader phase and different kernel versions.

  • U-Boot (v2025.10): Verified PCIe initialization. Confirmed Ethernet RX/TX functionality (successfully receives DHCP IP and sends packets without choking).
  • Kernel Edge (old 6.19): Full audio hardware verification. Successfully tested 3.5mm headphone output, onboard microphone input, and headset microphone input.
  • Kernel Edge (7.0): Booted minimal image. Verified Audio initialization via kernel registers an I2C, confirmed YT6801 Ethernet correctly reads and assigns the eFUSE MAC address.
  • Kernel Current (6.18): Verified Audio via registers and I2C, tested Ethernet stability, PWM Fan control (MOSFET temps stable at 50Hz), PCIe NVMe, and HDMI output.

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • My changes generate no new warnings
  • Any dependent changes have been merged and published in downstream modules

Summary by CodeRabbit

  • New Features

    • Added PCIe Ethernet support (Motorcomm NIC) with kernel driver and module.
    • Board device-tree updates: PWM-controlled fan, PWM LEDs, DisplayPort endpoint, SDIO Wi‑Fi/BT power sequencing, new regulators, revised audio routing and Bluetooth pinctrl.
  • Bug Fixes

    • Fixed eFuse MAC read race to improve MAC detection.
    • Improved PHY/interface compatibility and added microphone LRCK-sharing support for the audio codec.
  • Chores

    • Updated bootloader and upstream board support for Orange Pi 5 Pro.

c127dev and others added 5 commits March 26, 2026 01:14
This commit adds a suite of 4 patches for U-Boot v2025.10 to enable
full support for the Xunlong Orange Pi 5 Pro SBC.

The Orange Pi 5 Pro introduces several significant hardware departures
from the base Orange Pi 5, necessitating specific driver and DTS
adjustments:

1. Networking (Motorcomm YT6801):
   - The Pro variant replaces the SoC's built-in GMAC1 NIC with a
     PCIe-attached Motorcomm YT6801 controller.
   - Introduce a new glue driver (dwc_eth_qos_motorcomm) to bridge
     the core DWC EQoS IP to the PCIe bus.
   - Core EQoS driver is modified to support the YT6801's unique
     32-byte descriptor size and Descriptor Skip Length requirements.
   - Auto-generation of MAC addresses from CPU ID is disabled to
     preserve the hardware's native eFuse MAC.

2. Audio and I/O:
   - Audio routing is moved from I2S1 to I2S2 (M1 mux) with the
     ES8388 codec on I2C3.
   - LEDs are remapped from GPIO to PWM control (PWM3/PWM15).
   - Headphone amplifier enable is remapped to GPIO4_PB5.

3. Thermal and Power:
   - PWM Fan control is implemented with a specific 20ms (50Hz)
     period. This is CRITICAL because the hardware's RC filter gate
     logic causes MOSFET overheating if standard 25kHz PWM is used.

4. Wireless:
   - Full support for the AP6256 module via SDIO and UART9.

Patch Summary:
- [0001] Board support (DTS, defconfig, doc). DTS based on initial
         submission by Dennis Gilmore.
- [0002] Motorcomm YT6801 PCIe glue driver and PHY support.
- [0003] Core EQoS driver extension for descriptor/DSL overrides.
- [0004] Rockchip board MAC setup bypass for Pro hardware.

Signed-off-by: c127dev <contact@c127.dev>
…rnel

This commit enables full support for the Orange Pi 5 Pro on the current
Linux kernel (rockchip64-6.18). It includes a comprehensive device tree,
board configuration updates, and a series of patches for the PCIe Motorcomm
YT6801 Ethernet controller.

Key additions and modifications:

1. Device Tree Updates (rk3588s-orangepi-5-pro.dts):
   - Added support for DisplayPort 1.4 to HDMI 2.0 (DP0/VP2).
   - Configured USB3 Type-A ports (with USB2 OTG PHY) and explicitly set the
     USB-C port to power-delivery only (no FUSB302/data/alt-mode).
   - Configured combphy2_psu for NVMe M.2 slot support by disabling
     conflicting USB3 modes.
   - Re-mapped fan to PWM2 and LEDs to PWM3/PWM15.
   - Added full AP6256 Wi-Fi/Bluetooth support (SDIO and UART9).

2. Motorcomm YT6801 Ethernet Support (Patches 1-5):
   - Added generic suspend/resume helper for PCI-based controllers.
   - Backported glue driver for Motorcomm YT6801 and YT8531S PHY support.
   - Included fixes for eFUSE MAC address read failures.
   - Resolved specific stmmac/motorcomm driver compilation errors and
     panics on kernel 6.18.

3. Board Configuration (orangepi5pro.csc):
   - Refactored U-Boot configuration selection logic, segregating mainline
     and vendor branches correctly.
   - Configured the Armbian build system to automatically enable the newly
     added Motorcomm PHY, STMMAC_ETH, and STMMAC_PLATFORM kernel configs
     for the "current" and "edge" branches.

Signed-off-by: c127dev <contact@c127.dev>
This commit enables full support for the Orange Pi 5 Pro on the edge
Linux kernel (rockchip64-7.0). It synchronizes the device tree additions
with the current kernel and includes the necessary eFUSE MAC address fix for
the Motorcomm Ethernet controller.

Key additions and modifications:

1. Device Tree Updates (rk3588s-orangepi-5-pro.dts):
   - Added support for DisplayPort 1.4 to HDMI 2.0 (DP0/VP2).
   - Configured USB3 Type-A ports (with USB2 OTG PHY) and explicitly set the
     USB-C port to power-delivery only (no FUSB302/data/alt-mode).
   - Configured combphy2_psu for NVMe M.2 slot support by disabling
     conflicting USB3 modes.
   - Re-mapped fan to PWM2 and LEDs to PWM3/PWM15.
   - Added full AP6256 Wi-Fi/Bluetooth support (SDIO and UART9).

2. Motorcomm YT6801 Ethernet Support (Patches):
   - Included fix for Motorcomm YT6801 eFUSE MAC address read failures
     on the 7.0 kernel.

Signed-off-by: c127dev <contact@c127.dev>
This commit introduces a patch for the rockchip64 kernel (current 6.18 and
edge 7.0 branches) to fix audio routing issues affecting the ES8328 codec.

The patch modifies the ASoC es8328 driver to explicitly allow sharing the
LRCK (Left/Right Clock) between the microphone and playback interfaces.
This is required for hardware designs where capture and playback must share
the same clock line.

Signed-off-by: c127dev <contact@c127.dev>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 26, 2026

Important

Review skipped

Auto reviews are limited based on label configuration.

🏷️ Required labels (at least one) (1)
  • Needs review

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 842edd61-59db-4da4-9e31-e16f8468aaad

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds Orange Pi 5 Pro support and board-specific adjustments: new U‑Boot v2025.10 board and drivers, removal of v2025.07 patchset, Motorcomm YT6801 glue driver and PHY updates, STMMAC PCI helpers, eFUSE MAC-read fixes, ES8328 LRCK probe option, extensive RK3588S device-tree rewrites, and build-hook/config tweaks.

Changes

Cohort / File(s) Summary
Board config
config/boards/orangepi5pro.csc
Adjusted KERNEL_TARGET to current,edge,vendor, added KERNEL_TEST_TARGET="vendor,current", made audio renaming conditional on branch, added firmware symlink creation, renamed/adjusted U‑Boot hook and branch/patch version checks, removed first-boot PHY installer.
U‑Boot: new v2025.10 board & drivers
patch/u-boot/v2025.10/board_orangepi5pro/0001-*.patch, .../0002-*.patch, .../0003-*.patch, .../0004-*.patch
Adds Orange Pi 5 Pro defconfig and DTS, Motorcomm DWC EQoS glue driver (YT6801) with eFUSE MAC provisioning and fallback, descriptor-size/DSL overrides, and platform-specific Rockchip MAC auto-gen skip.
U‑Boot: removed v2025.07 board patchset
patch/u-boot/v2025.07/board_orangepi5pro/0001-*.patch
Deletes previously added v2025.07 Orange Pi 5 Pro U‑Boot patches (defconfig and DTS entries removed).
Kernel: Motorcomm glue driver & PHY changes
patch/kernel/.../board-orangepi5pro-net-stmmac-Add-glue-driver-for-Motorcomm-*.patch, .../board-orangepi5pro-net-phy-motorcomm-Support-YT8531S-*.patch
Introduces Motorcomm PCI glue driver for YT6801, PCI probe/reset/IRQ/MSI-X handling, eFUSE MAC read with fallback, and extends Motorcomm PHY code to accept GMII for YT8531S when appropriate.
Kernel: dwmac-motorcomm fixes
patch/kernel/.../dwmac-motorcomm-Fix-compilation-errors-an.patch, .../dwmac-motorcomm-fix-eFUSE-MAC-Address-Rea.patch
Fixes stmmac platform-data allocation/initialization, addresses eFUSE read race with atomic polling, init ordering change and 15–20ms post-reset delay.
Kernel: DWC EQoS descriptor overrides
patch/u-boot/v2025.10/.../0003-*.patch, drivers/net/dwc_eth_qos.h
Adds per-config overrides for descriptor size and Channel0 DSL; Motorcomm glue sets 32‑byte descriptors and DSL override.
Kernel: STMMAC PCI helpers
patch/kernel/.../board-orangepi5pro-net-stmmac-Add-generic-suspend-resume-helper-for-PCI.patch
Adds STMMAC_LIBPCI Kconfig, build wiring, and exported helpers stmmac_pci_plat_suspend() / stmmac_pci_plat_resume().
Kernel: ES8328 LRCK option (6.18 & 7.0)
patch/kernel/.../general-ASoC-codecs-es8328-allow-sharing-LRCK-for-microphone.patch, patch/kernel/archive/rockchip64-7.0/general-ASoC-codecs-es8328-allow-sharing-LRCK-for-microphone.patch
Adds device-tree boolean everest,mic-lrck-same handling in es8328_probe() to set DACCONTROL21 bit; probe fails on regmap error.
Kernel: Device Tree RK3588S Orange Pi 5 Pro (6.18)
patch/kernel/archive/rockchip64-6.18/dt/rk3588s-orangepi-5-pro.dts
Large DTS rework: removed /chosen RNG, reworked audio (ES8388/simple-audio-card), added PWM fan/thermal maps, new fixed regulators and SDIO pwrseq, LED/PWM changes, enabled PCIe endpoints and DP endpoints, disabled conflicting nodes (gmac1, sfc, usb_host2_xhci), and many pinctrl/IRQ adjustments.
Kernel: Device Tree RK3588S Orange Pi 5 Pro (7.0)
patch/kernel/archive/rockchip64-7.0/dt/rk3588s-orangepi-5-pro.dts
Ports/mirrors the 6.18 DT changes into the 7.0 tree with similar regulator/audio/PCIe/DP/USB/SDIO/fan/LED updates.
Kernel config
config/kernel/linux-rockchip-rk3588-edge.config
Enables CONFIG_DWMAC_MOTORCOMM (module) to build the Motorcomm DWMAC driver.

Sequence Diagram(s)

sequenceDiagram
    participant Boot as U-Boot/Kernel<br/>Boot
    participant PCI as PCI Bus
    participant Driver as Motorcomm<br/>Glue Driver
    participant HW as YT6801<br/>Controller
    participant eFUSE as eFUSE<br/>Controller
    participant STMMAC as STMMAC<br/>Core Driver

    Boot->>PCI: enumerate PCI devices
    PCI->>Driver: probe()
    Driver->>Driver: map BAR0, enable mem & bus mastering
    Driver->>HW: motorcomm_reset()
    HW-->>Driver: reset deasserted
    Driver->>Driver: usleep_range(15000,20000)
    Driver->>Driver: motorcomm_init()
    Driver->>eFUSE: motorcomm_efuse_read_mac()
    eFUSE->>eFUSE: readl_poll_timeout_atomic()
    eFUSE-->>Driver: MAC bytes (or zero)
    alt valid eFUSE MAC
        Driver->>Driver: use eFUSE MAC
    else
        Driver->>Driver: generate random MAC
    end
    Driver->>HW: configure DMA/AXI/core, disable OOB WOL
    Driver->>Driver: setup interrupts (MSI-X/MSI)
    Driver->>STMMAC: stmmac_dvr_probe()
    STMMAC-->>Boot: network available
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~65 minutes

Poem

🐰 I hopped through DTs, drivers, and pins so spry,

read eFUSE whispers beneath the PCI sky,
fans and codecs found their perfect tune,
U‑Boot and kernel waltzed beneath the moon,
tiny rabbit clap — a board that’ll fly!

🚥 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 title directly and specifically summarizes the main changes: YT6801 PCIe Ethernet support, ES8388 audio codec support, eFUSE fixes, and U-Boot v2025.10 upgrade for Orange Pi 5 Pro.
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

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.

@github-actions github-actions Bot added 05 Milestone: Second quarter release size/large PR with 250 lines or more Needs review Seeking for review labels Mar 26, 2026
@c127dev c127dev requested a review from vidplace7 as a code owner March 26, 2026 19:12
Copy link
Copy Markdown
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.

🧹 Nitpick comments (1)
config/boards/orangepi5pro.csc (1)

17-18: Consider removing stale commented freeze override once finalized.

The commented KERNEL_UPGRADE_FREEZE line can become misleading over time; dropping it keeps board config intent clearer.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@config/boards/orangepi5pro.csc` around lines 17 - 18, Remove the stale
commented configuration line for KERNEL_UPGRADE_FREEZE (the "#
KERNEL_UPGRADE_FREEZE=\"vendor-rk35xx@24.8.1\"" entry) from the board config so
the intent is not misleading; if you need to preserve the value for history,
move it to a changelog or commit message instead of leaving it commented in the
file.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@config/boards/orangepi5pro.csc`:
- Around line 17-18: Remove the stale commented configuration line for
KERNEL_UPGRADE_FREEZE (the "# KERNEL_UPGRADE_FREEZE=\"vendor-rk35xx@24.8.1\""
entry) from the board config so the intent is not misleading; if you need to
preserve the value for history, move it to a changelog or commit message instead
of leaving it commented in the file.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c1e6ec24-0b9b-4824-abbe-22e1db47f73f

📥 Commits

Reviewing files that changed from the base of the PR and between b51df54 and 1b06a35.

📒 Files selected for processing (2)
  • config/boards/orangepi5pro.csc
  • config/kernel/linux-rockchip-rk3588-edge.config

Comment thread patch/kernel/archive/rockchip64-7.0/dt/rk3588s-orangepi-5-pro.dts
Comment thread config/boards/orangepi5pro.csc Outdated
Comment thread config/boards/orangepi5pro.csc
…rs, add test targets)

Signed-off-by: c127dev <contact@c127.dev>
@EvilOlaf
Copy link
Copy Markdown
Member

I wonder if the motorcomm driver can be added as module rather than forcing it into the kernel?

Signed-off-by: c127dev <contact@c127.dev>
@c127dev
Copy link
Copy Markdown
Contributor Author

c127dev commented Mar 27, 2026

I wonder if the motorcomm driver can be added as module rather than forcing it into the kernel?

Hi EvilOlaf, you are right.

Initially I've set it to built-in thinking about network availability inside initramfs for recovery scenarios. However, I forgot realizing the config applies to the entire rk3588 family, forcing it to =y just bloats the kernel memory footprint for other boards.

@github-actions github-actions Bot added the Ready to merge Reviewed, tested and ready for merge label Mar 27, 2026
@github-actions
Copy link
Copy Markdown
Contributor

✅ This PR has been reviewed and approved — all set for merge!

@github-actions github-actions Bot removed the Needs review Seeking for review label Mar 27, 2026
@igorpecovnik igorpecovnik merged commit fad1a4f into armbian:main Mar 27, 2026
1 check passed
@eebssk1
Copy link
Copy Markdown
Collaborator

eebssk1 commented Apr 8, 2026

@c127dev
My nvme disk does not get detected after boot.
Hower force a pci rescan via sysfs allow it to appear and work normally.

&pcie2x1l1 {
pinctrl-names = "default";
pinctrl-0 = <&pcie30x1m1_1_clkreqn &pcie30x1m1_1_waken>;
reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
supports-clkreq;
status = "okay";
};

Possibly caused by this? I see top is pcie2 but internal is pcie3.

@eebssk1
Copy link
Copy Markdown
Collaborator

eebssk1 commented Apr 8, 2026

Log after rescan:


[  111.016192] [   T1371] pcieport 0003:30:00.0: bridge configuration invalid ([bus 00-31]), reconfiguring
[  111.016397] [   T1371] pci 0003:31:00.0: [15b7:5003] type 00 class 0x010802 PCIe Endpoint
[  111.016665] [   T1371] pci 0003:31:00.0: BAR 0 [mem 0x00000000-0x00003fff 64bit]
[  111.017720] [   T1371] pci 0003:31:00.0: 2.000 Gb/s available PCIe bandwidth, limited by 2.5 GT/s PCIe x1 link at 0003:30:00.0 (capable of 15.752 Gb/s with 8.0 GT/s PCIe x2 link)
[  111.021573] [   T1371] pci 0003:31:00.0: Adding to iommu group 0
[  111.025853] [   T1371] pci 0003:31:00.0: ASPM: default states L1
[  111.025912] [   T1371] pci_bus 0003:31: busn_res: [bus 31] end is updated to 31
[  111.025947] [   T1371] pcieport 0003:30:00.0: bridge window [mem 0xf3300000-0xf33fffff]: assigned
[  111.025966] [   T1371] pci 0003:31:00.0: BAR 0 [mem 0xf3300000-0xf3303fff 64bit]: assigned
[  111.032649] [     T69] nvme nvme0: pci function 0003:31:00.0
[  111.032736] [     T69] nvme 0003:31:00.0: enabling device (0000 -> 0002)
[  111.092296] [     T69] nvme nvme0: failed to set APST feature (8196)
[  111.093719] [     T69] hwmon hwmon8: temp1_input not attached to any thermal zone
[  111.099254] [     T69] nvme nvme0: 8/0/0 default/read/poll queues
[  111.104971] [     T70]  nvme0n1:

@c127dev
Copy link
Copy Markdown
Contributor Author

c127dev commented Apr 8, 2026

Hi @eebssk1,

Thanks for the feedback! It's interesting that it requires a manual rescan to appear. This often points to timing issues during the initial PCIe link training or a conflict with the CLKREQ signal management.

I've refactored the node to a more "failsafe" configuration by removing the pinctrl and the supports-clkreq property, which some NVMe drives struggle with during early boot. On my unit (using a WD Blue SN550), both versions work, but the simplified one should be more universal.

/* Enable NVMe */
&pcie2x1l1 {
	reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
	status = "okay";
};

Also, could you please provide:

  • Your linux version uname -r
  • The specific model of your NVMe drive.
  • Your u-boot version

I can provide a testing .deb or a pre-compiled dtb if you prefer, but if you can patch and recompile the DTS locally, it would be great to confirm if this simplified node solves the detection issue.

If this fixes it for you, I'll submit a new PR with these stability improvements.

@eebssk1
Copy link
Copy Markdown
Collaborator

eebssk1 commented Apr 9, 2026

Hi @eebssk1,

Thanks for the feedback! It's interesting that it requires a manual rescan to appear. This often points to timing issues during the initial PCIe link training or a conflict with the CLKREQ signal management.

I've refactored the node to a more "failsafe" configuration by removing the pinctrl and the supports-clkreq property, which some NVMe drives struggle with during early boot. On my unit (using a WD Blue SN550), both versions work, but the simplified one should be more universal.

/* Enable NVMe */
&pcie2x1l1 {
	reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
	status = "okay";
};

Also, could you please provide:

* Your linux version `uname -r`

* The specific model of your NVMe drive.

* Your u-boot version

I can provide a testing .deb or a pre-compiled dtb if you prefer, but if you can patch and recompile the DTS locally, it would be great to confirm if this simplified node solves the detection issue.

If this fixes it for you, I'll submit a new PR with these stability improvements.

Thanks for the fix. I'm currently using a rescan script in initramfs early so disk can be used in real system.
I'll test yours.

armbian trunk
7.0.0-rc6-edge-rockchip64
0003:31:00.0 Non-Volatile memory controller: Sandisk Corp WD Blue SN500 / PC SN520 x2 M.2 2280 NVMe SSD (rev 01)
v2025.10 orangepi-patch

@eebssk1
Copy link
Copy Markdown
Collaborator

eebssk1 commented Apr 9, 2026

Hi @eebssk1,

Thanks for the feedback! It's interesting that it requires a manual rescan to appear. This often points to timing issues during the initial PCIe link training or a conflict with the CLKREQ signal management.

I've refactored the node to a more "failsafe" configuration by removing the pinctrl and the supports-clkreq property, which some NVMe drives struggle with during early boot. On my unit (using a WD Blue SN550), both versions work, but the simplified one should be more universal.

/* Enable NVMe */
&pcie2x1l1 {
	reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
	status = "okay";
};

Also, could you please provide:

* Your linux version `uname -r`

* The specific model of your NVMe drive.

* Your u-boot version

I can provide a testing .deb or a pre-compiled dtb if you prefer, but if you can patch and recompile the DTS locally, it would be great to confirm if this simplified node solves the detection issue.

If this fixes it for you, I'll submit a new PR with these stability improvements.

Unfortunately,this fix does not work.

@c127dev
Copy link
Copy Markdown
Contributor Author

c127dev commented Apr 9, 2026

Hmmm... I've been analyzing the Orange Pi 5 Pro schems and comparing them with the recent upstream patch for this board submitted to the mainline kernel just a few days ago.

So looking at the M.2 slot schematic, power pins (2, 4, 70, 72, 74) are directly tied to the VCC_3V3_S3 rail without a dedicated load switch. Because of this, the NVMe gets powered as soon as the system rail comes up.

However, i suspect that some drives often require strict PCIe specification delays (100ms wait after power stable before releasing PERST#) to initialize properly. If don't gets declared the power supply in the DTS, the Linux PCIe core might rush the Link Training, missing the drive while it's still booting its internal controller.

Let's align exactly with the mainline implementation. By adding vpcie3v3-supply, so its triggers the Linux PCIe core to apply proper specification-compliant delays automatically during the software state machine initialization.

Could you please test this block?

/* Enable NVMe */
&pcie2x1l1 {
	reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
	vpcie3v3-supply = <&vcc_3v3_s3>;
	status = "okay";
};

If it stills failling, probably adding this fixes the issue:

&vpcie3v3-supply {
	startup-delay-us = <100000>;
};

This configuration theoretically forces the kernel to respect the regulator timing, giving the drive the milliseconds it needs before the bus enumeration. Let me know how it goes.

@eebssk1
Copy link
Copy Markdown
Collaborator

eebssk1 commented Apr 9, 2026

Hmmm... I've been analyzing the Orange Pi 5 Pro schems and comparing them with the recent upstream patch for this board submitted to the mainline kernel just a few days ago.

So looking at the M.2 slot schematic, power pins (2, 4, 70, 72, 74) are directly tied to the VCC_3V3_S3 rail without a dedicated load switch. Because of this, the NVMe gets powered as soon as the system rail comes up.

However, i suspect that some drives often require strict PCIe specification delays (100ms wait after power stable before releasing PERST#) to initialize properly. If don't gets declared the power supply in the DTS, the Linux PCIe core might rush the Link Training, missing the drive while it's still booting its internal controller.

Let's align exactly with the mainline implementation. By adding vpcie3v3-supply, so its triggers the Linux PCIe core to apply proper specification-compliant delays automatically during the software state machine initialization.

Could you please test this block?

/* Enable NVMe */
&pcie2x1l1 {
	reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
	vpcie3v3-supply = <&vcc_3v3_s3>;
	status = "okay";
};

If it stills failling, probably adding this fixes the issue:

&vpcie3v3-supply {
	startup-delay-us = <100000>;
};

This configuration theoretically forces the kernel to respect the regulator timing, giving the drive the milliseconds it needs before the bus enumeration. Let me know how it goes.

is this correct, because your second block does not compile so I changed a little.

点击展开/Click to show
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)

/dts-v1/;

#include "rk3588s-orangepi-5.dtsi"

/ {
        model = "Xunlong Orange Pi 5 Pro";
        compatible = "xunlong,orangepi-5-pro", "rockchip,rk3588s";

        aliases {
                /delete-property/ ethernet0;
                mmc0 = &sdhci;
                mmc1 = &sdmmc;
                mmc2 = &sdio;
        };

        /*
         * Pro uses GPIO4_PB5 for headphone mute, but the base OPi5 DTSI
         * uses it for vcc_3v3_sd_s0. Delete the base regulator to avoid -EBUSY.
         */
        /delete-node/ regulator-vcc-3v3-sd-s0;

        /*
         * Headphone amplifier (not really an amplifier)
         * It uses MOSFETs to switch the audio signal
         * for Power Saving.
         */
        headphone_amp: headphone-amp {
                compatible = "simple-audio-amplifier";
                enable-gpios = <&gpio4 RK_PB5 GPIO_ACTIVE_HIGH>;
                pinctrl-names = "default";
                pinctrl-0 = <&headphone_amp_en>;
                sound-name-prefix = "Headphones Amp";
        };

        /* Pro uses PWM for LEDs instead of GPIO */
        /delete-node/ pwm-leds;

        pwm-leds {
                compatible = "pwm-leds";

                led-0 {
                        color = <LED_COLOR_ID_BLUE>;
                        function = LED_FUNCTION_STATUS;
                        linux,default-trigger = "heartbeat";
                        max-brightness = <255>;
                        pwms = <&pwm15 0 1000000 0>;
                };

                led-1 {
                        color = <LED_COLOR_ID_GREEN>;
                        function = LED_FUNCTION_ACTIVITY;
                        linux,default-trigger = "heartbeat";
                        max-brightness = <255>;
                        pwms = <&pwm3 0 1000000 0>;
                };
        };

        /*
         * Pro uses i2s2 (i2s2m1 mux) for audio, not i2s1. Recreate the sound
         * card node pointing at i2s2_2ch instead.
         */
        /delete-node/ analog-sound;

        /*
         * Pro version works when CPU gives the MCLK to the codec
         * instead of the codec generating it itself.
         * SDO uses MOSFETs to switch the audio signal for power saving.
         * SDI needs Mic BIAS enabled to work.
         */
        analog-sound {
                compatible = "simple-audio-card";
                pinctrl-names = "default";
                pinctrl-0 = <&hp_detect>;
                simple-audio-card,name = "rockchip,es8388";
                simple-audio-card,bitclock-master = <&masterdai>;
                simple-audio-card,format = "i2s";
                simple-audio-card,frame-master = <&masterdai>;
                simple-audio-card,hp-det-gpios = <&gpio1 RK_PD5 GPIO_ACTIVE_HIGH>;
                simple-audio-card,mclk-fs = <256>;
                simple-audio-card,aux-devs = <&headphone_amp>;
                simple-audio-card,routing =
                        "Headphones", "Headphones Amp OUTL",
                        "Headphones", "Headphones Amp OUTR",
                        "Headphones Amp INL", "LOUT1",
                        "Headphones Amp INR", "ROUT1",
                        "LINPUT1", "Microphone Jack",
                        "RINPUT1", "Microphone Jack",
                        "Microphone Jack", "Mic Bias",
                        "LINPUT2", "Onboard Microphone",
                        "RINPUT2", "Onboard Microphone",
                        "Onboard Microphone", "Mic Bias";
                simple-audio-card,widgets =
                        "Microphone", "Microphone Jack",
                        "Microphone", "Onboard Microphone",
                        "Headphone", "Headphones";

                /* CPU is the master */
                masterdai: simple-audio-card,cpu {
                        sound-dai = <&i2s2_2ch>;
                };

                simple-audio-card,codec {
                        sound-dai = <&es8388>;
                };
        };

        /*
         * Fan is controlled by PWM and turns on a MOSFET (Q2) to power the fan.
         * Recommended using a very low PWM frequency (50 Hz / 20,000,000 ns period).
         * EXPLANATION: The hardware has an aggressive RC low-pass filter (10K / 100nF)
         * at the MOSFET gate with a time constant of 1ms. If standard high-frequency PWM
         * (25kHz) is used, the gate capacitor will integrate the signal as a DC Voltage,
         * forcing the SOT-23 MOSFET into its linear (ohmic) region, causing
         * massive thermal dissipation and eventually burning out the component.
         * A 20ms period allows enough time for the gate to fully charge and discharge.
         */
        fan: pwm-fan {
                compatible = "pwm-fan";
                #cooling-cells = <2>;
                /* Extend SBC capacitors and CPU lifetime */
                cooling-levels = <150 173 192 223 255>;
                fan-supply = <&vcc5v0_sys>;
                pwms = <&pwm2 0 9615385 0>;
        };

        /* PCIe 2.0 Regulator for MT YT6801 (PCIE-to-Ethernet) */
        vcc3v3_phy1: regulator-vcc3v3-phy1 {
                compatible = "regulator-fixed";
                enable-active-high;
                /* Prevent PCIe PHY getting STUCK */
                startup-delay-us = <50000>;
                regulator-always-on;
                regulator-boot-on;
                gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_HIGH>;
                pinctrl-names = "default";
                pinctrl-0 = <&vcc3v3_phy1_en>;
                regulator-max-microvolt = <3300000>;
                regulator-min-microvolt = <3300000>;
                regulator-name = "vcc3v3_phy1";
                vin-supply = <&vcc_3v3_s3>;
        };

        /* Regulator for USB Type-C Port */
        vcc5v0_otg: regulator-vcc5v0-otg {
                compatible = "regulator-fixed";
                enable-active-high;
                gpios = <&gpio0 RK_PC4 GPIO_ACTIVE_HIGH>;
                pinctrl-names = "default";
                pinctrl-0 = <&vcc5v0_otg_en>;
                regulator-always-on;
                regulator-boot-on;
                regulator-max-microvolt = <5000000>;
                regulator-min-microvolt = <5000000>;
                regulator-name = "vcc5v0_otg";
                vin-supply = <&vcc5v0_sys>;
        };

        /* Regulator for LT8711UXD_U2 (DP-to-HDMI) */
        vcc3v3_dp0: regulator-vcc3v3-dp0 {
                compatible = "regulator-fixed";
                enable-active-high;
                gpios = <&gpio3 RK_PC2 GPIO_ACTIVE_HIGH>;
                pinctrl-names = "default";
                pinctrl-0 = <&dp0_en>;
                regulator-always-on;
                regulator-boot-on;
                regulator-min-microvolt = <3300000>;
                regulator-max-microvolt = <3300000>;
                regulator-name = "vcc3v3_dp0";
                vin-supply = <&vcc_3v3_s3>;
        };

        /* Power Sequence for SDIO (WiFi/Bluetooth Card) */
        sdio_pwrseq: sdio-pwrseq {
                compatible = "mmc-pwrseq-simple";
                clocks = <&hym8563>;
                clock-names = "ext_clock";
                post-power-on-delay-ms = <200>;
                reset-gpios = <&gpio0 RK_PD0 GPIO_ACTIVE_LOW>;
        };

        /* Experimental: DisplayPort 1.4 to HDMI 2.0 */
        dp0-con {
                compatible = "dp-connector";
                type = "full-size";
                pinctrl-names = "default";
                pinctrl-0 = <&dp0_hpd>;
                hpd-gpios = <&gpio4 RK_PB4 GPIO_ACTIVE_LOW>;

                port {
                        dp_con_in: endpoint {
                                remote-endpoint = <&dp0_out_con>;
                        };
                };
        };
};

/* Disable gmac1 as the pro has a PCIe attached NIC */
&gmac1 {
        status = "disabled";
};

/* 40-pin header pins 3/5 */
&i2c1 {
        pinctrl-names = "default";
        pinctrl-0 = <&i2c1m4_xfer>;
        status = "okay";
};

/*
 * Pro routes audio codec via i2c3 (not i2c6) and i2s2m1 (not i2s1m0).
 * Delete the inherited es8388 node from i2c6 and redeclare it here.
 */
/delete-node/ &es8388;

/*
 * Audio Codec ES8388
 * It uses custom "everest,mic-lrck-same" to set ADC LRCK as 1 by default
 * Allowing Microphone to work and avoid using "DAC LRCK" as it causes
 * the codec to never start Microphone clock.
 */
&i2c3 {
        pinctrl-names = "default";
        pinctrl-0 = <&i2c3m0_xfer>;
        status = "okay";

        es8388: audio-codec@11 {
                compatible = "everest,es8388", "everest,es8328";
                reg = <0x11>;
                clocks = <&cru I2S2_2CH_MCLKOUT>;
                clock-names = "mclk";
                AVDD-supply = <&vcc_3v3_s0>;
                DVDD-supply = <&vcc_1v8_s0>;
                HPVDD-supply = <&vcc_3v3_s0>;
                PVDD-supply = <&vcc_1v8_s0>;
                assigned-clocks = <&cru I2S2_2CH_MCLKOUT>;
                assigned-clock-rates = <12288000>;
                #sound-dai-cells = <0>;
                everest,mic-lrck-same;
        };
};

/* 40-pin header pins 27/28 */
&i2c4 {
        pinctrl-names = "default";
        pinctrl-0 = <&i2c4m3_xfer>;
        status = "okay";
};

/*
 * i2s1_8ch uses i2s1m0 which occupies GPIO4_PA0 (CLKREQ#) and GPIO4_PA1
 * (WAKE#) needed for the NVMe M.2 slot. Disable it; audio is on i2s2_2ch.
 */
&i2s1_8ch {
        status = "disabled";
};

/* Audio codec on i2s2, m1 mux; add mclk pin to the base pinctrl */
&i2s2_2ch {
        pinctrl-names = "default";
        pinctrl-0 = <&i2s2m1_sclk
                                                         &i2s2m1_mclk
                                                         &i2s2m1_lrck
                                                         &i2s2m1_sdi
                                                         &i2s2m1_sdo>;
        #sound-dai-cells = <0>;
        status = "okay";
};

&package_thermal {
        polling-delay = <1000>;

        cooling-maps {
                map0 {
                        trip = <&package_fan0>;
                        cooling-device = <&fan THERMAL_NO_LIMIT 1>;
                };

                map1 {
                        trip = <&package_fan1>;
                        cooling-device = <&fan 2 THERMAL_NO_LIMIT>;
                };
        };

        trips {
                package_fan0: package-fan0 {
                        hysteresis = <2000>;
                        temperature = <55000>;
                        type = "active";
                };

                package_fan1: package-fan1 {
                        hysteresis = <2000>;
                        temperature = <65000>;
                        type = "active";
                };
        };
};

/* Enable NVMe */
&pcie2x1l1 {
        pinctrl-names = "default";
        pinctrl-0 = <&pcie30x1m1_1_clkreqn &pcie30x1m1_1_waken>;
        reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
        supports-clkreq;
        vpcie3v3-supply = <&vcc_3v3_s3>;
        status = "okay";
};

/* Enable NIC */
&pcie2x1l2 {
        reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
        vpcie3v3-supply = <&vcc3v3_phy1>;
        status = "okay";
};

&vcc_3v3_s3 {
        startup-delay-us = <100000>;
};

&pinctrl {
        bluetooth {
                bt_wake_gpio: bt-wake-pin {
                        rockchip,pins = <0 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
                };

                bt_wake_host_irq: bt-wake-host-irq {
                        rockchip,pins = <0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_down>;
                };
        };

        sound {
                headphone_amp_en: headphone-amp-en {
                        rockchip,pins = <4 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
                };
        };

        usb {
                vcc5v0_otg_en: vcc5v0-otg-en {
                        rockchip,pins = <0 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
                };
        };

        wlan {
                wifi_host_wake_irq: wifi-host-wake-irq {
                        rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_down>;
                };
        };

        ethernet {
                vcc3v3_phy1_en: vcc3v3-phy1-en {
                        rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
                };
                pcie2x1l2_rstn: pcie2x1l2-rstn {
                        rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>;
                };
        };

        dp {
                dp0_en: dp0-en {
                        rockchip,pins = <3 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
                };

                dp0_hpd: dp0-hpd {
                        rockchip,pins = <4 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>;
                };
        };
};

/* pwm0 pin conflicts with i2c4 pin 27 Pro */
&pwm0 {
        status = "disabled";
};

/* Enable PWM for fan */
&pwm2 {
        pinctrl-names = "default";
        pinctrl-0 = <&pwm2m1_pins>;
        status = "okay";
};

/* Enable: PWM GREEN LED */
&pwm3 {
        pinctrl-names = "default";
        pinctrl-0 = <&pwm3m2_pins>;
        status = "okay";
};

/* Enable: PWM BLUE LED */
&pwm15 {
        pinctrl-names = "default";
        pinctrl-0 = <&pwm15m2_pins>;
        status = "okay";
};

&sdhci {
        status = "okay";
};

&sdmmc {
        /delete-property/ vmmc-supply;
};

/* Disable SPI Flash — pins muxed with eMMC */
&sfc {
        status = "disabled";
};

/* Enable SDIO for WiFi/Bluetooth Card */
&sdio {
        #address-cells = <1>;
        #size-cells = <0>;
        bus-width = <4>;
        cap-sd-highspeed;
        cap-sdio-irq;
        keep-power-in-suspend;
        max-frequency = <150000000>;
        mmc-pwrseq = <&sdio_pwrseq>;
        no-mmc;
        no-sd;
        non-removable;
        sd-uhs-sdr104;
        status = "okay";

        ap6256: wifi@1 {
                compatible = "brcm,bcm43456-fmac", "brcm,bcm4329-fmac";
                reg = <1>;
                interrupt-names = "host-wake";
                interrupt-parent = <&gpio0>;
                interrupts = <RK_PA0 IRQ_TYPE_LEVEL_HIGH>;
                pinctrl-names = "default";
                pinctrl-0 = <&wifi_host_wake_irq>;
        };
};

/* Enable UART for Bluetooth */
&uart9 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart9m2_xfer &uart9m2_ctsn &uart9m2_rtsn>;
        uart-has-rtscts;
        status = "okay";

        bluetooth {
                compatible = "brcm,bcm4345c5";
                clocks = <&hym8563>;
                clock-names = "lpo";
                device-wakeup-gpios = <&gpio0 RK_PC6 GPIO_ACTIVE_HIGH>;
                interrupt-names = "host-wakeup";
                interrupt-parent = <&gpio0>;
                interrupts = <RK_PC5 IRQ_TYPE_LEVEL_HIGH>;
                max-speed = <1500000>;
                pinctrl-names = "default";
                pinctrl-0 = <&bt_wake_host_irq &bt_wake_gpio>;
                shutdown-gpios = <&gpio0 RK_PD5 GPIO_ACTIVE_HIGH>;
                vbat-supply = <&vcc_3v3_s3>;
                vddio-supply = <&vcc_1v8_s3>;
        };
};

/* USB2 OTG PHY for usb_host0_xhci; phy-supply enables VBUS to USB3 Type-A port */
&u2phy0_otg {
        phy-supply = <&vcc5v0_otg>;
};

/* Pro has no FUSB302; the USB-C port is power delivery only */
/delete-node/ &usbc0;

/*
 * The Pro's USB-C port is power delivery only: no FUSB302, no data lines,
 * no alt-mode switching. The parent DTSI enables usbdp_phy0 (status = "okay")
 * and adds FUSB302 alt-mode/orientation properties; delete those here.
 *
 * dp-lane-mux = <0 1>: PHY lanes 0/1 are DP (physically routed to the
 * LT8711UXD DP→HDMI2 bridge), lanes 2/3 are USB3 SuperSpeed (physically
 * routed to the USB3 Type-A port P3). Without this property the driver
 * defaults to USB-only mode and places USB3 on lanes 0/1, which do not
 * reach the Type-A connector and makes the USB3 port non-functional.
 */
&usbdp_phy0 {
        rockchip,dp-lane-mux = <0 1>;
        /delete-property/ mode-switch;
        /delete-property/ orientation-switch;
        /delete-property/ sbu1-dc-gpios;
        /delete-property/ sbu2-dc-gpios;
        /delete-node/ port;
};

/* USB3 Type-A port*/
&usb_host0_xhci {
        dr_mode = "host";
        /delete-property/ usb-role-switch;
        status = "okay";
        /delete-node/ port;
};

/*
 * combphy2_psu is shared between usb_host2_xhci (USB3) and pcie2x1l1 (PCIe).
 * Disable USB3 so the PHY can be used for the NVMe M.2 slot.
 */
&usb_host2_xhci {
        status = "disabled";
};

/* Experimental: Enable DisplayPort 1.4 to HDMI 2.0 */
&dp0 {
        status = "okay";
};

&dp0_in {
        dp0_in_vp2: endpoint {
                remote-endpoint = <&vp2_out_dp0>;
        };
};

&dp0_out {
        dp0_out_con: endpoint {
                remote-endpoint = <&dp_con_in>;
        };
};

&vp2 {
        vp2_out_dp0: endpoint@a {
                reg = <ROCKCHIP_VOP2_EP_DP0>;
                remote-endpoint = <&dp0_in_vp2>;
        };
};
Unfortunately,this does not work either. Update: removed clkreq,no change.

@c127dev
Copy link
Copy Markdown
Contributor Author

c127dev commented Apr 9, 2026

Oops, I had a clipboard error in my previous snippet regarding the vpcie3v3-supply reference. Just to be sure we test a completely clean state without any conflicting pinctrl states, the correct minimal block would look like this:

/* Enable NVMe */
&pcie2x1l1 {
	reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
	vpcie3v3-supply = <&vcc_3v3_s3>;
	status = "okay";
};

&vcc_3v3_s3 {
	startup-delay-us = <100000>;
};

If this still doesn't work, we need to determine if this is a regression or an underlying driver/hardware quirk. Could you try testing with the original DTS (before these commits) to see if the drive behaves the same way?

If it also fails on the old DTS, then I strongly suspect the issue goes deeper than the Device Tree.
Let me know if the clean snippet above helps, or if the original DTS exhibits the same behavior!

@eebssk1
Copy link
Copy Markdown
Collaborator

eebssk1 commented Apr 9, 2026

Oops, I had a clipboard error in my previous snippet regarding the vpcie3v3-supply reference. Just to be sure we test a completely clean state without any conflicting pinctrl states, the correct minimal block would look like this:

/* Enable NVMe */
&pcie2x1l1 {
	reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
	vpcie3v3-supply = <&vcc_3v3_s3>;
	status = "okay";
};

&vcc_3v3_s3 {
	startup-delay-us = <100000>;
};

If this still doesn't work, we need to determine if this is a regression or an underlying driver/hardware quirk. Could you try testing with the original DTS (before these commits) to see if the drive behaves the same way?

If it also fails on the old DTS, then I strongly suspect the issue goes deeper than the Device Tree. Let me know if the clean snippet above helps, or if the original DTS exhibits the same behavior!

the minimal does not work too.
So I tried orange official Orangepi5pro_1.0.4_debian_bookworm_server_linux6.1.43 because couldn't find the older armbian image.Suprisingly the official image does detected the nvme driver corretly.

@c127dev
Copy link
Copy Markdown
Contributor Author

c127dev commented Apr 9, 2026

Hmmm...

I went back to the schematics, and I have a suspicion about what is causing this.

Looking at the RK3588 block diagram, the M.2 slot (PCIe20x1_1) shares a hardware Combo PHY (PCIE20/SATA30/USB30 HOST Mux2) with the USB 3.0 and SATA controllers.
Recently, I made several changes to the DTS to enable DisplayPort alt-mode and proper USB 3.0 routing so I suspect that these changes may be the problem.

To prove the theory, could you please try testing with this older DTS (from before the USB/DP refactoring)?
rk3588s-orangepi-5-pro.dts (from rockchip64-6.16)

If patching the DTS doesn't work, I recommend flashing and booting a very old release I made over a year ago which uses that old tree:
Orange Pi 5 Pro - v0.7 Release

If the old DTS (or the v0.7 release) detects your SN500 correctly without a rescan, then we have found the exact culprit: the USB3/DP combphy conflict. Let me know what you find!

@eebssk1
Copy link
Copy Markdown
Collaborator

eebssk1 commented Apr 9, 2026

Hmmm...

I went back to the schematics, and I have a suspicion about what is causing this.

Looking at the RK3588 block diagram, the M.2 slot (PCIe20x1_1) shares a hardware Combo PHY (PCIE20/SATA30/USB30 HOST Mux2) with the USB 3.0 and SATA controllers. Recently, I made several changes to the DTS to enable DisplayPort alt-mode and proper USB 3.0 routing so I suspect that these changes may be the problem.

To prove the theory, could you please try testing with this older DTS (from before the USB/DP refactoring)? rk3588s-orangepi-5-pro.dts (from rockchip64-6.16)

If patching the DTS doesn't work, I recommend flashing and booting a very old release I made over a year ago which uses that old tree: Orange Pi 5 Pro - v0.7 Release

If the old DTS (or the v0.7 release) detects your SN500 correctly without a rescan, then we have found the exact culprit: the USB3/DP combphy conflict. Let me know what you find!

Tried your image(wow the image really chocked my serial input much),still no luck.
Probably there are some quirks either in the pi pci or sn520,where orangepi have some dirty hacks.

@eebssk1
Copy link
Copy Markdown
Collaborator

eebssk1 commented Apr 9, 2026

@c127dev
It likely a sn520 error.
I replaced it with a 1t chinese nvme ssd and working fine.
Also while sn520 do appear after rescan,all IO are failed.

@c127dev
Copy link
Copy Markdown
Contributor Author

c127dev commented Apr 9, 2026

It likely a sn520 error.
I replaced it with a 1t chinese nvme ssd and working fine.
Also while sn520 do appear after rescan,all IO are failed.

Ah, that completely explains it!

Since the SN520 failed on the old release as well (and is throwing I/O errors even after a rescan), it definitely points to a hardware quirk or a failing controller on that specific drive, rather than a DTS regression.

Thanks for taking the time to test the old image and swapping the drive!

@eebssk1
Copy link
Copy Markdown
Collaborator

eebssk1 commented Apr 9, 2026

It likely a sn520 error.
I replaced it with a 1t chinese nvme ssd and working fine.
Also while sn520 do appear after rescan,all IO are failed.

Ah, that completely explains it!

Since the SN520 failed on the old release as well (and is throwing I/O errors even after a rescan), it definitely points to a hardware quirk or a failing controller on that specific drive, rather than a DTS regression.

Thanks for taking the time to test the old image and swapping the drive!

Thanks for the effort.
Sadly the 1t one is only a temporiry test drive. I have to return that cheap sn520 which is rarely,and buy a much expensive one(Taking consider of 5pro's low pci speed I don't sure if this is profitable).

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, ... Patches Patches related to kernel, U-Boot, ... Ready to merge Reviewed, tested and ready for merge size/large PR with 250 lines or more

Development

Successfully merging this pull request may close these issues.

5 participants