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@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 |


Reply via email to