Devicetree
 help / color / mirror / Atom feed
* [PATCH] arm64: dts: rockchip: Enable SD UHS-I modes on ROCK Pi 4
@ 2026-11-03  6:12 Igor Velkov via B4 Relay
  2026-11-03  6:45 ` sashiko-bot
  0 siblings, 1 reply; 3+ messages in thread
From: Igor Velkov via B4 Relay @ 2026-11-03  6:12 UTC (permalink / raw)
  To: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: devicetree, linux-arm-kernel, linux-rockchip, linux-kernel,
	Igor Velkov

From: Igor Velkov <iav@iav.lv>

The SD I/O supply vcc_sdio (RK808 LDO4) is pinned at 3.0 V, so the
card stays in high-speed mode at 50 MHz. Let dw_mmc switch it to 1.8 V
and enable SDR12 to SDR104.

The card supply is not switchable, so after a watchdog reset or a
panic the card and vcc_sdio are still at 1.8 V. Linux and U-Boot proper
boot from the card in that state; U-Boot SPL loading from it has to set
the SD I/O domain from vcc_sdio, as it does on NanoPi 4 since U-Boot
commit 210ab4f60df8.

On ROCK Pi 4A with a SanDisk 256 GB U3 card: SDR104 at 148.5 MHz,
direct read 64-67 MB/s instead of 23.5 MB/s.

Signed-off-by: Igor Velkov <iav@iav.lv>
---
Tested on ROCK Pi 4A: v7.3.1 with this change, 3 cold boots in SDR104;
the Armbian 7.3 kernel with the same change through reboot, panic,
watchdog reset, s2idle and hibernate, SDR104 each time. Not tested on
the other boards that include rk3399-rock-pi-4.dtsi (4A+, 4B, 4B+, 4C,
4SE).

With PCIE_ROCKCHIP_HOST=y and an empty PCIe slot, tuning also needs
https://lore.kernel.org/r/20261103-rockchip-pcie-async-v1-1-4dcadb94af64@iav.lv
The SPL side for U-Boot on the SD card:
https://lore.kernel.org/r/20261103-b4-rock-pi-4-spl-iodomain-v1-1-8dfc34a5e2e2@iav.lv
---
 arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
index 52de4a79e2f4..3de1d14529c1 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
@@ -356,7 +356,7 @@ vcc_sdio: LDO_REG4 {
 				regulator-name = "vcc_sdio";
 				regulator-always-on;
 				regulator-boot-on;
-				regulator-min-microvolt = <3000000>;
+				regulator-min-microvolt = <1800000>;
 				regulator-max-microvolt = <3000000>;
 				regulator-state-mem {
 					regulator-on-in-suspend;
@@ -696,6 +696,11 @@ &sdmmc {
 	max-frequency = <150000000>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&sdmmc_clk &sdmmc_cd &sdmmc_cmd &sdmmc_bus4>;
+	sd-uhs-sdr12;
+	sd-uhs-sdr25;
+	sd-uhs-sdr50;
+	sd-uhs-sdr104;
+	vqmmc-supply = <&vcc_sdio>;
 	status = "okay";
 };
 

---
base-commit: 2974b78ee4302390eceb5f5983c00b3d66fc3c78
change-id: 20261103-rockpi4-sd-uhs-5e61c1ecf674

Best regards,
-- 
Igor Velkov <iav@iav.lv>



^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] arm64: dts: rockchip: Enable SD UHS-I modes on ROCK Pi 4
  2026-11-03  6:12 [PATCH] arm64: dts: rockchip: Enable SD UHS-I modes on ROCK Pi 4 Igor Velkov via B4 Relay
@ 2026-11-03  6:45 ` sashiko-bot
  2026-11-03 19:19   ` Igor Velkov
  0 siblings, 1 reply; 3+ messages in thread
From: sashiko-bot @ 2026-11-03  6:45 UTC (permalink / raw)
  To: Igor Velkov; +Cc: devicetree, robh, conor+dt

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] arm64: dts: rockchip: sdmmc 1.8V switch races with rockchip_iodomain_probe()
- [Medium] arm64: dts: rockchip: vcc_sdio 3.0V suspend voltage with 1.8V UHS-I mode
--

commit b8883fc4178b08c2e5a74537faa16281101fdba5
Author: Igor Velkov <iav@iav.lv>

arm64: dts: rockchip: Enable SD UHS-I modes on ROCK Pi 4

This commit lowers the minimum voltage of the vcc_sdio regulator to 1.8 V and
enables UHS-I modes (SDR12 through SDR104) with vqmmc-supply on the sdmmc
controller for ROCK Pi 4 boards.

> diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
> index 52de4a79e2f41..3de1d14529c1a 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
> @@ -356,7 +356,7 @@ vcc_sdio: LDO_REG4 {
>  				regulator-name = "vcc_sdio";
>  				regulator-always-on;
>  				regulator-boot-on;
> -				regulator-min-microvolt = <3000000>;
> +				regulator-min-microvolt = <1800000>;
>  				regulator-max-microvolt = <3000000>;
>  				regulator-state-mem {
>  					regulator-on-in-suspend;

[Severity: Medium]
Just below this in vcc_sdio, regulator-state-mem still configures a 3.0 V
suspend voltage:

arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi:
    vcc_sdio: LDO_REG4 {
        ...
        regulator-state-mem {
            regulator-on-in-suspend;
            regulator-suspend-microvolt = <3000000>;
        };
    };

At regulator registration, set_machine_constraints() ->
suspend_set_initial_state() -> __suspend_set_state() ->
rk808_set_suspend_voltage() programs RK808_LDO4_SLP_VSEL_REG to 3.0 V.

When a UHS-I card is initialized, mmc_sd_init_card() ->
mmc_set_uhs_voltage() -> dw_mci_switch_voltage() ->
mmc_regulator_set_vqmmc() switches vcc_sdio to 1.8 V, and
rockchip_iodomain_notify() -> rockchip_iodomain_write() configures the
RK3399 GRF_IO_VSEL SDMMC0_VDD bit for 1.8 V mode.

During system suspend to RAM (mem), _mmc_sd_suspend() -> mmc_power_off() ->
dw_mci_set_ios() -> mmc_regulator_disable_vqmmc() only drops the enable
reference on the regulator-always-on vcc_sdio regulator without restoring
its voltage to 3.0 V, and the non-switchable SD card supply stays powered
with both the card and GRF_IO_VSEL in 1.8 V mode. When PMIC_SLEEP is
asserted, the RK808 switches LDO_REG4 to RK808_LDO4_SLP_VSEL_REG (3.0 V) in
hardware without notifying rockchip-iodomain:

drivers/soc/rockchip/io-domain.c:rockchip_iodomain_notify()
    /*
     * According to Rockchip it's important to keep the SoC IO domain
     * higher than (or equal to) the external voltage.  That means we need
     * to change it before external voltage changes happen in the case
     * of an increase.

Does leaving regulator-suspend-microvolt at 3.0 V drive 3.0 V onto the
1.8 V-configured SDMMC0_VDD I/O domain and SD bus during mem suspend?

> @@ -696,6 +696,11 @@ &sdmmc {
>  	max-frequency = <150000000>;
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&sdmmc_clk &sdmmc_cd &sdmmc_cmd &sdmmc_bus4>;
> +	sd-uhs-sdr12;
> +	sd-uhs-sdr25;
> +	sd-uhs-sdr50;
> +	sd-uhs-sdr104;
> +	vqmmc-supply = <&vcc_sdio>;

[Severity: Medium]
In arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi, io_domains is a
sibling consumer of vcc_sdio rather than a supplier to sdmmc:

    &io_domains {
        ...
        sdmmc-supply = <&vcc_sdio>;
        status = "okay";
    };

Because drivers/pci/ and drivers/soc/ are linked before drivers/i2c/ in
drivers/Makefile while drivers/mmc/ is linked after drivers/i2c/, when
CONFIG_PCIE_ROCKCHIP_HOST=y both rockchip_pcie_probe() and
rockchip_iodomain_probe() defer on their RK808 regulators before i2c0 probes
and are queued on deferred_probe_pending_list with pcie0 ahead of
io_domains.

Once i2c0 registers the RK808 regulators, dw_mci_rockchip_pltfm_driver
(which uses PROBE_PREFER_ASYNCHRONOUS) finds vcc_sdio ready, probes
immediately without waiting for io_domains, and schedules mmc_rescan().
Meanwhile, deferred_probe_work_func() runs rockchip_pcie_probe() ->
rockchip_pcie_host_init_port() synchronously before
rockchip_iodomain_probe():

drivers/pci/controller/pcie-rockchip-host.c:rockchip_pcie_host_init_port()
    msleep(PCIE_T_PVPERL_MS);
    gpiod_set_value_cansleep(rockchip->perst_gpio, 1);

    msleep(PCIE_RESET_CONFIG_WAIT_MS);

    /* 500ms timeout value should be enough for Gen1/2 training */
    err = readl_poll_timeout(rockchip->apb_base + PCIE_CLIENT_BASIC_STATUS1,
                             status, PCIE_LINK_UP(status), 20,
                             500 * USEC_PER_MSEC);

When the PCIe slot is empty, this blocks the deferred probe workqueue for
roughly 700 ms before rockchip_iodomain_probe() can call
regulator_register_notifier() on vcc_sdio. During that window,
mmc_rescan() -> mmc_sd_init_card() -> mmc_set_uhs_voltage() ->
dw_mci_switch_voltage() -> mmc_regulator_set_vqmmc() switches vcc_sdio to
1.8 V and runs dw_mci_rk3288_execute_tuning() while GRF_IO_VSEL is still at
its 3.3 V default.

Can this cause SDR104 tuning to fail at boot unless rockchip_iodomain_probe()
is guaranteed to register its vcc_sdio notifier before sdmmc switches voltage?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261103-rockpi4-sd-uhs-v1-1-fa394d2046e1@iav.lv?part=1

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] arm64: dts: rockchip: Enable SD UHS-I modes on ROCK Pi 4
  2026-11-03  6:45 ` sashiko-bot
@ 2026-11-03 19:19   ` Igor Velkov
  0 siblings, 0 replies; 3+ messages in thread
From: Igor Velkov @ 2026-11-03 19:19 UTC (permalink / raw)
  To: sashiko-reviews
  Cc: iav, Heiko Stuebner, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, devicetree, linux-arm-kernel, linux-rockchip,
	linux-kernel

The RK808 sleep voltages do not take effect on ROCK Pi 4. Its SLEEP
pin is wired to GPIO1_A5 (AP_PWROFF), and nothing muxes that pin to
AP_PWROFF: the DT has no ap_pwroff pinctrl (NanoPi 4 has one), and
U-Boot passes no suspend GPIOs to TF-A. Read back on a ROCK Pi 4A:
GPIO1_A5 is a GPIO input, low. The vcc_sdio sleep state is also the
same as on rockpro64, roc-pc and other RK3399 boards with SDR104.

The io-domain race is what the PCI patch linked under the commit
message fixes:
https://lore.kernel.org/r/20261103-rockchip-pcie-async-v1-1-4dcadb94af64@iav.lv

Igor

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-11-03 19:20 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-03  6:12 [PATCH] arm64: dts: rockchip: Enable SD UHS-I modes on ROCK Pi 4 Igor Velkov via B4 Relay
2026-11-03  6:45 ` sashiko-bot
2026-11-03 19:19   ` Igor Velkov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox