OpenWRT support for NanoPi R3S

The NanoPi R3S(as “R3S”) is an open source platform with dual-Gbps Ethernet ports designed and developed by FriendlyElec for IoT applications. The NanoPi R3S uses the RK3566 SoC. It has two Gbps Ethernet ports and 2G LPDDR4X RAM, as well as optional 32GB eMMC. The NanoPi R3S can be optionally equipped with an integrated CNC anodized aluminum case.

UPDATE 10/27/2024: The FriendlyARM/FriendlyELEC NanoPi R3S is now supported in OpenWRT snapshots as well as the upcoming 24.10 release per the following commit: https://github.com/openwrt/openwrt/commit/b5c7c67b8f10203253138ec35bb6aef213faae30

More information regarding installation instructions and specifications can be found on the OpenWRT wiki: https://openwrt.org/toh/friendlyelec/nanopi_r3s

2 Likes

Hi,
I quickly tried your builds.
On the connected laptop i got an ip address 169.xxx, so I couldn't do much more.
I'll spent more time on them in the next days.
Unfortunately i'm not either a developer

My kind regards

The initial build was probably unusable. If you're willing to try the 2024-10-09-2 build please let me know how that goes. My R3S is ordered and should hopefully arrive within a week.

Gave it a try on my device, doesn't install at all on boot.
Installing it as new firmware from within friendlywrt does not work either.

I've been busy but I'm going to try making my own build again in the next few days.

Just realized my latest patchset is missing rk3566-nanopi-r3s-u-boot.dtsi :man_facepalming: Will push a new build asap.

Hi,
no better luck with the 2024-10-11 build.

Regards

Hi write to miscrosd, Nanopi r3s boot not. Red sys.

Thanks for the feedback. Still awaiting on mine to arrive and will attempt to debug once it does.

My specimen arrived and I was able to further debug through UART. Good news, I now have it in a bootable state with the WAN port working. Unfortunately, I can't seem to quite get the LAN port (R8111F) working, and I'm not quite sure if USB works either. Any help with the DTS would be appreciated.

3 Likes

Nice work! I also just got mine and can help, but it doesn't look like your GitHub links are updated.

I can try to resurrect my build system and include your linked patches but if you have a build I can test with, I can try that also.

I've now got both ports working, along with the LEDs. Currently working on USB support. Will post a new build as soon as I get that reasonably working.

1 Like

I posted a new (bootable!) build here: https://github.com/kz26/openwrt/releases/tag/2024-10-18

Unfortunately, I wasn't able to get USB working even though the DTS mappings should be correct. Enabling USB in the build causes a kernel hang on boot. Not sure if it's a upstream kernel issue or not - any help would be appreciated. For now I'm building with CONFIG_USB_SUPPORT disabled in the kernel.

// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
/*
 * Copyright (c) 2022 FriendlyElec Computer Tech. Co., Ltd.
 * (http://www.friendlyelec.com)
 *
 * Copyright (c) 2023 Tianling Shen <cnsztl@gmail.com>
 *
 * Copyright (c) 2024 Kevin Zhang <kevin@kevinzhang.me>
 */

/dts-v1/;
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/leds/common.h>
#include <dt-bindings/pinctrl/rockchip.h>
#include <dt-bindings/soc/rockchip,vop2.h>
#include "rk3566.dtsi"

/ {
	model = "FriendlyElec NanoPi R3S";
	compatible = "friendlyarm,nanopi-r3s", "rockchip,rk3566";

    aliases {
		ethernet0 = &gmac1;
	};

	chosen: chosen {
		stdout-path = "serial2:1500000n8";
	};

	vdd_usbc: vdd-usbc-regulator {
		compatible = "regulator-fixed";
		regulator-name = "vdd_usbc";
		regulator-always-on;
		regulator-boot-on;
		regulator-min-microvolt = <5000000>;
		regulator-max-microvolt = <5000000>;
	};

	vcc3v3_sys: vcc3v3-sys-regulator {
		compatible = "regulator-fixed";
		regulator-name = "vcc3v3_sys";
		regulator-always-on;
		regulator-boot-on;
		regulator-min-microvolt = <3300000>;
		regulator-max-microvolt = <3300000>;
		vin-supply = <&vdd_usbc>;
	};

	vcc5v0_sys: vcc5v0-sys-regulator {
		compatible = "regulator-fixed";
		regulator-name = "vcc5v0_sys";
		regulator-always-on;
		regulator-boot-on;
		regulator-min-microvolt = <5000000>;
		regulator-max-microvolt = <5000000>;
		vin-supply = <&vdd_usbc>;
	};

	vcc3v3_pcie: vcc3v3-pcie-regulator {
		compatible = "regulator-fixed";
		regulator-name = "vcc3v3_pcie";
		regulator-min-microvolt = <3300000>;
		regulator-max-microvolt = <3300000>;
		enable-active-high;
		gpios = <&gpio0 RK_PD4 GPIO_ACTIVE_HIGH>;
		startup-delay-us = <200000>;
		vin-supply = <&vcc5v0_sys>;
	};

	vcc5v0_usb: vcc5v0-usb-regulator {
		compatible = "regulator-fixed";
		regulator-name = "vcc5v0_usb";
		regulator-always-on;
		regulator-boot-on;
		regulator-min-microvolt = <5000000>;
		regulator-max-microvolt = <5000000>;
		vin-supply = <&vdd_usbc>;
	};

	vcc5v0_usb_host: vcc5v0-usb-host-regulator {
		compatible = "regulator-fixed";
		enable-active-high;
		gpio = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
		pinctrl-names = "default";
		pinctrl-0 = <&vcc5v0_usb_host_en>;
		regulator-name = "vcc5v0_usb_host";
		regulator-always-on;
		regulator-boot-on;
		regulator-min-microvolt = <5000000>;
		regulator-max-microvolt = <5000000>;
		vin-supply = <&vcc5v0_usb>;
	};

	vcc5v0_usb_otg: vcc5v0-usb-otg-regulator {
		compatible = "regulator-fixed";
		enable-active-high;
		gpio = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>;
		pinctrl-names = "default";
		pinctrl-0 = <&vcc5v0_usb_otg_en>;
		regulator-name = "vcc5v0_usb_otg";
		regulator-min-microvolt = <5000000>;
		regulator-max-microvolt = <5000000>;
		vin-supply = <&vcc5v0_usb>;
	};

	gpio_keys: gpio-keys {
		compatible = "gpio-keys";
		pinctrl-names = "default";
		pinctrl-0 = <&reset_button_pin>;

		button-reset {
			debounce-interval = <50>;
			gpios = <&gpio0 RK_PC2 GPIO_ACTIVE_LOW>;
			label = "reset";
			linux,code = <KEY_RESTART>;
			wakeup-source;
		};
	};

	gpio_leds: gpio-leds {
		compatible = "gpio-leds";
		pinctrl-names = "default";
		pinctrl-0 = <&lan_led_pin>, <&power_led_pin>, <&wan_led_pin>;

		power_led: led-power {
			color = <LED_COLOR_ID_RED>;
			function = LED_FUNCTION_POWER;
			gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
			linux,default-trigger = "heartbeat";
		};

		led-wan {
			color = <LED_COLOR_ID_GREEN>;
			function = LED_FUNCTION_WAN;
			gpios = <&gpio3 RK_PC3 GPIO_ACTIVE_HIGH>;
		};

		led-lan {
			color = <LED_COLOR_ID_GREEN>;
			function = LED_FUNCTION_LAN;
			gpios = <&gpio3 RK_PC2 GPIO_ACTIVE_HIGH>;
		};
	};
};

&cpu0 {
	cpu-supply = <&vdd_cpu>;
};

&cpu1 {
	cpu-supply = <&vdd_cpu>;
};

&cpu2 {
	cpu-supply = <&vdd_cpu>;
};

&cpu3 {
	cpu-supply = <&vdd_cpu>;
};

&gpu {
	mali-supply = <&vdd_gpu>;
	status = "okay";
};

&hdmi {
	status = "okay";
	rockchip,phy-table =
		<92812500  0x8009 0x0000 0x0270>,
		<165000000 0x800b 0x0000 0x026d>,
		<185625000 0x800b 0x0000 0x01ed>,
		<297000000 0x800b 0x0000 0x01ad>,
		<594000000 0x8029 0x0000 0x0088>,
		<000000000 0x0000 0x0000 0x0000>;
};

&i2c0 {
	status = "okay";

	vdd_cpu: regulator@1c {
		compatible = "tcs,tcs4525";
		reg = <0x1c>;
		fcs,suspend-voltage-selector = <1>;
		regulator-name = "vdd_cpu";
		regulator-always-on;
		regulator-boot-on;
		regulator-min-microvolt = <800000>;
		regulator-max-microvolt = <1150000>;
		regulator-ramp-delay = <2300>;
		vin-supply = <&vcc5v0_sys>;

		regulator-state-mem {
			regulator-off-in-suspend;
		};
	};

	rk809: pmic@20 {
		compatible = "rockchip,rk809";
		reg = <0x20>;
		interrupt-parent = <&gpio0>;
		interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
		#clock-cells = <1>;
		pinctrl-names = "default";
		pinctrl-0 = <&pmic_int>;
		rockchip,system-power-controller;
		vcc1-supply = <&vcc3v3_sys>;
		vcc2-supply = <&vcc3v3_sys>;
		vcc3-supply = <&vcc3v3_sys>;
		vcc4-supply = <&vcc3v3_sys>;
		vcc5-supply = <&vcc3v3_sys>;
		vcc6-supply = <&vcc3v3_sys>;
		vcc7-supply = <&vcc3v3_sys>;
		vcc8-supply = <&vcc3v3_sys>;
		vcc9-supply = <&vcc3v3_sys>;
		wakeup-source;

		regulators {
			vdd_logic: DCDC_REG1 {
				regulator-name = "vdd_logic";
				regulator-always-on;
				regulator-boot-on;
				regulator-initial-mode = <0x2>;
				regulator-min-microvolt = <500000>;
				regulator-max-microvolt = <1350000>;
				regulator-ramp-delay = <6001>;

				regulator-state-mem {
					regulator-off-in-suspend;
				};
			};

			vdd_gpu: DCDC_REG2 {
				regulator-name = "vdd_gpu";
				regulator-always-on;
				regulator-initial-mode = <0x2>;
				regulator-min-microvolt = <500000>;
				regulator-max-microvolt = <1350000>;
				regulator-ramp-delay = <6001>;

				regulator-state-mem {
					regulator-off-in-suspend;
				};
			};

			vcc_ddr: DCDC_REG3 {
				regulator-name = "vcc_ddr";
				regulator-always-on;
				regulator-boot-on;
				regulator-initial-mode = <0x2>;

				regulator-state-mem {
					regulator-on-in-suspend;
				};
			};

			vdd_npu: DCDC_REG4 {
				regulator-name = "vdd_npu";
				regulator-initial-mode = <0x2>;
				regulator-min-microvolt = <500000>;
				regulator-max-microvolt = <1350000>;
				regulator-ramp-delay = <6001>;

				regulator-state-mem {
					regulator-off-in-suspend;
				};
			};

			vcc_1v8: DCDC_REG5 {
				regulator-name = "vcc_1v8";
				regulator-always-on;
				regulator-boot-on;
				regulator-min-microvolt = <1800000>;
				regulator-max-microvolt = <1800000>;

				regulator-state-mem {
					regulator-off-in-suspend;
				};
			};

			vdda0v9_image: LDO_REG1 {
				regulator-name = "vdda0v9_image";
				regulator-min-microvolt = <950000>;
				regulator-max-microvolt = <950000>;

				regulator-state-mem {
					regulator-off-in-suspend;
				};
			};

			vdda_0v9: LDO_REG2 {
				regulator-name = "vdda_0v9";
				regulator-always-on;
				regulator-boot-on;
				regulator-min-microvolt = <900000>;
				regulator-max-microvolt = <900000>;

				regulator-state-mem {
					regulator-off-in-suspend;
				};
			};

			vdda0v9_pmu: LDO_REG3 {
				regulator-name = "vdda0v9_pmu";
				regulator-always-on;
				regulator-boot-on;
				regulator-min-microvolt = <900000>;
				regulator-max-microvolt = <900000>;

				regulator-state-mem {
					regulator-on-in-suspend;
					regulator-suspend-microvolt = <900000>;
				};
			};

			vccio_acodec: LDO_REG4 {
				regulator-name = "vccio_acodec";
				regulator-min-microvolt = <3300000>;
				regulator-max-microvolt = <3300000>;

				regulator-state-mem {
					regulator-off-in-suspend;
				};
			};

			vccio_sd: LDO_REG5 {
				regulator-name = "vccio_sd";
				regulator-min-microvolt = <1800000>;
				regulator-max-microvolt = <3300000>;

				regulator-state-mem {
					regulator-off-in-suspend;
				};
			};

			vcc3v3_pmu: LDO_REG6 {
				regulator-name = "vcc3v3_pmu";
				regulator-always-on;
				regulator-boot-on;
				regulator-min-microvolt = <3300000>;
				regulator-max-microvolt = <3300000>;

				regulator-state-mem {
					regulator-on-in-suspend;
					regulator-suspend-microvolt = <3300000>;
				};
			};

			vcca_1v8: LDO_REG7 {
				regulator-name = "vcca_1v8";
				regulator-always-on;
				regulator-boot-on;
				regulator-min-microvolt = <1800000>;
				regulator-max-microvolt = <1800000>;

				regulator-state-mem {
					regulator-off-in-suspend;
				};
			};

			vcca1v8_pmu: LDO_REG8 {
				regulator-name = "vcca1v8_pmu";
				regulator-always-on;
				regulator-boot-on;
				regulator-min-microvolt = <1800000>;
				regulator-max-microvolt = <1800000>;

				regulator-state-mem {
					regulator-on-in-suspend;
					regulator-suspend-microvolt = <1800000>;
				};
			};

			vcca1v8_image: LDO_REG9 {
				regulator-name = "vcca1v8_image";
				regulator-min-microvolt = <1800000>;
				regulator-max-microvolt = <1800000>;

				regulator-state-mem {
					regulator-off-in-suspend;
				};
			};

			vcc_3v3: SWITCH_REG1 {
				regulator-name = "vcc_3v3";
				regulator-always-on;
				regulator-boot-on;

				regulator-state-mem {
					regulator-off-in-suspend;
				};
			};

			vcc3v3_sd: SWITCH_REG2 {
				regulator-name = "vcc3v3_sd";
				regulator-always-on;
				regulator-boot-on;

				regulator-state-mem {
					regulator-off-in-suspend;
				};
			};
		};

	};
};

&combphy1 {
	status = "okay";
};

&combphy2 {
	status = "okay";
};

&gmac1 {
	phy-mode = "rgmii";
	clock_in_out = "output";

	snps,reset-gpio = <&gpio4 RK_PC2 GPIO_ACTIVE_LOW>;
	snps,reset-active-low;
	/* Reset time is 15ms, 50ms for rtl8211f */
	snps,reset-delays-us = <0 15000 50000>;

	assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>;
	assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>, <&cru CLK_MAC1_2TOP>;
	assigned-clock-rates = <0>, <125000000>;

	pinctrl-names = "default";
	pinctrl-0 = <&gmac1m0_miim
		     &gmac1m0_tx_bus2_level3
		     &gmac1m0_rx_bus2
		     &gmac1m0_rgmii_clk_level2
		     &gmac1m0_rgmii_bus_level3>;

	tx_delay = <0x3c>;
	rx_delay = <0x2f>;

	phy-handle = <&rgmii_phy1>;
	status = "okay";
};

&mdio1 {
	rgmii_phy1: ethernet-phy@1 {
		compatible = "ethernet-phy-ieee802.3-c22";
		reg = <1>;
		pinctrl-0 = <&gmac_int>;
		pinctrl-names = "default";
	};
};

&i2c1 {
	status = "okay";

	hym8563: hym8563@51 {
		compatible = "haoyu,hym8563";
		reg = <0x51>;
		pinctrl-names = "default";
		pinctrl-0 = <&rtc_int>;
		interrupt-parent = <&gpio0>;
		interrupts = <RK_PD3 IRQ_TYPE_LEVEL_LOW>;
		wakeup-source;
	};
};

&pcie2x1 {
	num-lanes = <1>;
	num-viewport = <4>;
	reset-gpios = <&gpio4 RK_PC6 GPIO_ACTIVE_HIGH>;
   vpcie3v3-supply = <&vcc3v3_pcie>;
	status = "okay";
};

&pmu_io_domains {
	status = "okay";
	pmuio1-supply = <&vcc3v3_pmu>;
	pmuio2-supply = <&vcc3v3_pmu>;
	vccio2-supply = <&vcc_1v8>;
	vccio3-supply = <&vccio_sd>;
	vccio4-supply = <&vcc_3v3>;
	vccio5-supply = <&vcc_1v8>;
	vccio6-supply = <&vcc_3v3>;
	vccio7-supply = <&vcc_3v3>;
};

&saradc {
	vref-supply = <&vcca_1v8>;
	status = "okay";
};

&tsadc {
	rockchip,hw-tshut-mode = <1>;
	rockchip,hw-tshut-polarity = <0>;
	status = "okay";
};

&uart2 {
	status = "okay";
};

&sdhci {
	bus-width = <8>;
	max-frequency = <200000000>;
	non-removable;
	pinctrl-names = "default";
	pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd>;
	status = "okay";
};

&sdmmc0 {
	max-frequency = <150000000>;
	no-sdio;
	no-mmc;
	bus-width = <4>;
	cap-mmc-highspeed;
	cap-sd-highspeed;
	disable-wp;
	sd-uhs-sdr104;
	vmmc-supply = <&vcc3v3_sd>;
	vqmmc-supply = <&vccio_sd>;
	pinctrl-names = "default";
	pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
	status = "okay";
};

&usb_host0_ehci {
	status = "okay";
};

&usb_host0_ohci {
	status = "okay";
};

&usb_host1_ehci {
	status = "okay";
};

&usb_host1_ohci {
	status = "okay";
};

&usb_host0_xhci {
	dr_mode = "host";
	status = "okay";
};

&usb_host1_xhci {
	status = "okay";
};

&usb2phy0 {
	status = "okay";
};

&usb2phy0_host {
	phy-supply = <&vcc5v0_usb_host>;
	status = "okay";
};

&usb2phy0_otg {
	status = "okay";
};


&usb2phy1 {
	status = "okay";
};

&usb2phy1_host {
	phy-supply = <&vcc5v0_usb_otg>;
	status = "okay";
};

&usb2phy1_otg {
	phy-supply = <&vcc5v0_usb_otg>;
	status = "okay";
};

&vop {
	assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>;
	assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>;
	status = "okay";
};

&pinctrl {
	hym8563 {
		hym8563_int: hym8563-int {
			rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>;
		};
	};

	pmic {
		pmic_int: pmic-int {
			rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
		};
	};

	usb {
		vcc5v0_usb_host_en: vcc5v0-usb-host-en {
			rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
		};

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

	rtc {
		rtc_int: rtc-int {
			rockchip,pins =
				<0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>;
		};
	};
	
	gpio-key {
		reset_button_pin: reset-button-pin {
			rockchip,pins = <0 RK_PC2 RK_FUNC_GPIO &pcfg_pull_up>;
		};
	};

	gpio-leds {
		power_led_pin: power-led-pin {
			rockchip,pins =
				<0 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
		};

		wan_led_pin: wan-led-pin {
			rockchip,pins =
				<3 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>;
		};

		lan_led_pin: lan-led-pin {
			rockchip,pins =
				<3 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
		};
	};

	gmac {
		gmac_int: gmac-int {
			rockchip,pins =
				<4 RK_PC3 RK_FUNC_GPIO &pcfg_pull_up>;
		};
	};
};

Fixed :smiley: Just had to explicitly disable the &usb2phy1 node as this device only has a single port. New working build has been tested with USB mass storage and is working. Posted to my Github. Will create a PR to the OpenWRT repo soon.

1 Like

Nice job, it boots and works.
More tests tomorrow

Many thanks

1 Like

Hi,
I moved the firmware into the emmc and it worked as expected.
Trying to install packages i got some issue:

  • package for kmod-* found but incompatible with the architecture configured
  • not enough space on the device to install packages like docker.

Let me know if i can help anyway.

My kind regards

What do you mean by "package for kmod-* found but incompatible with the architecture configured"? Since this is a snapshot build, the package manager would not work and you would need to manually recompile a new build locally with the packages you want.

The second issue should be solvable by manually resizing the root partition and is not unique to this device.

solved following instructions here, they work on aarch64 platform as well

ok, i'll do it.
Thank you

Awesome job!

I flashed it to emmc and it's running as expected. I'll keep playing around with it but your efforts are totally appreciated here!

There's crypto acceleration available in this chip and can be accessed in the libwolfsslcpu-crypto package. I was unable to test any of the kernel-level cryptodev modules, but that should be doable once this device is merged into the main builds.

Here's a before-and-after running the benchmark utility:

AES-256-CBC-enc             40 MiB took 1.127 seconds,   35.503 MiB/s
AES-256-CBC-dec             35 MiB took 1.047 seconds,   33.443 MiB/s

And after installing:

AES-256-CBC-enc            825 MiB took 1.004 seconds,  821.777 MiB/s
AES-256-CBC-dec            800 MiB took 1.003 seconds,  797.556 MiB/s

That's a pretty significant improvement over the nanopi neo2 this intends to replace which was scoring around half that (not unexpected since the neo2 is over 7-years-old now). This is for anything using wolfssl, but services using libopenssl should expect similar acceleration once those kernel modules are pulled in.

Some basic throughput testing shows line speeds through the two interfaces with NAT enabled. I'll test some more, but everything seems to be working as we'd want it to!

Great job getting this nifty little device added to the lineup!

Thats weird. You shouldn't need any wolfssl package for that.
What does /proc/cpuinfo show in features for you? I'm running friendlywrt at the moment, but my line is clearly showing aes, sha1, and sha2 in there.