reset: Add RPi5 rescal reset facilities

A driver for Broadcom rescal reset controllers ported from
linux/drivers/reset/reset-brcmstb-rescal.c to U-Boot.

Signed-off-by: Torsten Duwe <duwe@suse.de>
Co-authored-by: Oleksii Moisieiev <oleksii_moisieiev@epam.com>
Tested-by: Pedro Falcato <pfalcato@suse.de>
This commit is contained in:
Torsten Duwe
2026-06-01 12:39:29 +02:00
committed by Peter Robinson
parent 64ae1351b5
commit af4f915fd6
4 changed files with 113 additions and 0 deletions

View File

@@ -45,6 +45,7 @@ CONFIG_PCI_BRCMSTB=y
CONFIG_PINCTRL=y
# CONFIG_PINCTRL_GENERIC is not set
CONFIG_RESET_BRCMSTB=y
CONFIG_RESET_BRCMSTB_RESCAL=y
CONFIG_DM_RNG=y
CONFIG_RNG_IPROC200=y
# CONFIG_REQUIRE_SERIAL_CONSOLE is not set

View File

@@ -72,6 +72,14 @@ config RESET_BRCMSTB
If you wish to use reset resources managed by the Broadcom
Reset Controller, say Y here. Otherwise, say N.
config RESET_BRCMSTB_RESCAL
depends on ARCH_BCM283X
bool "Generic Rescal Reset controller driver for Broadcom"
help
Support rescal reset controller on Broadcom.
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

View File

@@ -14,6 +14,7 @@ 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_BRCMSTB_RESCAL) += reset-brcmstb-rescal.o
obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o
obj-$(CONFIG_RESET_AST2500) += reset-ast2500.o
obj-$(CONFIG_RESET_AST2600) += reset-ast2600.o

View File

@@ -0,0 +1,103 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Broadcom STB generic reset controller
*
* Copyright (C) 2024 EPAM Systems
* Moved from linux kernel:
* Copyright (C) 2018-2020 Broadcom
*/
#include <asm/io.h>
#include <dm.h>
#include <dm/device_compat.h>
#include <errno.h>
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/iopoll.h>
#include <log.h>
#include <malloc.h>
#include <reset-uclass.h>
#define BRCM_RESCAL_START 0x0
#define BRCM_RESCAL_START_BIT BIT(0)
#define BRCM_RESCAL_CTRL 0x4
#define BRCM_RESCAL_STATUS 0x8
#define BRCM_RESCAL_STATUS_BIT BIT(0)
struct brcm_rescal_reset {
void __iomem *base;
};
/* Also doubles a deassert */
static int brcm_rescal_reset_set(struct reset_ctl *rst)
{
struct brcm_rescal_reset *data = dev_get_priv(rst->dev);
void __iomem *base = data->base;
u32 reg;
int ret;
reg = readl(base + BRCM_RESCAL_START);
writel(reg | BRCM_RESCAL_START_BIT, base + BRCM_RESCAL_START);
reg = readl(base + BRCM_RESCAL_START);
if (!(reg & BRCM_RESCAL_START_BIT)) {
dev_err(rst->dev, "failed to start SATA/PCIe rescal\n");
return -EIO;
}
ret = readl_poll_timeout(base + BRCM_RESCAL_STATUS, reg,
(reg & BRCM_RESCAL_STATUS_BIT), 100);
if (ret) {
dev_err(rst->dev, "time out on SATA/PCIe rescal\n");
return ret;
}
reg = readl(base + BRCM_RESCAL_START);
writel(reg & ~BRCM_RESCAL_START_BIT, base + BRCM_RESCAL_START);
dev_dbg(rst->dev, "SATA/PCIe rescal success\n");
return 0;
}
/* A dummy function - deassert/reset does all the work */
static int brcm_rescal_reset_assert(struct reset_ctl *rst)
{
return 0;
}
static int brcm_rescal_reset_xlate(struct reset_ctl *reset_ctl,
struct ofnode_phandle_args *args)
{
/* This is needed if #reset-cells == 0. */
return 0;
}
static const struct reset_ops brcm_rescal_reset_ops = {
.rst_deassert = brcm_rescal_reset_set,
.rst_assert = brcm_rescal_reset_assert,
.of_xlate = brcm_rescal_reset_xlate,
};
static int brcm_rescal_reset_probe(struct udevice *dev)
{
struct brcm_rescal_reset *data = dev_get_priv(dev);
data->base = dev_remap_addr(dev);
if (!data->base)
return -EINVAL;
return 0;
}
static const struct udevice_id brcm_rescal_reset_of_match[] = {
{.compatible = "brcm,bcm7216-pcie-sata-rescal"},
{},
};
U_BOOT_DRIVER(brcmstb_reset_rescal) = {
.name = "brcmstb-reset-rescal",
.id = UCLASS_RESET,
.of_match = brcm_rescal_reset_of_match,
.ops = &brcm_rescal_reset_ops,
.probe = brcm_rescal_reset_probe,
.priv_auto = sizeof(struct brcm_rescal_reset),
};