[PATCH v2] arm64: rockchip: Add support for QNAP's ts-433 4bay NAS
Ahmad Fatoum
a.fatoum at pengutronix.de
Tue Jul 22 09:42:39 PDT 2025
Hello Uwe,
On 7/19/25 19:47, Uwe Kleine-König wrote:
> The resulting image boots to a prompt using usb booting or when booting
> from eMMC. Networking and USB are working.
Cool stuff!
My comments below.
> Thanks to the fine rk3568 base support this was an easy journey to
> create a powerful bootloader for my NAS. Thanks!
Glad to hear. :)
> diff --git a/arch/arm/boards/qnap-tsx33/board.c b/arch/arm/boards/qnap-tsx33/board.c
> new file mode 100644
> index 000000000000..2611f7a6a9bf
> --- /dev/null
> +++ b/arch/arm/boards/qnap-tsx33/board.c
> @@ -0,0 +1,73 @@
> +#include <common.h>
> +#include <gpio.h>
> +#include <init.h>
> +#include <mach/rockchip/bbu.h>
> +#include <bootsource.h>
> +#include <environment.h>
> +#include <globalvar.h>
> +#include <magicvar.h>
> +#include <deep-probe.h>
> +
> +static int ts433_usb_device_mode(void)
> +{
> + struct device_node *node;
> +
> + /* &usb_host0_xhci */
> + node = of_find_node_by_path("/usb at fcc00000");
> + if (!node)
> + return -ENODEV;
> +
> + return of_property_write_string(node, "dr_mode", "peripheral");
> +}
> +
> +static int ts433_probe(struct device *dev)
> +{
> + enum bootsource bootsource = bootsource_get();
> + int copy_button_pressed = !gpio_get_value(14);
You need to ensure the GPIO controller is probed before you try to get
the GPIO, e.g. by calling
of_devices_ensure_probed_by_property("gpio-controller");
first.
My preference would be using the input API for this though.
Define a gpio-keys node in the DT, wire the GPIO and then call:
of_devices_ensure_probed_by_compatible("gpio-keys");
input_key_get_status(keys, KEY_COPY);
For an example, see commit e44d472d128d ("ARM: boards: protonic-imx6:
prtvt7: Use the input system for key detection").
> + barebox_set_model("QNAP TS-433");
> + barebox_set_hostname("ts433");
> +
> + if (bootsource == BOOTSOURCE_USB || copy_button_pressed) {
> + /*
> + * Configure the front USB socket to USB device (i.e. like the
> + * ROM when booting from USB. Add gadget support equivalent to
> + * usbgadget -b -A "kernel(kernel)c,initramfs(initramfs)c,dtb(dtb)" -a
> + */
> + ts433_usb_device_mode();
If you set dr_mode = "otg" in the device tree, you can just do
otg.mode=peripheral/host in barebox without having to mess with DT directly.
> + globalvar_add_simple("usbgadget.autostart", "1");
Conceptually, this should be at the end, because it activate the
feature. It doesn't matter here though, I think, because it's only
evaluated later on.
> + globalvar_add_simple("fastboot.bbu", "1");
> + globalvar_add_simple("fastboot.partitions", "kernel(kernel)c,initramfs(initramfs)c,dtb(dtb)c");
> + globalvar_add_simple("usbgadget.acm", "1");
These could have been a built-in init script, but both are fine I guess.
> + /*
> + * exit to a shell, also to give the user the chance to open the
> + * console on USB.
> + */
> + globalvar_add_simple("autoboot", "abort");
You could instead set a higher count down time, so a mistaken press
during startup will eventually boot still. For actual flashing use,
first fastboot command or console input will abort the countdown anyway.
> +
> + /*
> + * Don't use emmc to result in a working state even with a
> + * borked environment.
> + */
> + of_device_disable_path("/chosen/environment-emmc");
You will want to call globalvar_set("env.autoprobe", "0") as well, so
environment isn't autoprobed by Type UUID.
Cheers,
Ahmad
> + }
> +
> + rockchip_bbu_mmc_register("emmc", BBU_HANDLER_FLAG_DEFAULT, "/dev/mmc0");
> +
> + return 0;
> +}
> +
> +static const struct of_device_id ts433_of_match[] = {
> + { .compatible = "qnap,ts433" },
> + { /* Sentinel */},
> +};
> +
> +static struct driver ts433_board_driver = {
> + .name = "board-ts433",
> + .probe = ts433_probe,
> + .of_compatible = ts433_of_match,
> +};
> +coredevice_platform_driver(ts433_board_driver);
> +
> +BAREBOX_DEEP_PROBE_ENABLE(ts433_of_match);
> diff --git a/arch/arm/boards/qnap-tsx33/lowlevel.c b/arch/arm/boards/qnap-tsx33/lowlevel.c
> new file mode 100644
> index 000000000000..f852e8d00a2b
> --- /dev/null
> +++ b/arch/arm/dts/rk3568-qnap-ts433.dts
> @@ -0,0 +1,26 @@
> +// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
> +
> +/dts-v1/;
> +#include <arm64/rockchip/rk3568-qnap-ts433.dts>
> +#include "rk356x.dtsi"
> +
> +/ {
> + chosen: chosen {
> + environment-emmc {
> + compatible = "barebox,environment";
> + device-path = &sdhci, "partname:barebox-environment";
> + };
> + };
If you choose 6C3737F2-07F8-45D1-AD45-15D260AAB24D as GPT partition type
UUID, barebox should automatically choose it as environment partition.
This would allow you to drop this node completely.
> +};
> +
> +&gmac0 {
> + /*
> + * The Linux device tree uses rgmii-id and that also works iff the
> + * matching phy driver (motorcomm) is available. The barebox motorcomm
> + * driver however doesn't support the used phy (Motorcomm YT8521) yet
> + * and so we have to stick to rgmii and explicit delays for now.
> + */
Fair enough.
> + phy-mode = "rgmii";
> + tx_delay = <0x3c>;
> + rx_delay = <0x2f>;
> +};
Cheers,
Ahmad
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
More information about the barebox
mailing list