Hi Torsten,

On 5/28/2026 1:22 PM, Torsten Duwe wrote:
> 
> Devicetree commit a198185b9b5 introduced a new type of clock,
> "gated-fixed-clock", for which Das U-Boot does not have
> a driver yet. The required code is similar to gpio-gate-clock,
> and can be added using little extra text space.
> 
> Use this code e.g. to boot a Rock5 ITX from NVMe
> 
> Signed-off-by: Torsten Duwe <[email protected]>
> ---
> Hi all,
> 
> I have a Rock 5 ITX, too, and got struck by Heiko's change ;)
> Instead of Copy & Waste I merged the required changes into 
> clk-gpio, which results in 121 extra code bytes and a driver
> which accepts a superset of both DT bindings.
> 
>  size clk-gated-fixed.o clk-gpio*.o
>    text          data     bss     dec     hex filename
>     673           120       0     793     319 clk-gated-fixed.o
>     665           120       0     785     311 clk-gpio.o
>     544           120       0     664     298 clk-gpio-orig.o
> 
> All I want to do here is present it as an alternative to Daniele's
> approach[1] and let the maintainers decide how to proceed. This is 
> a "works for me" raw cut, feel free to review if we want to go this
> way.
> 
>       Torsten
> 
> [1] https://lists.denx.de/pipermail/u-boot/2026-May/619110.html
> ---
>  configs/rock-5-itx-rk3588_defconfig |  1 +
>  drivers/clk/clk-gpio.c              | 29 ++++++++++++++++++++++-------
>  2 files changed, 23 insertions(+), 7 deletions(-)
> 
> diff --git a/configs/rock-5-itx-rk3588_defconfig 
> b/configs/rock-5-itx-rk3588_defconfig
> index cb014de4188..adb20c2f3a0 100644
> --- a/configs/rock-5-itx-rk3588_defconfig
> +++ b/configs/rock-5-itx-rk3588_defconfig
> @@ -52,6 +52,7 @@ CONFIG_AHCI=y
>  CONFIG_AHCI_PCI=y
>  CONFIG_DWC_AHCI=y
>  CONFIG_SPL_CLK=y
> +CONFIG_CLK_GPIO=y
>  # CONFIG_USB_FUNCTION_FASTBOOT is not set
>  CONFIG_ROCKCHIP_GPIO=y
>  CONFIG_SYS_I2C_ROCKCHIP=y
> diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c
> index 4ed14306575..b7abc891ed2 100644
> --- a/drivers/clk/clk-gpio.c
> +++ b/drivers/clk/clk-gpio.c
> @@ -6,6 +6,7 @@
>  #include <clk.h>
>  #include <clk-uclass.h>
>  #include <dm.h>
> +#include <power/regulator.h>
>  #include <linux/clk-provider.h>
>  
>  #include <asm/gpio.h>
> @@ -13,14 +14,18 @@
>  struct clk_gpio_priv {
>       struct gpio_desc        enable; /* GPIO, controlling the gate */
>       struct clk              *clk;   /* Gated clock */
> +     struct udevice          *vdd_supply;
>  };
>  
>  static int clk_gpio_enable(struct clk *clk)
>  {
>       struct clk_gpio_priv *priv = dev_get_priv(clk->dev);
>  
> -     clk_enable(priv->clk);
> -     dm_gpio_set_value(&priv->enable, 1);
> +     if (priv->clk)
> +             clk_enable(priv->clk);
> +
> +     if (priv->enable.dev)
> +             dm_gpio_set_value(&priv->enable, 1);
>  
>       return 0;
>  }
> @@ -29,8 +34,11 @@ static int clk_gpio_disable(struct clk *clk)
>  {
>       struct clk_gpio_priv *priv = dev_get_priv(clk->dev);
>  
> -     dm_gpio_set_value(&priv->enable, 0);
> -     clk_disable(priv->clk);
> +     if (priv->enable.dev)
> +             dm_gpio_set_value(&priv->enable, 0);
> +
> +     if (priv->clk)
> +             clk_disable(priv->clk);
>  
>       return 0;
>  }
> @@ -39,7 +47,7 @@ static ulong clk_gpio_get_rate(struct clk *clk)
>  {
>       struct clk_gpio_priv *priv = dev_get_priv(clk->dev);
>  
> -     return clk_get_rate(priv->clk);
> +     return (priv->clk) ? clk_get_rate(priv->clk) : -1;
>  }
>  
>  const struct clk_ops clk_gpio_ops = {
> @@ -57,7 +65,7 @@ static int clk_gpio_probe(struct udevice *dev)
>       if (IS_ERR(priv->clk)) {
>               log_debug("%s: Could not get gated clock: %ld\n",
>                         __func__, PTR_ERR(priv->clk));
> -             return PTR_ERR(priv->clk);
> +             priv->clk = 0;
>       }
>  
>       ret = gpio_request_by_name(dev, "enable-gpios", 0,
> @@ -65,9 +73,15 @@ static int clk_gpio_probe(struct udevice *dev)
>       if (ret) {
>               log_debug("%s: Could not decode enable-gpios (%d)\n",
>                         __func__, ret);
> -             return ret;
>       }
>  
> +     ret = device_get_supply_regulator(dev, "vdd-supply",
> +                                       &priv->vdd_supply);
> +     if (ret == 0)
> +             ret = regulator_set_enable(priv->vdd_supply, true);

You should use regulator_set_enable_if_allowed() and also only enable
and disable the regulator in clk enable and disable ops to keep a
balanced enable ref-count of the regulator.

Regards,
Jonas

> +
> +     log_debug("%s: %s regulator = %d\n", __func__, dev->name, ret);
> +
>       return 0;
>  }
>  
> @@ -80,6 +94,7 @@ static int clk_gpio_probe(struct udevice *dev)
>   */
>  static const struct udevice_id clk_gpio_match[] = {
>       { .compatible = "gpio-gate-clock" },
> +     { .compatible = "gated-fixed-clock" },
>       { /* sentinel */ }
>  };
>  

Reply via email to