[PATCH v2 4/9] pci: brcmstb: Add RPi5 reset facilities
Peter Robinson
pbrobinson at gmail.com
Wed May 6 12:49:07 CEST 2026
> A driver for Broadcom reset controllers ported from
> linux/drivers/reset/reset-brcmstb.c to U-Boot.
The subject for this is wrong, it's a new reset driver, not part of
the pcie subsystem.
> Signed-off-by: Torsten Duwe <duwe at suse.de>
> Co-authored-by: Oleksii Moisieiev <oleksii_moisieiev at epam.com>
> Tested-by: Pedro Falcato <pfalcato at suse.de>
>
> ---
> configs/rpi_arm64_defconfig | 1 +
> drivers/reset/Kconfig | 7 +++
> drivers/reset/Makefile | 1 +
> drivers/reset/reset-brcmstb.c | 97 +++++++++++++++++++++++++++++++++++
> 4 files changed, 106 insertions(+)
> create mode 100644 drivers/reset/reset-brcmstb.c
>
> diff --git a/configs/rpi_arm64_defconfig b/configs/rpi_arm64_defconfig
> index 69e8e72c5d7..153d7ed301e 100644
> --- a/configs/rpi_arm64_defconfig
> +++ b/configs/rpi_arm64_defconfig
> @@ -44,6 +44,7 @@ CONFIG_BCMGENET=y
> CONFIG_PCI_BRCMSTB=y
> CONFIG_PINCTRL=y
> # CONFIG_PINCTRL_GENERIC is not set
> +CONFIG_RESET_BRCMSTB=y
> CONFIG_DM_RNG=y
> CONFIG_RNG_IPROC200=y
> # CONFIG_REQUIRE_SERIAL_CONSOLE is not set
> diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
> index 66911199c8b..e0561df8058 100644
> --- a/drivers/reset/Kconfig
> +++ b/drivers/reset/Kconfig
> @@ -64,6 +64,13 @@ config RESET_BCM6345
> help
> Support reset controller on BCM6345.
>
> +config RESET_BRCMSTB
> + bool "Generic Reset controller driver for Broadcom"
Should probably have
depends on ARCH_BCM283X
> + help
> + This enables reset controller for Broadcom devices.
> + If you wish to use reset resources managed by the Broadcom
> + Reset Controller, say Y here. Otherwise, say N.
> +
> config RESET_UNIPHIER
> bool "Reset controller driver for UniPhier SoCs"
> depends on ARCH_UNIPHIER
> diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
> index 088545c6473..ad5fe6b6184 100644
> --- a/drivers/reset/Makefile
> +++ b/drivers/reset/Makefile
> @@ -13,6 +13,7 @@ obj-$(CONFIG_RESET_AIROHA) += reset-airoha.o
> obj-$(CONFIG_RESET_TI_SCI) += reset-ti-sci.o
> obj-$(CONFIG_RESET_HSDK) += reset-hsdk.o
> obj-$(CONFIG_RESET_BCM6345) += reset-bcm6345.o
> +obj-$(CONFIG_RESET_BRCMSTB) += reset-brcmstb.o
> obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o
> obj-$(CONFIG_RESET_AST2500) += reset-ast2500.o
> obj-$(CONFIG_RESET_AST2600) += reset-ast2600.o
> diff --git a/drivers/reset/reset-brcmstb.c b/drivers/reset/reset-brcmstb.c
> new file mode 100644
> index 00000000000..7861f7c9baf
> --- /dev/null
> +++ b/drivers/reset/reset-brcmstb.c
> @@ -0,0 +1,97 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Broadcom STB generic reset controller
> + *
> + * Copyright (C) 2024 EPAM Systems
> + *
> + * Moved from linux kernel:
> + * Author: Florian Fainelli <f.fainelli at gmail.com>
> + * Copyright (C) 2018 Broadcom
> + */
> +
> +#include <asm/io.h>
> +#include <dm.h>
> +#include <errno.h>
> +#include <linux/bitops.h>
> +#include <linux/delay.h>
> +#include <log.h>
> +#include <malloc.h>
> +#include <reset-uclass.h>
> +
> +struct brcmstb_reset {
> + void __iomem *base;
> +};
> +
> +#define SW_INIT_SET 0x00
> +#define SW_INIT_CLEAR 0x04
> +#define SW_INIT_STATUS 0x08
> +
> +#define SW_INIT_BIT(id) BIT((id) & 0x1f)
> +#define SW_INIT_BANK(id) ((id) >> 5)
> +
> +#define usleep_range(a, b) udelay((b))
> +
> +/* A full bank contains extra registers that we are not utilizing but still
> + * qualify as a single bank.
> + */
> +#define SW_INIT_BANK_SIZE 0x18
> +
> +static int brcmstb_reset_assert(struct reset_ctl *rst)
> +{
> + unsigned int off = SW_INIT_BANK(rst->id) * SW_INIT_BANK_SIZE;
> + struct brcmstb_reset *priv = dev_get_priv(rst->dev);
> +
> + writel_relaxed(SW_INIT_BIT(rst->id), priv->base + off + SW_INIT_SET);
> + return 0;
> +}
> +
> +static int brcmstb_reset_deassert(struct reset_ctl *rst)
> +{
> + unsigned int off = SW_INIT_BANK(rst->id) * SW_INIT_BANK_SIZE;
> + struct brcmstb_reset *priv = dev_get_priv(rst->dev);
> +
> + writel_relaxed(SW_INIT_BIT(rst->id), priv->base + off + SW_INIT_CLEAR);
> + /* Maximum reset delay after de-asserting a line and seeing block
> + * operation is typically 14us for the worst case, build some slack
> + * here.
> + */
> + usleep_range(100, 200);
> + return 0;
> +}
> +
> +static int brcmstb_reset_status(struct reset_ctl *rst)
> +{
> + unsigned int off = SW_INIT_BANK(rst->id) * SW_INIT_BANK_SIZE;
> + struct brcmstb_reset *priv = dev_get_priv(rst->dev);
> +
> + return readl_relaxed(priv->base + off + SW_INIT_STATUS) &
> + SW_INIT_BIT(rst->id);
> +}
> +
> +struct reset_ops brcmstb_reset_reset_ops = {
> + .rst_assert = brcmstb_reset_assert,
> + .rst_deassert = brcmstb_reset_deassert,
> + .rst_status = brcmstb_reset_status};
> +
> +static int brcmstb_reset_probe(struct udevice *dev)
> +{
> + struct brcmstb_reset *priv = dev_get_priv(dev);
> +
> + priv->base = dev_remap_addr(dev);
> + if (!priv->base)
> + return -EINVAL;
> +
> + return 0;
> +}
> +
> +static const struct udevice_id brcmstb_reset_ids[] = {
> + {.compatible = "brcm,brcmstb-reset"}, {/* sentinel */}};
> +
> +U_BOOT_DRIVER(brcmstb_reset) = {
> + .name = "brcmstb-reset",
> + .id = UCLASS_RESET,
> + .of_match = brcmstb_reset_ids,
> + .ops = &brcmstb_reset_reset_ops,
> + .probe = brcmstb_reset_probe,
> + .priv_auto = sizeof(struct brcmstb_reset),
> +};
> --
> 2.54.0
>
More information about the U-Boot
mailing list